timely-app 1.3.0 → 1.3.2

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -22
  3. data/README.md +20 -1
  4. data/bin/timely-app +6 -118
  5. data/lib/timely-app/cli.rb +132 -0
  6. data/lib/timely-app/client/accounts.rb +1 -1
  7. data/lib/timely-app/client/auth.rb +1 -1
  8. data/lib/timely-app/client/clients.rb +1 -1
  9. data/lib/timely-app/client.rb +29 -24
  10. data/lib/timely-app/errors.rb +1 -1
  11. data/lib/timely-app/link_header.rb +2 -2
  12. data/lib/timely-app/params.rb +5 -4
  13. data/lib/timely-app/record.rb +3 -3
  14. data/lib/timely-app/response.rb +6 -5
  15. data/lib/timely-app.rb +16 -16
  16. data/sig/timely-app/cli.rbs +33 -0
  17. data/sig/timely-app/client/accounts.rbs +10 -0
  18. data/sig/timely-app/client/auth.rbs +8 -0
  19. data/sig/timely-app/client/clients.rbs +12 -0
  20. data/sig/timely-app/client/events.rbs +36 -0
  21. data/sig/timely-app/client/forecasts.rbs +12 -0
  22. data/sig/timely-app/client/labels.rbs +16 -0
  23. data/sig/timely-app/client/permissions.rbs +8 -0
  24. data/sig/timely-app/client/projects.rbs +14 -0
  25. data/sig/timely-app/client/reports.rbs +8 -0
  26. data/sig/timely-app/client/roles.rbs +6 -0
  27. data/sig/timely-app/client/teams.rbs +14 -0
  28. data/sig/timely-app/client/user_capacities.rbs +8 -0
  29. data/sig/timely-app/client/users.rbs +16 -0
  30. data/sig/timely-app/client/webhooks.rbs +14 -0
  31. data/sig/timely-app/client.rbs +24 -0
  32. data/sig/timely-app/errors.rbs +24 -0
  33. data/sig/timely-app/link_header.rbs +8 -0
  34. data/sig/timely-app/params.rbs +14 -0
  35. data/sig/timely-app/record.rbs +15 -0
  36. data/sig/timely-app/response.rbs +10 -0
  37. data/sig/timely-app.rbs +6 -0
  38. data/timely-app.gemspec +26 -18
  39. metadata +174 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0be07dc2504cd0d663370364349e9c32ba0f224feedd2c8a1d34cdf000236d1a
4
- data.tar.gz: 327c2065f8e757bb081c12b266154387989ea3d55d83b3a191af60b7d8a2d35c
3
+ metadata.gz: c82f58f7c3e0713310beb5653d74487822d9f96bb883ae15805c5987896a589e
4
+ data.tar.gz: d90c62ee9a7baa1b29468f70997a7b1e5e6236d8553c9d92abfc082855595292
5
5
  SHA512:
6
- metadata.gz: 78b6bd494db0a7a2c1e2bb75f63573bc5ff74d8dfbce3fcdf6a5d809810f91579ee07d77ebcfd8c77b63659ac499fc8918b0f031d21856f59bdb21a6378d13fa
7
- data.tar.gz: 9762b80efff32de7b69b757b2f20993d97c6e3ff2270c80e5e181cd1ab002425177221df849275d3d414244e743235c0fdf322c1f7f594de68816f7c16465637
6
+ metadata.gz: cf7b4edda75f282566b4f38c3e48c88f716056055734dae4bd2a08016e5d1e9d7d148922fc4ddcd5625fde5740376cb6e0088bf0c8a558c5d78e6e4723f84668
7
+ data.tar.gz: 3cdb10455d12dbc9f265ea500bccb965775e2d767ae8e798bea35a356ce8065036c0402e60016ff7feb2ea2de2198ea75b901592ac3c45993e3f55c953662ba7
data/CHANGELOG.md CHANGED
@@ -1,41 +1,53 @@
1
- # 1.3.0
1
+ # CHANGELOG
2
2
 
