monday_ruby 1.0.0 → 1.1.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 +4 -4
- data/.env +1 -1
- data/.rspec +0 -1
- data/.rubocop.yml +18 -0
- data/.simplecov +1 -0
- data/CHANGELOG.md +35 -0
- data/CONTRIBUTING.md +61 -0
- data/README.md +78 -3
- data/lib/monday/client.rb +17 -2
- data/lib/monday/configuration.rb +8 -0
- data/lib/monday/deprecation.rb +23 -0
- data/lib/monday/error.rb +5 -2
- data/lib/monday/request.rb +4 -1
- data/lib/monday/resources/board.rb +52 -0
- data/lib/monday/resources/column.rb +6 -0
- data/lib/monday/resources/folder.rb +55 -0
- data/lib/monday/resources/group.rb +66 -0
- data/lib/monday/resources/item.rb +62 -0
- data/lib/monday/util.rb +32 -1
- data/lib/monday/version.rb +1 -1
- data/lib/monday_ruby.rb +1 -0
- metadata +8 -10
- data/monday_ruby.gemspec +0 -39
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fca12fa6b3f49d85bea9353e7621904cbe773f69fc9b4b18afc641a7c25318a0
|
|
4
|
+
data.tar.gz: 738fa89ae3732c0bf6afe22c314d7dcc42bae2990bfc313e640ce8aee7183755
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 843ba4a79d3a53b75b8ddfc8eb545d442600fe3b5b90df4f01ced08dd1516c8e9aab4755180b094d7c8fa94a2c330497dbee0b86ecc04071101deb0e236d2d6c
|
|
7
|
+
data.tar.gz: e6a6b8a7c1b912aee79a55f3da44372cf4d35eed207c7e061f131e6385ed9c48475c87c5722162dbdbf259058eaf13f7acf0e990a765dbc3b33299662120d8ef
|
data/.env
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
token="eyJhbGciOiJIUzI1NiJ9.
|
|
1
|
+
token="eyJhbGciOiJIUzI1NiJ9.eyJ0aWQiOjU3ODczMzkyMiwiYWFpIjoxMSwidWlkIjo5NDg5NDgxMywiaWFkIjoiMjAyNS0xMC0yN1QwMToyMToxMy44NDFaIiwicGVyIjoibWU6d3JpdGUiLCJhY3RpZCI6MzIxODc3OTQsInJnbiI6InVzZTEifQ.SgPS-m2FEMHjitKC0SYTYsiQ8vAHZ7ynjDmMwQInneE"
|
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
plugins:
|
|
2
|
+
- rubocop-rake
|
|
3
|
+
- rubocop-rspec
|
|
4
|
+
|
|
1
5
|
AllCops:
|
|
2
6
|
TargetRubyVersion: 2.7
|
|
3
7
|
NewCops: enable
|
|
8
|
+
SuggestExtensions: false
|
|
9
|
+
Exclude:
|
|
10
|
+
- "spec/support/**/*.rb"
|
|
11
|
+
- "vendor/**/*"
|
|
4
12
|
|
|
5
13
|
Style/StringLiterals:
|
|
6
14
|
Enabled: true
|
|
@@ -20,3 +28,13 @@ Metrics/BlockLength:
|
|
|
20
28
|
Metrics/MethodLength:
|
|
21
29
|
Exclude:
|
|
22
30
|
- "lib/monday/util.rb"
|
|
31
|
+
|
|
32
|
+
Metrics/ParameterLists:
|
|
33
|
+
Exclude:
|
|
34
|
+
- "lib/monday/resources/group.rb"
|
|
35
|
+
|
|
36
|
+
RSpec/NestedGroups:
|
|
37
|
+
Max: 5
|
|
38
|
+
|
|
39
|
+
RSpec/MultipleMemoizedHelpers:
|
|
40
|
+
Max: 10
|
data/.simplecov
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,38 @@
|
|
|
1
|
+
## v1.1.0 (October 27, 2025)
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
- **Cursor-based pagination for items**:
|
|
6
|
+
- Added `items_page` method to `Board` resource for paginated item retrieval
|
|
7
|
+
- Added `items_page` method to `Group` resource for paginated group items
|
|
8
|
+
- Added `items_page` method to `Item` resource for paginated item queries
|
|
9
|
+
- Support for cursor-based pagination with customizable limits (up to 500 items per page)
|
|
10
|
+
- Support for filtered queries using `query_params` with rules and operators
|
|
11
|
+
|
|
12
|
+
- **Deprecation warning system**:
|
|
13
|
+
- Added `Deprecation` module for issuing deprecation warnings
|
|
14
|
+
- Marked `delete_subscribers` method for deprecation in v2.0.0
|
|
15
|
+
- Provides clear migration paths for deprecated methods
|
|
16
|
+
|
|
17
|
+
- **Configurable request timeouts**:
|
|
18
|
+
- Added `open_timeout` configuration option (default: 10 seconds)
|
|
19
|
+
- Added `read_timeout` configuration option (default: 30 seconds)
|
|
20
|
+
- Configurable at both global and client instance levels
|
|
21
|
+
|
|
22
|
+
- **Documentation improvements**:
|
|
23
|
+
- Added CONTRIBUTING.md with development guidelines
|
|
24
|
+
- Added VCR testing guide in pull request template
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Updated Ruby version support matrix in CI (added Ruby 3.3 and 3.4)
|
|
29
|
+
- Updated base64 gem dependency to ~> 0.3.0
|
|
30
|
+
- Improved RuboCop configuration and fixed linting issues
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- CI workflow improvements and linting configurations
|
|
35
|
+
|
|
1
36
|
## v1.0.0 (July 30, 2024)
|
|
2
37
|
|
|
3
38
|
### Changed
|
data/CONTRIBUTING.md
CHANGED
|
@@ -16,6 +16,67 @@ Please follow these steps to have your contribution considered:
|
|
|
16
16
|
2. Follow the [commit guidelines](#commit-message-guidelines).
|
|
17
17
|
3. After you submit your pull request, verify that all the status checks are passing.
|
|
18
18
|
|
|
19
|
+
## Testing Guidelines
|
|
20
|
+
|
|
21
|
+
This project uses [VCR](https://github.com/vcr/vcr) to record HTTP interactions for tests. This means you **do not need a Monday.com API token** to run most tests or contribute to the project.
|
|
22
|
+
|
|
23
|
+
### Running Tests
|
|
24
|
+
|
|
25
|
+
To run the test suite:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bundle exec rake spec
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
All tests will use pre-recorded VCR cassettes stored in `spec/fixtures/vcr_cassettes/`.
|
|
32
|
+
|
|
33
|
+
### Working with VCR Cassettes
|
|
34
|
+
|
|
35
|
+
**For most contributions, you won't need to modify VCR cassettes.** The existing cassettes cover the current API functionality.
|
|
36
|
+
|
|
37
|
+
#### When You Need to Record New Cassettes
|
|
38
|
+
|
|
39
|
+
You only need to record new VCR cassettes when:
|
|
40
|
+
- Adding support for a **new API endpoint** that doesn't have existing test coverage
|
|
41
|
+
- Modifying an existing API call that changes the request/response structure
|
|
42
|
+
|
|
43
|
+
To record new cassettes:
|
|
44
|
+
|
|
45
|
+
1. Set your Monday.com API token as an environment variable:
|
|
46
|
+
```bash
|
|
47
|
+
export MONDAY_TOKEN="your_token_here"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
2. Delete the old cassette file (if updating an existing test):
|
|
51
|
+
```bash
|
|
52
|
+
rm spec/fixtures/vcr_cassettes/your_cassette_name.yml
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
3. Run the specific test to generate a new cassette:
|
|
56
|
+
```bash
|
|
57
|
+
bundle exec rspec spec/path/to/your_spec.rb
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
4. **Important:** Before committing, verify the cassette doesn't contain sensitive data:
|
|
61
|
+
- VCR automatically filters the `Authorization` header
|
|
62
|
+
- Check for any other sensitive information in the cassette file
|
|
63
|
+
- Cassettes are committed to the repository
|
|
64
|
+
|
|
65
|
+
#### Testing New Features Without API Access
|
|
66
|
+
|
|
67
|
+
If you're adding a new feature but don't have API access to record cassettes:
|
|
68
|
+
1. Write your implementation and tests
|
|
69
|
+
2. Create a pull request noting that cassettes need to be recorded
|
|
70
|
+
3. A maintainer with API access will record the cassettes for you
|
|
71
|
+
|
|
72
|
+
### Code Quality
|
|
73
|
+
|
|
74
|
+
Run RuboCop to ensure code style compliance:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
bundle exec rake rubocop
|
|
78
|
+
```
|
|
79
|
+
|
|
19
80
|
## Commit message guidelines
|
|
20
81
|
|
|
21
82
|
* Use present tense ("Add feature" not "Added feature")
|
data/README.md
CHANGED
|
@@ -58,6 +58,25 @@ Monday.configure do |config|
|
|
|
58
58
|
end
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
You can also configure request timeouts (new in v1.1.0):
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
require "monday_ruby"
|
|
65
|
+
|
|
66
|
+
Monday.configure do |config|
|
|
67
|
+
config.token = "<AUTH_TOKEN>"
|
|
68
|
+
config.open_timeout = 10 # seconds (default: 10)
|
|
69
|
+
config.read_timeout = 30 # seconds (default: 30)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Or configure per client
|
|
73
|
+
client = Monday::Client.new(
|
|
74
|
+
token: "<AUTH_TOKEN>",
|
|
75
|
+
open_timeout: 15,
|
|
76
|
+
read_timeout: 45
|
|
77
|
+
)
|
|
78
|
+
```
|
|
79
|
+
|
|
61
80
|
### Accessing a response object
|
|
62
81
|
|
|
63
82
|
Get access to response objects by initializing a client and using the appropriate action you want to perform:
|
|
@@ -87,7 +106,7 @@ response = client.boards # => <Monday::Response ...>
|
|
|
87
106
|
response.success? # => true
|
|
88
107
|
|
|
89
108
|
# To get the boards from the response
|
|
90
|
-
response.dig("data", "boards") # => [...]
|
|
109
|
+
response.body.dig("data", "boards") # => [...]
|
|
91
110
|
```
|
|
92
111
|
|
|
93
112
|
#### Creating a new board
|
|
@@ -110,7 +129,7 @@ response = client.create_board(args: args)
|
|
|
110
129
|
response.success? # => true
|
|
111
130
|
|
|
112
131
|
# To get the created board from the response
|
|
113
|
-
response.dig("data", "create_board") # => { ... }
|
|
132
|
+
response.body.dig("data", "create_board") # => { ... }
|
|
114
133
|
```
|
|
115
134
|
|
|
116
135
|
#### Creating a new item on board
|
|
@@ -140,7 +159,63 @@ response = client.create_item(args: args)
|
|
|
140
159
|
response.success? # => true
|
|
141
160
|
|
|
142
161
|
# To get the created item from the response
|
|
143
|
-
response.dig("data", "create_item") # => { ... }
|
|
162
|
+
response.body.dig("data", "create_item") # => { ... }
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
#### Fetching items with pagination (New in v1.1.0)
|
|
166
|
+
|
|
167
|
+
The library now supports efficient cursor-based pagination for retrieving large numbers of items. This is the recommended approach for working with boards, groups, or items that contain many records.
|
|
168
|
+
|
|
169
|
+
```ruby
|
|
170
|
+
client = Monday::Client.new(token: <AUTH_TOKEN>)
|
|
171
|
+
|
|
172
|
+
# Fetch first page of items from a board (up to 500 items per page)
|
|
173
|
+
response = client.board.items_page(
|
|
174
|
+
board_ids: <BOARD_ID>,
|
|
175
|
+
limit: 100
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
# Extract items and cursor from response
|
|
179
|
+
items = response.body.dig("data", "boards", 0, "items_page", "items")
|
|
180
|
+
cursor = response.body.dig("data", "boards", 0, "items_page", "cursor")
|
|
181
|
+
|
|
182
|
+
# Fetch next page using cursor
|
|
183
|
+
if cursor
|
|
184
|
+
next_response = client.board.items_page(
|
|
185
|
+
board_ids: <BOARD_ID>,
|
|
186
|
+
limit: 100,
|
|
187
|
+
cursor: cursor
|
|
188
|
+
)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# You can also filter items using query_params
|
|
192
|
+
response = client.board.items_page(
|
|
193
|
+
board_ids: <BOARD_ID>,
|
|
194
|
+
limit: 50,
|
|
195
|
+
query_params: {
|
|
196
|
+
rules: [{ column_id: "status", compare_value: [1] }],
|
|
197
|
+
operator: :and
|
|
198
|
+
}
|
|
199
|
+
)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Pagination is also available for groups and items:
|
|
203
|
+
|
|
204
|
+
```ruby
|
|
205
|
+
# Fetch paginated items from a group
|
|
206
|
+
response = client.group.items_page(
|
|
207
|
+
board_ids: <BOARD_ID>,
|
|
208
|
+
group_ids: "group_id",
|
|
209
|
+
limit: 100
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
# Fetch paginated items with custom query
|
|
213
|
+
response = client.item.items_page(
|
|
214
|
+
limit: 100,
|
|
215
|
+
query_params: {
|
|
216
|
+
rules: [{ column_id: "status", compare_value: [5] }]
|
|
217
|
+
}
|
|
218
|
+
)
|
|
144
219
|
```
|
|
145
220
|
|
|
146
221
|
## Development
|
data/lib/monday/client.rb
CHANGED
|
@@ -26,7 +26,13 @@ module Monday
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def make_request(body)
|
|
29
|
-
response = Request.post(
|
|
29
|
+
response = Request.post(
|
|
30
|
+
uri,
|
|
31
|
+
body,
|
|
32
|
+
request_headers,
|
|
33
|
+
open_timeout: @config.open_timeout,
|
|
34
|
+
read_timeout: @config.read_timeout
|
|
35
|
+
)
|
|
30
36
|
|
|
31
37
|
handle_response(Response.new(response))
|
|
32
38
|
end
|
|
@@ -63,7 +69,7 @@ module Monday
|
|
|
63
69
|
end
|
|
64
70
|
|
|
65
71
|
def response_exception(response)
|
|
66
|
-
error_code = response
|
|
72
|
+
error_code = response_error_code(response)
|
|
67
73
|
|
|
68
74
|
return Error.new(response: response) if error_code.nil?
|
|
69
75
|
|
|
@@ -71,6 +77,15 @@ module Monday
|
|
|
71
77
|
exception_klass.new(message: error_code, response: response, code: code)
|
|
72
78
|
end
|
|
73
79
|
|
|
80
|
+
def response_error_code(response)
|
|
81
|
+
error_code = response.body["error_code"]
|
|
82
|
+
return error_code unless error_code.nil?
|
|
83
|
+
|
|
84
|
+
return unless response.body["errors"].is_a?(Array) && !response.body["errors"].empty?
|
|
85
|
+
|
|
86
|
+
response.body.dig("errors", 0, "extensions", "code") || response.body.dig("errors", 0, "extensions", "error_code")
|
|
87
|
+
end
|
|
88
|
+
|
|
74
89
|
def default_exception(response)
|
|
75
90
|
Util.status_code_exceptions_mapping(response.status).new(response: response)
|
|
76
91
|
end
|
data/lib/monday/configuration.rb
CHANGED
|
@@ -11,11 +11,15 @@ module Monday
|
|
|
11
11
|
DEFAULT_HOST = "https://api.monday.com/v2"
|
|
12
12
|
DEFAULT_TOKEN = nil
|
|
13
13
|
DEFAULT_VERSION = "2023-07"
|
|
14
|
+
DEFAULT_OPEN_TIMEOUT = 10
|
|
15
|
+
DEFAULT_READ_TIMEOUT = 30
|
|
14
16
|
|
|
15
17
|
CONFIGURATION_FIELDS = %i[
|
|
16
18
|
token
|
|
17
19
|
host
|
|
18
20
|
version
|
|
21
|
+
open_timeout
|
|
22
|
+
read_timeout
|
|
19
23
|
].freeze
|
|
20
24
|
|
|
21
25
|
attr_accessor(*CONFIGURATION_FIELDS)
|
|
@@ -27,6 +31,8 @@ module Monday
|
|
|
27
31
|
@host = DEFAULT_HOST
|
|
28
32
|
@token = DEFAULT_TOKEN
|
|
29
33
|
@version = DEFAULT_VERSION
|
|
34
|
+
@open_timeout = DEFAULT_OPEN_TIMEOUT
|
|
35
|
+
@read_timeout = DEFAULT_READ_TIMEOUT
|
|
30
36
|
|
|
31
37
|
config_args.each do |key, value|
|
|
32
38
|
public_send("#{key}=", value)
|
|
@@ -37,6 +43,8 @@ module Monday
|
|
|
37
43
|
@token = DEFAULT_TOKEN
|
|
38
44
|
@host = DEFAULT_HOST
|
|
39
45
|
@version = DEFAULT_VERSION
|
|
46
|
+
@open_timeout = DEFAULT_OPEN_TIMEOUT
|
|
47
|
+
@read_timeout = DEFAULT_READ_TIMEOUT
|
|
40
48
|
end
|
|
41
49
|
end
|
|
42
50
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Monday
|
|
4
|
+
# Utility module for handling deprecation warnings
|
|
5
|
+
module Deprecation
|
|
6
|
+
# Issues a deprecation warning to stderr
|
|
7
|
+
#
|
|
8
|
+
# @param method_name [String] The name of the deprecated method
|
|
9
|
+
# @param removal_version [String] The version in which the method will be removed
|
|
10
|
+
# @param alternative [String, nil] The recommended alternative method
|
|
11
|
+
#
|
|
12
|
+
# @example
|
|
13
|
+
# Deprecation.warn(method_name: "items", removal_version: "2.0.0", alternative: "items_page")
|
|
14
|
+
# # => [DEPRECATION] `items` is deprecated and will be removed in v2.0.0. Use `items_page` instead.
|
|
15
|
+
def self.warn(method_name:, removal_version:, alternative: nil)
|
|
16
|
+
message = "[DEPRECATION] `#{method_name}` is deprecated and will be removed in v#{removal_version}."
|
|
17
|
+
message += " Use `#{alternative}` instead." if alternative
|
|
18
|
+
|
|
19
|
+
# Output to stderr so it doesn't interfere with normal output
|
|
20
|
+
Kernel.warn message
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/monday/error.rb
CHANGED
|
@@ -56,13 +56,16 @@ module Monday
|
|
|
56
56
|
# AuthorizationError is raised when the request returns
|
|
57
57
|
# a 401 or 403 status code.
|
|
58
58
|
#
|
|
59
|
-
# It is also raised when the body returns the following
|
|
60
|
-
# UserUnauthorizedException
|
|
59
|
+
# It is also raised when the body returns the following error_codes:
|
|
60
|
+
# UserUnauthorizedException, USER_UNAUTHORIZED
|
|
61
61
|
class AuthorizationError < Error
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
# RateLimitError is raised when the request returns
|
|
65
65
|
# a 429 status code.
|
|
66
|
+
#
|
|
67
|
+
# It is also raised when the body returns the following error_codes:
|
|
68
|
+
# ComplexityException, COMPLEXITY_BUDGET_EXHAUSTED
|
|
66
69
|
class RateLimitError < Error
|
|
67
70
|
end
|
|
68
71
|
|
data/lib/monday/request.rb
CHANGED
|
@@ -4,9 +4,12 @@ module Monday
|
|
|
4
4
|
# Defines the HTTP request methods.
|
|
5
5
|
class Request
|
|
6
6
|
# Performs a POST request
|
|
7
|
-
def self.post(uri, query, headers)
|
|
7
|
+
def self.post(uri, query, headers, open_timeout: 10, read_timeout: 30)
|
|
8
8
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
9
9
|
http.use_ssl = true
|
|
10
|
+
http.open_timeout = open_timeout
|
|
11
|
+
http.read_timeout = read_timeout
|
|
12
|
+
|
|
10
13
|
request = Net::HTTP::Post.new(uri.request_uri, headers)
|
|
11
14
|
|
|
12
15
|
request.body = {
|
|
@@ -7,6 +7,7 @@ module Monday
|
|
|
7
7
|
# Represents Monday.com's board resource.
|
|
8
8
|
class Board < Base
|
|
9
9
|
DEFAULT_SELECT = %w[id name description].freeze
|
|
10
|
+
DEFAULT_PAGINATED_SELECT = %w[id name].freeze
|
|
10
11
|
|
|
11
12
|
# Retrieves all the boards.
|
|
12
13
|
#
|
|
@@ -79,11 +80,62 @@ module Monday
|
|
|
79
80
|
# Allows customizing the values to retrieve using the select option.
|
|
80
81
|
# By default, returns the deleted subscriber IDs.
|
|
81
82
|
def delete_subscribers(board_id, user_ids, select: ["id"])
|
|
83
|
+
Deprecation.warn(
|
|
84
|
+
method_name: "delete_subscribers",
|
|
85
|
+
removal_version: "2.0.0",
|
|
86
|
+
alternative: "user.delete_from_board"
|
|
87
|
+
)
|
|
88
|
+
|
|
82
89
|
query = "mutation{delete_subscribers_from_board(" \
|
|
83
90
|
"board_id: #{board_id}, user_ids: #{user_ids}){#{Util.format_select(select)}}}"
|
|
84
91
|
|
|
85
92
|
make_request(query)
|
|
86
93
|
end
|
|
94
|
+
|
|
95
|
+
# Retrieves paginated items from a board.
|
|
96
|
+
#
|
|
97
|
+
# Uses cursor-based pagination for efficient data retrieval.
|
|
98
|
+
# The items_page field is the modern replacement for the deprecated items field.
|
|
99
|
+
#
|
|
100
|
+
# @param board_id [Integer] The ID of the board
|
|
101
|
+
# @param limit [Integer] Number of items to retrieve per page (default: 25, max: 500)
|
|
102
|
+
# @param cursor [String, nil] Pagination cursor for fetching next page (expires after 60 minutes)
|
|
103
|
+
# @param query_params [Hash, nil] Query parameters for filtering items with rules and operators
|
|
104
|
+
# @param args [Hash] Additional board query arguments
|
|
105
|
+
# @param select [Array] Fields to retrieve for each item
|
|
106
|
+
# @return [Monday::Response] Response containing items and cursor
|
|
107
|
+
#
|
|
108
|
+
# @example Fetch first page of items
|
|
109
|
+
# response = client.board.items_page(board_id: 123, limit: 50)
|
|
110
|
+
# items = response.dig("data", "boards", 0, "items_page", "items")
|
|
111
|
+
# cursor = response.dig("data", "boards", 0, "items_page", "cursor")
|
|
112
|
+
#
|
|
113
|
+
# @example Fetch next page using cursor
|
|
114
|
+
# response = client.board.items_page(board_id: 123, cursor: cursor)
|
|
115
|
+
#
|
|
116
|
+
# @example Filter items by column value
|
|
117
|
+
# response = client.board.items_page(
|
|
118
|
+
# board_id: 123,
|
|
119
|
+
# limit: 100,
|
|
120
|
+
# query_params: {
|
|
121
|
+
# rules: [{ column_id: "status", compare_value: [1] }],
|
|
122
|
+
# operator: :and
|
|
123
|
+
# }
|
|
124
|
+
# )
|
|
125
|
+
def items_page(board_ids:, limit: 25, cursor: nil, query_params: nil, select: DEFAULT_PAGINATED_SELECT)
|
|
126
|
+
items_args_parts = ["limit: #{limit}"]
|
|
127
|
+
items_args_parts << "cursor: \"#{cursor}\"" if cursor
|
|
128
|
+
items_args_parts << "query_params: #{Util.format_graphql_object(query_params)}" if query_params
|
|
129
|
+
|
|
130
|
+
items_args_string = items_args_parts.empty? ? "" : "(#{items_args_parts.join(", ")})"
|
|
131
|
+
|
|
132
|
+
items_page_select = "items_page#{items_args_string}{cursor items{#{Util.format_select(select)}}}"
|
|
133
|
+
|
|
134
|
+
board_args = { ids: board_ids.is_a?(Array) ? board_ids : [board_ids] }
|
|
135
|
+
request_query = "query{boards#{Util.format_args(board_args)}{#{items_page_select}}}"
|
|
136
|
+
|
|
137
|
+
make_request(request_query)
|
|
138
|
+
end
|
|
87
139
|
end
|
|
88
140
|
end
|
|
89
141
|
end
|
|
@@ -25,6 +25,12 @@ module Monday
|
|
|
25
25
|
# Allows customizing the values to retrieve using the select option.
|
|
26
26
|
# By default, ID, title and description fields are retrieved.
|
|
27
27
|
def column_values(board_ids = [], item_ids = [], select: DEFAULT_SELECT)
|
|
28
|
+
Deprecation.warn(
|
|
29
|
+
method_name: "column_values",
|
|
30
|
+
removal_version: "2.0.0",
|
|
31
|
+
alternative: "item.column_values"
|
|
32
|
+
)
|
|
33
|
+
|
|
28
34
|
board_args = board_ids.empty? ? "" : "ids: #{board_ids}"
|
|
29
35
|
item_args = item_ids.empty? ? "" : "ids: #{item_ids}"
|
|
30
36
|
query = "query{boards(#{board_args}){items(#{item_args})" \
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module Monday
|
|
6
|
+
module Resources
|
|
7
|
+
# Represents Monday.com's board resource.
|
|
8
|
+
class Folder < Base
|
|
9
|
+
DEFAULT_SELECT = %w[id name].freeze
|
|
10
|
+
|
|
11
|
+
# Retrieves all the folders.
|
|
12
|
+
#
|
|
13
|
+
# Allows filtering folders using the args option.
|
|
14
|
+
# Allows customizing the values to retrieve using the select option.
|
|
15
|
+
# By default, ID and name fields are retrieved.
|
|
16
|
+
def query(args: {}, select: DEFAULT_SELECT)
|
|
17
|
+
request_query = "query{folders#{Util.format_args(args)}{#{Util.format_select(select)}}}"
|
|
18
|
+
|
|
19
|
+
make_request(request_query)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Create a new folder.
|
|
23
|
+
#
|
|
24
|
+
# Allows customizing creating a folder using the args option.
|
|
25
|
+
# Allows customizing the values to retrieve using the select option.
|
|
26
|
+
# By default, ID and name fields are retrieved.
|
|
27
|
+
def create(args: {}, select: DEFAULT_SELECT)
|
|
28
|
+
query = "mutation{create_folder#{Util.format_args(args)}{#{Util.format_select(select)}}}"
|
|
29
|
+
|
|
30
|
+
make_request(query)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Update a folder.
|
|
34
|
+
#
|
|
35
|
+
# Allows customizing updating the folder using the args option.
|
|
36
|
+
# By default, returns the ID of the updated folder.
|
|
37
|
+
def update(args: {}, select: ["id"])
|
|
38
|
+
query = "mutation{update_folder#{Util.format_args(args)}{#{Util.format_select(select)}}}"
|
|
39
|
+
|
|
40
|
+
make_request(query)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Delete a folder.
|
|
44
|
+
#
|
|
45
|
+
# Requires folder_id in args option to delete the folder.
|
|
46
|
+
# Allows customizing the values to retrieve using the select option.
|
|
47
|
+
# By default, returns the ID of the folder deleted.
|
|
48
|
+
def delete(args: {}, select: ["id"])
|
|
49
|
+
query = "mutation{delete_folder#{Util.format_args(args)}{#{Util.format_select(select)}}}"
|
|
50
|
+
|
|
51
|
+
make_request(query)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -7,6 +7,7 @@ module Monday
|
|
|
7
7
|
# Represents Monday.com's group resource.
|
|
8
8
|
class Group < Base
|
|
9
9
|
DEFAULT_SELECT = %w[id title].freeze
|
|
10
|
+
DEFAULT_PAGINATED_SELECT = %w[id name].freeze
|
|
10
11
|
|
|
11
12
|
# Retrieves all the groups.
|
|
12
13
|
#
|
|
@@ -83,6 +84,71 @@ module Monday
|
|
|
83
84
|
|
|
84
85
|
make_request(query)
|
|
85
86
|
end
|
|
87
|
+
|
|
88
|
+
# Retrieves paginated items from a group.
|
|
89
|
+
#
|
|
90
|
+
# Uses cursor-based pagination for efficient data retrieval.
|
|
91
|
+
# The items_page field is the modern replacement for the deprecated items field.
|
|
92
|
+
#
|
|
93
|
+
# @param board_ids [Integer, Array<Integer>] The ID(s) of the board(s) containing the group
|
|
94
|
+
# @param group_ids [String, Array<String>] The ID(s) of the group(s)
|
|
95
|
+
# @param limit [Integer] Number of items to retrieve per page (default: 25, max: 500)
|
|
96
|
+
# @param cursor [String, nil] Pagination cursor for fetching next page (expires after 60 minutes)
|
|
97
|
+
# @param query_params [Hash, nil] Query parameters for filtering items with rules and operators
|
|
98
|
+
# @param select [Array] Fields to retrieve for each item
|
|
99
|
+
# @return [Monday::Response] Response containing items and cursor
|
|
100
|
+
#
|
|
101
|
+
# @example Fetch first page of items from a group
|
|
102
|
+
# response = client.group.items_page(board_ids: 123, group_ids: "group_1", limit: 50)
|
|
103
|
+
# items = response.dig("data", "boards", 0, "groups", 0, "items_page", "items")
|
|
104
|
+
# cursor = response.dig("data", "boards", 0, "groups", 0, "items_page", "cursor")
|
|
105
|
+
#
|
|
106
|
+
# @example Fetch next page using cursor
|
|
107
|
+
# response = client.group.items_page(board_ids: 123, group_ids: "group_1", cursor: cursor)
|
|
108
|
+
#
|
|
109
|
+
# @example Filter items by column value
|
|
110
|
+
# response = client.group.items_page(
|
|
111
|
+
# board_ids: 123,
|
|
112
|
+
# group_ids: "group_1",
|
|
113
|
+
# limit: 100,
|
|
114
|
+
# query_params: {
|
|
115
|
+
# rules: [{ column_id: "status", compare_value: [1] }],
|
|
116
|
+
# operator: :and
|
|
117
|
+
# }
|
|
118
|
+
# )
|
|
119
|
+
def items_page(
|
|
120
|
+
board_ids:, group_ids:, limit: 25, cursor: nil, query_params: nil, select: DEFAULT_PAGINATED_SELECT
|
|
121
|
+
)
|
|
122
|
+
items_page_query = build_items_page_query(limit, cursor, query_params, select)
|
|
123
|
+
request_query = build_groups_items_page_request(board_ids, group_ids, items_page_query)
|
|
124
|
+
|
|
125
|
+
make_request(request_query)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
private
|
|
129
|
+
|
|
130
|
+
def build_items_page_query(limit, cursor, query_params, select)
|
|
131
|
+
args_parts = ["limit: #{limit}"]
|
|
132
|
+
args_parts << "cursor: \"#{cursor}\"" if cursor
|
|
133
|
+
args_parts << "query_params: #{Util.format_graphql_object(query_params)}" if query_params
|
|
134
|
+
|
|
135
|
+
args_string = "(#{args_parts.join(", ")})"
|
|
136
|
+
"items_page#{args_string}{cursor items{#{Util.format_select(select)}}}"
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def build_groups_items_page_request(board_ids, group_ids, items_page_query)
|
|
140
|
+
board_args = { ids: board_ids.is_a?(Array) ? board_ids : [board_ids] }
|
|
141
|
+
group_ids_formatted = format_group_ids(group_ids)
|
|
142
|
+
|
|
143
|
+
boards_part = "boards#{Util.format_args(board_args)}"
|
|
144
|
+
groups_part = "groups(ids: #{group_ids_formatted})"
|
|
145
|
+
"query{#{boards_part}{#{groups_part}{#{items_page_query}}}}"
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def format_group_ids(group_ids)
|
|
149
|
+
ids_array = group_ids.is_a?(Array) ? group_ids : [group_ids]
|
|
150
|
+
"[#{ids_array.map { |id| "\"#{id}\"" }.join(", ")}]"
|
|
151
|
+
end
|
|
86
152
|
end
|
|
87
153
|
end
|
|
88
154
|
end
|
|
@@ -7,6 +7,7 @@ module Monday
|
|
|
7
7
|
# Represents Monday.com's item resource.
|
|
8
8
|
class Item < Base
|
|
9
9
|
DEFAULT_SELECT = %w[id name created_at].freeze
|
|
10
|
+
DEFAULT_PAGINATED_SELECT = %w[id name].freeze
|
|
10
11
|
|
|
11
12
|
# Retrieves all the items for the boards.
|
|
12
13
|
#
|
|
@@ -63,6 +64,67 @@ module Monday
|
|
|
63
64
|
|
|
64
65
|
make_request(query)
|
|
65
66
|
end
|
|
67
|
+
|
|
68
|
+
# Retrieves paginated items filtered by column values.
|
|
69
|
+
#
|
|
70
|
+
# Enables searching for items based on specific column values.
|
|
71
|
+
# Uses cursor-based pagination for efficient data retrieval.
|
|
72
|
+
#
|
|
73
|
+
# @param board_id [Integer] The ID of the board
|
|
74
|
+
# @param columns [Array<Hash>, nil] Column filtering criteria (mutually exclusive with cursor)
|
|
75
|
+
# Each hash should contain :column_id and :column_values
|
|
76
|
+
# @param limit [Integer] Number of items to retrieve per page (default: 25, max: 500)
|
|
77
|
+
# @param cursor [String, nil] Pagination cursor for fetching next page (mutually exclusive with columns)
|
|
78
|
+
# @param select [Array] Fields to retrieve for each item
|
|
79
|
+
# @return [Monday::Response] Response containing items and cursor
|
|
80
|
+
#
|
|
81
|
+
# @example Search items by column values
|
|
82
|
+
# response = client.item.page_by_column_values(
|
|
83
|
+
# board_id: 123,
|
|
84
|
+
# columns: [
|
|
85
|
+
# { column_id: "status", column_values: ["Done", "Working on it"] },
|
|
86
|
+
# { column_id: "text", column_values: ["High Priority"] }
|
|
87
|
+
# ],
|
|
88
|
+
# limit: 50
|
|
89
|
+
# )
|
|
90
|
+
# items = response.dig("data", "items_page_by_column_values", "items")
|
|
91
|
+
# cursor = response.dig("data", "items_page_by_column_values", "cursor")
|
|
92
|
+
#
|
|
93
|
+
# @example Fetch next page using cursor
|
|
94
|
+
# response = client.item.page_by_column_values(
|
|
95
|
+
# board_id: 123,
|
|
96
|
+
# cursor: cursor
|
|
97
|
+
# )
|
|
98
|
+
#
|
|
99
|
+
# @note Supported column types: Checkbox, Country, Date, Dropdown, Email, Hour, Link,
|
|
100
|
+
# Long Text, Numbers, People, Phone, Status, Text, Timeline, World Clock
|
|
101
|
+
# @note Columns use AND logic; values within a column use ANY_OF logic
|
|
102
|
+
def page_by_column_values(board_id:, columns: nil, limit: 25, cursor: nil, select: DEFAULT_PAGINATED_SELECT)
|
|
103
|
+
query_string = build_items_page_by_column_values_query(board_id, columns, limit, cursor, select)
|
|
104
|
+
make_request(query_string)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def build_items_page_by_column_values_query(board_id, columns, limit, cursor, select)
|
|
110
|
+
args_parts = ["board_id: #{board_id}", "limit: #{limit}"]
|
|
111
|
+
args_parts << "cursor: \"#{cursor}\"" if cursor
|
|
112
|
+
args_parts << "columns: #{format_columns(columns)}" if columns
|
|
113
|
+
|
|
114
|
+
args_string = "(#{args_parts.join(", ")})"
|
|
115
|
+
"query{items_page_by_column_values#{args_string}{cursor items{#{Util.format_select(select)}}}}"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def format_columns(columns)
|
|
119
|
+
return nil unless columns
|
|
120
|
+
|
|
121
|
+
column_strings = columns.map do |col|
|
|
122
|
+
values = col[:column_values].map { |v| "\"#{v}\"" }.join(", ")
|
|
123
|
+
"{column_id: \"#{col[:column_id]}\", column_values: [#{values}]}"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
"[#{column_strings.join(", ")}]"
|
|
127
|
+
end
|
|
66
128
|
end
|
|
67
129
|
end
|
|
68
130
|
end
|
data/lib/monday/util.rb
CHANGED
|
@@ -29,6 +29,18 @@ module Monday
|
|
|
29
29
|
values
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
# Formats a hash as a GraphQL input object (not JSON string)
|
|
33
|
+
# Used for complex input types like ItemsQuery
|
|
34
|
+
#
|
|
35
|
+
# input: { rules: [{ column_id: "status", compare_value: [1] }], operator: :and }
|
|
36
|
+
# output: { rules: [{ column_id: "status", compare_value: [1] }], operator: and }
|
|
37
|
+
def format_graphql_object(hash)
|
|
38
|
+
formatted = hash.map do |key, value|
|
|
39
|
+
"#{key}: #{format_graphql_value(value)}"
|
|
40
|
+
end.join(", ")
|
|
41
|
+
"{#{formatted}}"
|
|
42
|
+
end
|
|
43
|
+
|
|
32
44
|
def status_code_exceptions_mapping(status_code)
|
|
33
45
|
{
|
|
34
46
|
"500" => InternalServerError,
|
|
@@ -43,7 +55,9 @@ module Monday
|
|
|
43
55
|
def response_error_exceptions_mapping(error_code)
|
|
44
56
|
{
|
|
45
57
|
"ComplexityException" => [ComplexityError, 429],
|
|
58
|
+
"COMPLEXITY_BUDGET_EXHAUSTED" => [RateLimitError, 429],
|
|
46
59
|
"UserUnauthorizedException" => [AuthorizationError, 403],
|
|
60
|
+
"USER_UNAUTHORIZED" => [AuthorizationError, 403],
|
|
47
61
|
"ResourceNotFoundException" => [ResourceNotFoundError, 404],
|
|
48
62
|
"InvalidUserIdException" => [InvalidRequestError, 400],
|
|
49
63
|
"InvalidVersionException" => [InvalidRequestError, 400],
|
|
@@ -58,7 +72,8 @@ module Monday
|
|
|
58
72
|
"ItemNameTooLongException" => [InvalidRequestError, 400],
|
|
59
73
|
"ColumnValueException" => [InvalidRequestError, 400],
|
|
60
74
|
"CorrectedValueException" => [InvalidRequestError, 400],
|
|
61
|
-
"InvalidWorkspaceIdException" => [InvalidRequestError, 400]
|
|
75
|
+
"InvalidWorkspaceIdException" => [InvalidRequestError, 400],
|
|
76
|
+
"INTERNAL_SERVER_ERROR" => [InternalServerError, 500]
|
|
62
77
|
}[error_code] || [Error, 400]
|
|
63
78
|
end
|
|
64
79
|
|
|
@@ -76,10 +91,26 @@ module Monday
|
|
|
76
91
|
end.join(" ")
|
|
77
92
|
end
|
|
78
93
|
|
|
94
|
+
def format_graphql_value(value)
|
|
95
|
+
case value
|
|
96
|
+
when Hash
|
|
97
|
+
format_graphql_object(value)
|
|
98
|
+
when Array
|
|
99
|
+
"[#{value.map { |v| format_graphql_value(v) }.join(", ")}]"
|
|
100
|
+
when Integer, TrueClass, FalseClass
|
|
101
|
+
value
|
|
102
|
+
when String
|
|
103
|
+
"\"#{value}\""
|
|
104
|
+
else
|
|
105
|
+
value.to_s
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
79
109
|
def formatted_args_value(value)
|
|
80
110
|
return value if value.is_a?(Symbol)
|
|
81
111
|
return value.to_json.to_json if value.is_a?(Hash)
|
|
82
112
|
return value if integer?(value)
|
|
113
|
+
return "[#{value.map { |v| formatted_args_value(v) }.join(", ")}]" if value.is_a?(Array)
|
|
83
114
|
|
|
84
115
|
"\"#{value}\""
|
|
85
116
|
end
|
data/lib/monday/version.rb
CHANGED
data/lib/monday_ruby.rb
CHANGED
metadata
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: monday_ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sanif Himani
|
|
8
8
|
- Wes Hays
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: exe
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: base64
|
|
@@ -17,14 +16,14 @@ dependencies:
|
|
|
17
16
|
requirements:
|
|
18
17
|
- - "~>"
|
|
19
18
|
- !ruby/object:Gem::Version
|
|
20
|
-
version: 0.
|
|
19
|
+
version: 0.3.0
|
|
21
20
|
type: :runtime
|
|
22
21
|
prerelease: false
|
|
23
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
23
|
requirements:
|
|
25
24
|
- - "~>"
|
|
26
25
|
- !ruby/object:Gem::Version
|
|
27
|
-
version: 0.
|
|
26
|
+
version: 0.3.0
|
|
28
27
|
description: A Gem to easily interact with monday.com API using native Ruby
|
|
29
28
|
email:
|
|
30
29
|
- sanifhimani92@gmail.com
|
|
@@ -46,6 +45,7 @@ files:
|
|
|
46
45
|
- Rakefile
|
|
47
46
|
- lib/monday/client.rb
|
|
48
47
|
- lib/monday/configuration.rb
|
|
48
|
+
- lib/monday/deprecation.rb
|
|
49
49
|
- lib/monday/error.rb
|
|
50
50
|
- lib/monday/request.rb
|
|
51
51
|
- lib/monday/resources.rb
|
|
@@ -55,6 +55,7 @@ files:
|
|
|
55
55
|
- lib/monday/resources/board.rb
|
|
56
56
|
- lib/monday/resources/board_view.rb
|
|
57
57
|
- lib/monday/resources/column.rb
|
|
58
|
+
- lib/monday/resources/folder.rb
|
|
58
59
|
- lib/monday/resources/group.rb
|
|
59
60
|
- lib/monday/resources/item.rb
|
|
60
61
|
- lib/monday/resources/subitem.rb
|
|
@@ -64,16 +65,14 @@ files:
|
|
|
64
65
|
- lib/monday/util.rb
|
|
65
66
|
- lib/monday/version.rb
|
|
66
67
|
- lib/monday_ruby.rb
|
|
67
|
-
- monday_ruby.gemspec
|
|
68
68
|
homepage: https://github.com/sanifhimani/monday_ruby
|
|
69
69
|
licenses:
|
|
70
70
|
- MIT
|
|
71
71
|
metadata:
|
|
72
72
|
homepage_uri: https://github.com/sanifhimani/monday_ruby
|
|
73
73
|
documentation_uri: https://monday-ruby.gitbook.io/docs/
|
|
74
|
-
changelog_uri: https://github.com/sanifhimani/monday_ruby/blob/v1.
|
|
74
|
+
changelog_uri: https://github.com/sanifhimani/monday_ruby/blob/v1.1.0/CHANGELOG.md
|
|
75
75
|
rubygems_mfa_required: 'true'
|
|
76
|
-
post_install_message:
|
|
77
76
|
rdoc_options: []
|
|
78
77
|
require_paths:
|
|
79
78
|
- lib
|
|
@@ -88,8 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
88
87
|
- !ruby/object:Gem::Version
|
|
89
88
|
version: '0'
|
|
90
89
|
requirements: []
|
|
91
|
-
rubygems_version: 3.
|
|
92
|
-
signing_key:
|
|
90
|
+
rubygems_version: 3.6.9
|
|
93
91
|
specification_version: 4
|
|
94
92
|
summary: Ruby bindings to use the monday.com API
|
|
95
93
|
test_files: []
|
data/monday_ruby.gemspec
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "lib/monday/version"
|
|
4
|
-
|
|
5
|
-
version = Monday::VERSION
|
|
6
|
-
repository = "https://github.com/sanifhimani/monday_ruby"
|
|
7
|
-
|
|
8
|
-
Gem::Specification.new do |spec|
|
|
9
|
-
spec.name = "monday_ruby"
|
|
10
|
-
spec.version = version
|
|
11
|
-
spec.authors = ["Sanif Himani", "Wes Hays"]
|
|
12
|
-
spec.email = ["sanifhimani92@gmail.com", "weshays@gmail.com"]
|
|
13
|
-
|
|
14
|
-
spec.summary = "Ruby bindings to use the monday.com API"
|
|
15
|
-
spec.description = "A Gem to easily interact with monday.com API using native Ruby"
|
|
16
|
-
spec.homepage = repository
|
|
17
|
-
spec.license = "MIT"
|
|
18
|
-
spec.required_ruby_version = ">= 2.7.0"
|
|
19
|
-
|
|
20
|
-
spec.metadata = {
|
|
21
|
-
"homepage_uri" => spec.homepage,
|
|
22
|
-
"documentation_uri" => "https://monday-ruby.gitbook.io/docs/",
|
|
23
|
-
"changelog_uri" => "#{repository}/blob/v#{version}/CHANGELOG.md",
|
|
24
|
-
"rubygems_mfa_required" => "true"
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
spec.files = Dir.chdir(__dir__) do
|
|
28
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
|
29
|
-
(File.expand_path(f) == __FILE__) ||
|
|
30
|
-
f.start_with?(*%w[bin/ test/ spec/ features/ .git Gemfile])
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
spec.bindir = "exe"
|
|
35
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
36
|
-
spec.require_paths = ["lib"]
|
|
37
|
-
|
|
38
|
-
spec.add_dependency "base64", "~> 0.2.0"
|
|
39
|
-
end
|