3
- * Set ruby version minimum requirement to 2.5.0
3
+ ## 1.3.2 (2026-07-25)
4
4
 
5
- # 1.2.0
5
+ - BREAKING: Require Ruby 3.4 or newer
6
+ - Fix `get_clients` to call `/1.1/:account_id/clients` instead of `/1.1/accounts`
7
+ - Move `TimelyApp::Cli` under `lib/`
6
8
 
7
- * Fix version definition
9
+ ## 1.3.1 (2023-09-30)
8
10
 
9
- # 1.1.1
11
+ - Refresh gemfile lock
10
12
 
11
- * Update gem configuration
13
+ ## 1.3.0 (2023-08-30)
12
14
 
13
- # 1.1.0
15
+ - Set minimum ruby version requirement to 2.5.0
14
16
 
15
- * Update ruby version to 3.2.2
16
- * Update dependencies
17
+ ## 1.2.0 (2023-08-29)
17
18
 
18
- # 1.0.5
19
+ - Fix version definition
19
20
 
20
- * Fix verbose mode check
21
+ ## 1.1.1 (2023-08-29)
21
22
 
22
- # 1.0.4
23
+ - Update gem configuration
23
24
 
24
- * Update CLI to check input properly and handle command arguments
25
+ ## 1.1.0 (2023-08-15)
25
26
 
26
- # 1.0.3
27
+ - Update ruby version to 3.2.2
28
+ - Update dependencies
27
29
 
28
- * Fix gemspec
30
+ ## 1.0.5 (2023-03-02)
29
31
 
30
- # 1.0.2
32
+ - Fix verbose mode check
31
33
 
32
- * Add basic CLI script `timely-app`
34
+ ## 1.0.4 (2023-02-14)
33
35
 
34
- # 1.0.1
36
+ - Update CLI to check input properly and handle command arguments
35
37
 
36
- * Fix oauth token request
37
- * Add example web service for CLI authorization
38
+ ## 1.0.3 (2023-02-14)
38
39
 
39
- # 1.0.0
40
+ - Fix gemspec
40
41
 
41
- * Initial version
42
+ ## 1.0.2 (2023-02-14)
43
+
44
+ - Add basic CLI script `timely-app`
45
+
46
+ ## 1.0.1 (2023-02-14)
47
+
48
+ - Fix oauth token request
49
+ - Add example web service for CLI authorization
50
+
51
+ ## 1.0.0 (2023-02-14)
52
+
53
+ - Initial version
data/README.md CHANGED
@@ -1,19 +1,25 @@
1
1
  # timely-app
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/timely-app.svg)](https://badge.fury.io/rb/timely-app) [![Test Status](https://github.com/amkisko/timely-app/actions/workflows/test.yml/badge.svg)](https://github.com/amkisko/timely-app/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/amkisko/timely_app.rb/graph/badge.svg?token=QL3A7ATCRK)](https://codecov.io/gh/amkisko/timely_app.rb)
3
+ [![Gem Version](https://badge.fury.io/rb/timely-app.svg)](https://badge.fury.io/rb/timely-app) [![Test Status](https://github.com/amkisko/timely-app/actions/workflows/test.yml/badge.svg)](https://github.com/amkisko/timely-app/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/amkisko/timely_app.rb/graph/badge.svg?token=QL3A7ATCRK)](https://app.codecov.io/github/amkisko/timely_app.rb)
4
4
 
5
5
  Ruby client for the [Timely API](https://dev.timelyapp.com).
6
6
 
7
7
  Sponsored by [Kisko Labs](https://www.kiskolabs.com).
8
8
 
9
+ <a href="https://www.kiskolabs.com">
10
+ <img src="kisko.svg" width="200" alt="Sponsored by Kisko Labs" />
11
+ </a>
12
+
9
13
  ## Install
10
14
 
11
15
  Using Bundler:
16
+
12
17
  ```sh
13
18
  bundle add timely-app
14
19
  ```
15
20
 
16
21
  Using RubyGems:
22
+
17
23
  ```sh
18
24
  gem install timely-app
19
25
  ```
@@ -99,6 +105,19 @@ gem build timely-app.gemspec
99
105
  gem push timely-app-*.gem
100
106
  ```
101
107
 
108
+ ## Links
109
+
110
+ - [GitHub](https://github.com/amkisko/timely_app.rb)
111
+ - [GitLab](https://gitlab.com/amkisko/timely_app.rb)
112
+ - [RubyGems](https://rubygems.org/gems/timely-app)
113
+ - [Versions Atom](https://rubygems.org/gems/timely-app/versions.atom) (feed id `5816973660388`)
114
+ - [libraries.io](https://libraries.io/rubygems/timely-app)
115
+ - [Deps.dev](https://deps.dev/rubygems/timely-app)
116
+ - [SonarCloud](https://sonarcloud.io/project/overview?id=amkisko_timely_app.rb)
117
+ - [Snyk](https://snyk.io/test/github/amkisko/timely_app.rb)
118
+ - [Codecov](https://app.codecov.io/github/amkisko/timely_app.rb)
119
+ - [OpenSSF Scorecard](https://scorecard.dev/viewer/?uri=github.com/amkisko/timely_app.rb)
120
+
102
121
  ## License
103
122
 
104
123
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/bin/timely-app CHANGED
@@ -4,121 +4,6 @@ require "yaml"
4
4
  require "optparse"
5
5
  require "timely-app"
6
6
 
7
- module TimelyApp
8
- class CLI
9
- attr_reader :options, :client
10
-
11
- def initialize(options = {})
12
- @options = options
13
- @client = TimelyApp::Client.new(
14
- access_token: options[:access_token] || fetch_access_token,
15
- account_id: options[:account_id] || fetch_account_id,
16
- verbose: options[:verbose]
17
- )
18
- end
19
-
20
- def get_config(key)
21
- read_config_file&.fetch(key, nil)
22
- end
23
-
24
- def set_config(key, value)
25
- save_config_file(key => value)
26
- end
27
-
28
- def command_exists?(cmd)
29
- return false if cmd.nil? || cmd.empty?
30
-
31
- client.respond_to?(cmd)
32
- end
33
-
34
- def call(cmd, *args)
35
- client.send(cmd, *args)
36
- end
37
-
38
- def auth(client_id, client_secret)
39
- if !client_id || !client_secret
40
- puts "Usage: timely-app auth CLIENT_ID CLIENT_SECRET"
41
- exit 1
42
- end
43
-
44
- auth_client = TimelyApp::Client.new(verbose: options[:verbose])
45
- auth_url = auth_client.get_oauth_authorize_url(
46
- client_id: client_id,
47
- redirect_uri: "urn:ietf:wg:oauth:2.0:oob"
48
- )
49
- puts "Visit this URL in your browser:"
50
- puts auth_url
51
- puts "\nEnter authorization code here:"
52
- code = gets.chomp
53
- begin
54
- token = auth_client.post_oauth_token(
55
- client_id: client_id,
56
- client_secret: client_secret,
57
- code: code,
58
- redirect_uri: "urn:ietf:wg:oauth:2.0:oob",
59
- grant_type: "authorization_code"
60
- )
61
- if options[:save]
62
- save_config_file(
63
- access_token: token.access_token,
64
- refresh_token: token.refresh_token,
65
- created_at: token.created_at
66
- )
67
- else
68
- puts "\nAccess token:\n#{token.access_token}\n"
69
- end
70
- if options[:verbose]
71
- puts "Token details: #{token.to_h}"
72
- end
73
- rescue TimelyApp::Error => e
74
- puts "Authentication failed"
75
- if options[:verbose]
76
- puts "Code: #{code}"
77
- puts "Response code: #{e.response.code}"
78
- puts "Response: #{e.response.body}"
79
- end
80
- exit 1
81
- end
82
- end
83
-
84
- private
85
-
86
- def config_file_path
87
- Dir.home + "/.timelyrc"
88
- end
89
-
90
- def read_config_file
91
- if File.exist?(config_file_path)
92
- YAML.load_file(config_file_path)
93
- end
94
- end
95
-
96
- def fetch_account_id
97
- read_config_file&.fetch("account_id", nil)
98
- end
99
-
100
- def fetch_access_token
101
- read_config_file&.fetch("access_token", nil)
102
- end
103
-
104
- def check_access_token
105
- if !fetch_access_token
106
- puts "No access token found. Run `timely-app auth` to get one."
107
- exit 1
108
- end
109
- end
110
-
111
- def save_config_file(**options)
112
- config = read_config_file || {}
113
- config.merge!(options)
114
- File.open(config_file_path, "w") do |f|
115
- f.write(config.to_yaml)
116
- end
117
- puts "Saved to #{config_file_path}"
118
- end
119
- end
120
- end
121
-
122
7
  options = {}
123
8
  OptionParser.new do |opts|
124
9
  opts.banner = "Usage: timely-app [command] [options]"
@@ -141,8 +26,8 @@ cli = TimelyApp::CLI.new(options)
141
26
  cmd = ARGV.shift
142
27
  case cmd
143
28
  when "auth"
144
- client_id = ARGV.shift || ENV.fetch('TIMELY_CLIENT_ID')
145
- client_secret = ARGV.shift || ENV.fetch('TIMELY_CLIENT_SECRET')
29
+ client_id = ARGV.shift || ENV.fetch("TIMELY_CLIENT_ID")
30
+ client_secret = ARGV.shift || ENV.fetch("TIMELY_CLIENT_SECRET")
146
31
  ARGV.clear
147
32
  if client_id && client_secret
148
33
  cli.auth(client_id, client_secret)
@@ -161,7 +46,10 @@ when "config"
161
46
  end
162
47
  else
163
48
  if cli.command_exists?(cmd)
164
- args = ARGV.reduce({}){ |h, arg| k, v = arg.split("="); h[k] = v; h }
49
+ args = ARGV.each_with_object({}) { |arg, h|
50
+ k, v = arg.split("=")
51
+ h[k] = v
52
+ }
165
53
  ARGV.clear
166
54
  response = cli.call(cmd, *args)
167
55
  case response
@@ -0,0 +1,132 @@
1
+ module TimelyApp
2
+ class CLI
3
+ attr_reader :options, :client
4
+
5
+ def initialize(options = {})
6
+ @options = options
7
+ @client = TimelyApp::Client.new(
8
+ access_token: options[:access_token] || fetch_access_token,
9
+ account_id: options[:account_id] || fetch_account_id,
10
+ verbose: options[:verbose]
11
+ )
12
+ end
13
+
14
+ def get_config(key)
15
+ read_config_file&.fetch(key, nil)
16
+ end
17
+
18
+ def set_config(key, value)
19
+ save_config_file(key => value)
20
+ end
21
+
22
+ def command_exists?(cmd)
23
+ return false if cmd.nil? || cmd.empty?
24
+
25
+ client.respond_to?(cmd)
26
+ end
27
+
28
+ def call(cmd, *args)
29
+ client.send(cmd, *args)
30
+ end
31
+
32
+ def auth(client_id, client_secret)
33
+ validate_auth_credentials!(client_id, client_secret)
34
+
35
+ auth_client = TimelyApp::Client.new(verbose: options[:verbose])
36
+ code = authorize_via_browser(auth_client, client_id)
37
+ token = fetch_oauth_token(auth_client, client_id, client_secret, code)
38
+ persist_or_print_token(token)
39
+ rescue TimelyApp::Error => error
40
+ handle_auth_failure(error, code)
41
+ end
42
+
43
+ private
44
+
45
+ def validate_auth_credentials!(client_id, client_secret)
46
+ return if client_id && client_secret
47
+
48
+ puts "Usage: timely-app auth CLIENT_ID CLIENT_SECRET"
49
+ exit 1
50
+ end
51
+
52
+ def authorize_via_browser(auth_client, client_id)
53
+ auth_url = auth_client.get_oauth_authorize_url(
54
+ client_id: client_id,
55
+ redirect_uri: oauth_redirect_uri
56
+ )
57
+ puts "Visit this URL in your browser:"
58
+ puts auth_url
59
+ puts "\nEnter authorization code here:"
60
+ gets.chomp
61
+ end
62
+
63
+ def oauth_redirect_uri
64
+ "urn:ietf:wg:oauth:2.0:oob"
65
+ end
66
+
67
+ def fetch_oauth_token(auth_client, client_id, client_secret, code)
68
+ auth_client.post_oauth_token(
69
+ client_id: client_id,
70
+ client_secret: client_secret,
71
+ code: code,
72
+ redirect_uri: oauth_redirect_uri,
73
+ grant_type: "authorization_code"
74
+ )
75
+ end
76
+
77
+ def persist_or_print_token(token)
78
+ if options[:save]
79
+ save_config_file(
80
+ access_token: token.access_token,
81
+ refresh_token: token.refresh_token,
82
+ created_at: token.created_at
83
+ )
84
+ else
85
+ puts "\nAccess token:\n#{token.access_token}\n"
86
+ end
87
+ puts "Token details: #{token.to_h}" if options[:verbose]
88
+ end
89
+
90
+ def handle_auth_failure(error, code)
91
+ puts "Authentication failed"
92
+ if options[:verbose]
93
+ puts "Code: #{code}"
94
+ puts "Response code: #{error.response.code}"
95
+ puts "Response: #{error.response.body}"
96
+ end
97
+ exit 1
98
+ end
99
+
100
+ def config_file_path
101
+ Dir.home + "/.timelyrc"
102
+ end
103
+
104
+ def read_config_file
105
+ if File.exist?(config_file_path)
106
+ YAML.load_file(config_file_path)
107
+ end
108
+ end
109
+
110
+ def fetch_account_id
111
+ read_config_file&.fetch("account_id", nil)
112
+ end
113
+
114
+ def fetch_access_token
115
+ read_config_file&.fetch("access_token", nil)
116
+ end
117
+
118
+ def check_access_token
119
+ unless fetch_access_token
120
+ puts "No access token found. Run `timely-app auth` to get one."
121
+ exit 1
122
+ end
123
+ end
124
+
125
+ def save_config_file(**options)
126
+ config = read_config_file || {}
127
+ config.merge!(options)
128
+ File.write(config_file_path, config.to_yaml)
129
+ puts "Saved to #{config_file_path}"
130
+ end
131
+ end
132
+ end
@@ -4,7 +4,7 @@
4
4
  module TimelyApp
5
5
  class Client
6
6
  def get_accounts
7
- get('/1.1/accounts')
7
+ get("/1.1/accounts")
8
8
  end
9
9
 
10
10
  def get_account_activities(account_id, **params)
@@ -6,7 +6,7 @@ module TimelyApp
6
6
  def get_oauth_authorize_url(client_id:, redirect_uri:)
7
7
  host_uri_join(
8
8
  "/1.1/oauth/authorize",
9
- response_type: 'code',
9
+ response_type: "code",
10
10
  redirect_uri: redirect_uri,
11
11
  client_id: client_id
12
12
  )
@@ -8,7 +8,7 @@ module TimelyApp
8
8
  end
9
9
 
10
10
  def get_clients(**params)
11
- get('/1.1/accounts', params)
11
+ get("/1.1/#{account_id}/clients", **params)
12
12
  end
13
13
 
14
14
  def get_client(id)
@@ -1,29 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'timely-app/errors'
4
- require 'timely-app/link_header'
5
- require 'timely-app/params'
6
- require 'timely-app/record'
7
- require 'timely-app/response'
8
- require 'net/http'
9
- require 'json'
3
+ require "timely-app/errors"
4
+ require "timely-app/link_header"
5
+ require "timely-app/params"
6
+ require "timely-app/record"
7
+ require "timely-app/response"
8
+ require "net/http"
9
+ require "json"
10
10
 
11
11
  module TimelyApp
12
12
  class Client
13
13
  attr_accessor :account_id
14
14
 
15
15
  def initialize(options = {})
16
- @auth_header = 'Authorization'
16
+ @auth_header = "Authorization"
17
17
  @auth_value = "Bearer #{options[:access_token]}"
18
18
  @user_agent = options.fetch(:user_agent) { "timely-app/#{VERSION} ruby/#{RUBY_VERSION}" }
19
19
 
20
- @host = 'api.timelyapp.com'
20
+ @host = "api.timelyapp.com"
21
21
 
22
22
  @http = Net::HTTP.new(@host, Net::HTTP.https_default_port)
23
23
  @http.use_ssl = true
24
24
 
25
25
  @account_id = options[:account_id]
26
- @verbose = options[:verbose] || !ENV['VERBOSE'].nil? || false
26
+ @verbose = options[:verbose] || !ENV["VERBOSE"].nil? || false
27
27
  end
28
28
 
29
29
  def get(path, params = nil)
@@ -37,7 +37,7 @@ module TimelyApp
37
37
  end
38
38
 
39
39
  def host_uri_join(path, params)
40
- URI::join("https://#{@host}", Params.join(path, params)).to_s
40
+ URI.join("https://#{@host}", Params.join(path, params)).to_s
41
41
  end
42
42
 
43
43
  def post(path, attributes)
@@ -53,24 +53,29 @@ module TimelyApp
53
53
  end
54
54
 
55
55
  def request(http_request, body_object = nil)
56
- http_request['User-Agent'] = @user_agent
57
- http_request[@auth_header] = @auth_value
56
+ apply_request_headers(http_request, body_object)
57
+ response = @http.request(http_request)
58
+ log_verbose_exchange(http_request, response)
59
+ raise Response.error(response) unless response.is_a?(Net::HTTPSuccess)
58
60
 
59
- if body_object
60
- http_request['Content-Type'] = 'application/json'
61
- http_request.body = JSON.generate(body_object)
62
- end
61
+ Response.parse(response)
62
+ end
63
63
 
64
- response = @http.request(http_request)
64
+ def apply_request_headers(http_request, body_object)
65
+ http_request["User-Agent"] = @user_agent
66
+ http_request[@auth_header] = @auth_value
65
67
 
66
- if verbose?
67
- puts ">> request: #{http_request.method} #{http_request.path} #{http_request.body}"
68
- puts "<< response: #{http_request.method} #{http_request.path} #{response.code} #{response.body}"
69
- end
68
+ return unless body_object
70
69
 
71
- raise Response.error(response) unless response.is_a?(Net::HTTPSuccess)
70
+ http_request["Content-Type"] = "application/json"
71
+ http_request.body = JSON.generate(body_object)
72
+ end
72
73
 
73
- Response.parse(response)
74
+ def log_verbose_exchange(http_request, response)
75
+ return unless verbose?
76
+
77
+ puts ">> request: #{http_request.method} #{http_request.path} #{http_request.body}"
78
+ puts "<< response: #{http_request.method} #{http_request.path} #{response.code} #{response.body}"
74
79
  end
75
80
  end
76
81
  end
@@ -16,6 +16,6 @@ module TimelyApp
16
16
 
17
17
  UnauthorizedError = Class.new(ClientError)
18
18
 
19
- NotFound = Class.new(ClientError)
19
+ NotFoundError = Class.new(ClientError)
20
20
  ForbiddenError = Class.new(ClientError)
21
21
  end
@@ -1,5 +1,5 @@
1
- require 'timely-app/record'
2
- require 'uri'
1
+ require "timely-app/record"
2
+ require "uri"
3
3
 
4
4
  module TimelyApp
5
5
  module LinkHeader
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
- require 'cgi'
2
+
3
+ require "cgi"
3
4
 
4
5
  module TimelyApp
5
6
  module Params
@@ -8,17 +9,17 @@ module TimelyApp
8
9
  def join(path, params = nil)
9
10
  return path if params.nil? || params.empty?
10
11
 
11
- path + '?' + encode(params)
12
+ path + "?" + encode(params)
12
13
  end
13
14
 
14
15
  def encode(params)
15
- params.map { |k, v| "#{escape(k)}=#{array_escape(v)}" }.join('&')
16
+ params.map { |k, v| "#{escape(k)}=#{array_escape(v)}" }.join("&")
16
17
  end
17
18
 
18
19
  private
19
20
 
20
21
  def array_escape(object)
21
- Array(object).map { |value| escape(value) }.join(',')
22
+ Array(object).map { |value| escape(value) }.join(",")
22
23
  end
23
24
 
24
25
  def escape(component)
@@ -14,13 +14,13 @@ module TimelyApp
14
14
 
15
15
  def method_missing(name, *args, &block)
16
16
  if @attributes.has_key?(name) && args.empty? && block.nil?
17
- return @attributes[name]
17
+ @attributes[name]
18
18
  else
19
- super name, *args, &block
19
+ super
20
20
  end
21
21
  end
22
22
 
23
- def respond_to_missing?(name, include_private = false)
23
+ def respond_to_missing?(name, _include_private = false)
24
24
  @attributes.has_key?(name)
25
25
  end
26
26
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
- require 'net/http'
3
- require 'json'
2
+
3
+ require "net/http"
4
+ require "json"
4
5
 
5
6
  module TimelyApp
6
7
  module Response
@@ -11,12 +12,12 @@ module TimelyApp
11
12
  return :no_content
12
13
  end
13
14
 
14
- if response.content_type == 'application/json'
15
+ if response.content_type == "application/json"
15
16
  object = JSON.parse(response.body, symbolize_names: true, object_class: Record)
16
17
 
17
- if response['Link']
18
+ if response["Link"]
18
19
  object.singleton_class.module_eval { attr_accessor :link }
19
- object.link = LinkHeader.parse(response['Link'])
20
+ object.link = LinkHeader.parse(response["Link"])
20
21
  end
21
22
 
22
23
  return object
data/lib/timely-app.rb CHANGED
@@ -1,19 +1,19 @@
1
- require 'timely-app/client'
2
- require 'timely-app/client/accounts'
3
- require 'timely-app/client/auth'
4
- require 'timely-app/client/clients'
5
- require 'timely-app/client/events'
6
- require 'timely-app/client/forecasts'
7
- require 'timely-app/client/labels'
8
- require 'timely-app/client/permissions'
9
- require 'timely-app/client/projects'
10
- require 'timely-app/client/reports'
11
- require 'timely-app/client/roles'
12
- require 'timely-app/client/teams'
13
- require 'timely-app/client/user_capacities'
14
- require 'timely-app/client/users'
15
- require 'timely-app/client/webhooks'
1
+ require "timely-app/client"
2
+ require "timely-app/client/accounts"
3
+ require "timely-app/client/auth"
4
+ require "timely-app/client/clients"
5
+ require "timely-app/client/events"
6
+ require "timely-app/client/forecasts"
7
+ require "timely-app/client/labels"
8
+ require "timely-app/client/permissions"
9
+ require "timely-app/client/projects"
10
+ require "timely-app/client/reports"
11
+ require "timely-app/client/roles"
12
+ require "timely-app/client/teams"
13
+ require "timely-app/client/user_capacities"
14
+ require "timely-app/client/users"
15
+ require "timely-app/client/webhooks"
16
16
 
17
17
  module TimelyApp
18
- VERSION = '1.3.0'
18
+ VERSION = "1.3.2"
19
19
  end