basecamp-sdk 0.8.0 → 0.9.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/README.md +2 -1
- data/lib/basecamp/client.rb +5 -0
- data/lib/basecamp/generated/metadata.json +54 -1
- data/lib/basecamp/generated/services/base_service.rb +13 -0
- data/lib/basecamp/generated/services/campfires_service.rb +2 -2
- data/lib/basecamp/generated/services/card_columns_service.rb +3 -3
- data/lib/basecamp/generated/services/checkins_service.rb +5 -4
- data/lib/basecamp/generated/services/client_approvals_service.rb +1 -1
- data/lib/basecamp/generated/services/client_correspondences_service.rb +1 -1
- data/lib/basecamp/generated/services/documents_service.rb +3 -2
- data/lib/basecamp/generated/services/forwards_service.rb +1 -1
- data/lib/basecamp/generated/services/gauges_service.rb +4 -4
- data/lib/basecamp/generated/services/messages_service.rb +4 -3
- data/lib/basecamp/generated/services/my_assignments_service.rb +1 -1
- data/lib/basecamp/generated/services/my_notifications_service.rb +1 -1
- data/lib/basecamp/generated/services/people_service.rb +2 -2
- data/lib/basecamp/generated/services/projects_service.rb +2 -2
- data/lib/basecamp/generated/services/recordings_service.rb +1 -1
- data/lib/basecamp/generated/services/reports_service.rb +2 -2
- data/lib/basecamp/generated/services/schedules_service.rb +5 -4
- data/lib/basecamp/generated/services/search_service.rb +14 -3
- data/lib/basecamp/generated/services/templates_service.rb +4 -5
- data/lib/basecamp/generated/services/timesheets_service.rb +3 -3
- data/lib/basecamp/generated/services/todolists_service.rb +15 -3
- data/lib/basecamp/generated/services/todos_service.rb +1 -1
- data/lib/basecamp/generated/services/tools_service.rb +1 -1
- data/lib/basecamp/generated/services/uploads_service.rb +3 -2
- data/lib/basecamp/generated/services/webhooks_service.rb +2 -2
- data/lib/basecamp/generated/services/wormholes_service.rb +44 -0
- data/lib/basecamp/generated/types.rb +254 -58
- data/lib/basecamp/version.rb +2 -2
- data/scripts/generate-services.rb +24 -10
- data/scripts/generate-types.rb +33 -1
- metadata +3 -2
data/lib/basecamp/version.rb
CHANGED
|
@@ -60,7 +60,8 @@ class ServiceGenerator
|
|
|
60
60
|
'CardSteps' => %w[
|
|
61
61
|
GetCardStep CreateCardStep UpdateCardStep SetCardStepCompletion
|
|
62
62
|
RepositionCardStep
|
|
63
|
-
]
|
|
63
|
+
],
|
|
64
|
+
'Wormholes' => %w[CreateWormhole UpdateWormhole DeleteWormhole]
|
|
64
65
|
},
|
|
65
66
|
'Files' => {
|
|
66
67
|
'Attachments' => %w[CreateAttachment],
|
|
@@ -116,7 +117,7 @@ class ServiceGenerator
|
|
|
116
117
|
},
|
|
117
118
|
'Todos' => {
|
|
118
119
|
'Todos' => %w[ListTodos CreateTodo GetTodo ReplaceTodo CompleteTodo UncompleteTodo TrashTodo],
|
|
119
|
-
'Todolists' => %w[GetTodolistOrGroup UpdateTodolistOrGroup ListTodolists CreateTodolist],
|
|
120
|
+
'Todolists' => %w[GetTodolistOrGroup UpdateTodolistOrGroup ListTodolists CreateTodolist RepositionTodolist],
|
|
120
121
|
'Todosets' => %w[GetTodoset],
|
|
121
122
|
'HillCharts' => %w[GetHillChart UpdateHillChartSettings],
|
|
122
123
|
'TodolistGroups' => %w[ListTodolistGroups CreateTodolistGroup RepositionTodolistGroup]
|
|
@@ -302,6 +303,7 @@ class ServiceGenerator
|
|
|
302
303
|
clientcorrespondences clientreply clientreplies forwardreply
|
|
303
304
|
forwardreplies campfireline campfirelines todolistgroup todolistgroups
|
|
304
305
|
todolistorgroup uploadversions hillchart hillcharts
|
|
306
|
+
wormhole wormholes
|
|
305
307
|
].freeze
|
|
306
308
|
|
|
307
309
|
def initialize(openapi_path)
|
|
@@ -396,7 +398,12 @@ class ServiceGenerator
|
|
|
396
398
|
.select { |p| p['in'] == 'query' }
|
|
397
399
|
.map do |p|
|
|
398
400
|
{
|
|
399
|
-
|
|
401
|
+
# Strip a trailing `[]` from bracketed array wire names (e.g.
|
|
402
|
+
# `bucket_ids[]`): the kwarg and the params-hash key are both clean
|
|
403
|
+
# `bucket_ids`, and Faraday's NestedParamsEncoder re-adds the `[]` when
|
|
404
|
+
# serializing the array value (a raw `bucket_ids[]` key would double to
|
|
405
|
+
# `bucket_ids[][]=`).
|
|
406
|
+
name: p['name'].sub(/\[\]\z/, ''),
|
|
400
407
|
type: schema_to_ruby_type(p['schema']),
|
|
401
408
|
required: p['required'] || false,
|
|
402
409
|
description: p['description']
|
|
@@ -533,7 +540,13 @@ class ServiceGenerator
|
|
|
533
540
|
def schema_to_ruby_type(schema)
|
|
534
541
|
return 'Object' unless schema
|
|
535
542
|
|
|
536
|
-
|
|
543
|
+
# Object-valued members (e.g. a `project`/`gauge`/`schedule` envelope) are passed
|
|
544
|
+
# as a Hash. Resolve $refs and treat only object-typed schemas as Hash; a string
|
|
545
|
+
# ref such as FirstWeekDay must stay String.
|
|
546
|
+
resolved = schema['$ref'] ? resolve_schema_ref(schema) : schema
|
|
547
|
+
return 'Hash' if resolved && resolved['type'] == 'object'
|
|
548
|
+
|
|
549
|
+
case resolved&.fetch('type', nil)
|
|
537
550
|
when 'integer' then 'Integer'
|
|
538
551
|
when 'boolean' then 'Boolean'
|
|
539
552
|
when 'array' then 'Array'
|
|
@@ -691,10 +704,11 @@ class ServiceGenerator
|
|
|
691
704
|
kwargs << "operation: \"#{op[:method_name]}\""
|
|
692
705
|
kwargs << "is_mutation: #{op[:is_mutation]}"
|
|
693
706
|
|
|
694
|
-
project_param = op[:path_params].find { |p| p[:name]
|
|
695
|
-
resource_param = op[:path_params].reject { |p| p[:name]
|
|
707
|
+
project_param = op[:path_params].find { |p| %w[projectId bucketId].include?(p[:name]) }
|
|
708
|
+
resource_param = op[:path_params].reject { |p| %w[projectId bucketId].include?(p[:name]) }
|
|
709
|
+
.select { |p| p[:name].end_with?("Id") || p[:name] == "id" }.last
|
|
696
710
|
|
|
697
|
-
kwargs << "project_id:
|
|
711
|
+
kwargs << "project_id: #{to_snake_case(project_param[:name])}" if project_param
|
|
698
712
|
kwargs << "resource_id: #{to_snake_case(resource_param[:name])}" if resource_param
|
|
699
713
|
|
|
700
714
|
kwargs.join(', ')
|
|
@@ -788,7 +802,7 @@ class ServiceGenerator
|
|
|
788
802
|
# Build params hash for query params
|
|
789
803
|
if op[:query_params].any?
|
|
790
804
|
param_names = op[:query_params].map { |q| "#{to_snake_case(q[:name])}: #{to_snake_case(q[:name])}" }
|
|
791
|
-
lines << " params =
|
|
805
|
+
lines << " params = compact_query_params(#{param_names.join(', ')})"
|
|
792
806
|
lines << " paginate(#{path_expr}, params: params)"
|
|
793
807
|
else
|
|
794
808
|
lines << " paginate(#{path_expr})"
|
|
@@ -802,7 +816,7 @@ class ServiceGenerator
|
|
|
802
816
|
|
|
803
817
|
if op[:query_params].any?
|
|
804
818
|
param_names = op[:query_params].map { |q| "#{to_snake_case(q[:name])}: #{to_snake_case(q[:name])}" }
|
|
805
|
-
lines << " params =
|
|
819
|
+
lines << " params = compact_query_params(#{param_names.join(', ')})"
|
|
806
820
|
lines << " paginate_wrapped(#{path_expr}, key: \"#{pagination_key}\", params: params)"
|
|
807
821
|
else
|
|
808
822
|
lines << " paginate_wrapped(#{path_expr}, key: \"#{pagination_key}\")"
|
|
@@ -834,7 +848,7 @@ class ServiceGenerator
|
|
|
834
848
|
lines << " http_#{http_method}(#{path_expr}, body: #{body_expr}).json"
|
|
835
849
|
elsif op[:query_params].any?
|
|
836
850
|
param_names = op[:query_params].map { |q| "#{to_snake_case(q[:name])}: #{to_snake_case(q[:name])}" }
|
|
837
|
-
lines << " http_#{http_method}(#{path_expr}, params:
|
|
851
|
+
lines << " http_#{http_method}(#{path_expr}, params: compact_query_params(#{param_names.join(', ')})).json"
|
|
838
852
|
else
|
|
839
853
|
lines << " http_#{http_method}(#{path_expr}).json"
|
|
840
854
|
end
|
data/scripts/generate-types.rb
CHANGED
|
@@ -124,6 +124,12 @@ if __FILE__ == $PROGRAM_NAME
|
|
|
124
124
|
|
|
125
125
|
puts ''
|
|
126
126
|
puts " # #{name}"
|
|
127
|
+
# Documentation-only deprecation (see #406): YARD marks a whole class/method,
|
|
128
|
+
# not individual params, so a class-level @deprecated tag documents a wholly
|
|
129
|
+
# deprecated type.
|
|
130
|
+
if schema['deprecated']
|
|
131
|
+
puts " # @deprecated #{schema['x-deprecated-reason'] || 'deprecated'}"
|
|
132
|
+
end
|
|
127
133
|
puts " class #{name}"
|
|
128
134
|
puts ' include TypeHelpers'
|
|
129
135
|
|
|
@@ -131,6 +137,19 @@ if __FILE__ == $PROGRAM_NAME
|
|
|
131
137
|
# Add system_label for schemas with flexible integer fields
|
|
132
138
|
has_flexible = ordered_props.any? { |k| properties[k]['x-go-type']&.include?('FlexibleInt64') }
|
|
133
139
|
attr_names << 'system_label' if has_flexible
|
|
140
|
+
|
|
141
|
+
# Per-attribute deprecation. The accessors are declared in one grouped
|
|
142
|
+
# attr_accessor, so a bare comment would wrongly document every attribute;
|
|
143
|
+
# a YARD @!attribute directive scopes the @deprecated tag to just this one.
|
|
144
|
+
ordered_props.each do |k|
|
|
145
|
+
ps = properties[k]
|
|
146
|
+
next unless ps['deprecated']
|
|
147
|
+
|
|
148
|
+
ruby_name = k.gsub(/([A-Z])/, '_\1').downcase.gsub(/^_/, '')
|
|
149
|
+
puts " # @!attribute [rw] #{ruby_name}"
|
|
150
|
+
puts " # @deprecated #{ps['x-deprecated-reason'] || 'deprecated'}"
|
|
151
|
+
end
|
|
152
|
+
|
|
134
153
|
puts " attr_accessor #{attr_names.map { |n| ":#{n}" }.join(", ")}"
|
|
135
154
|
|
|
136
155
|
unless required_props.empty?
|
|
@@ -182,7 +201,20 @@ if __FILE__ == $PROGRAM_NAME
|
|
|
182
201
|
attr_name = prop_name.gsub(/([A-Z])/, '_\1').downcase.gsub(/^_/, '')
|
|
183
202
|
puts " \"#{prop_name}\" => @#{attr_name},"
|
|
184
203
|
end
|
|
185
|
-
|
|
204
|
+
# A required-and-nullable field (OpenAPI 3.1 `type: [..., "null"]`) carries an
|
|
205
|
+
# explicit null that must survive to_h; plain .compact would drop it. Keep
|
|
206
|
+
# nil for exactly those keys — required-but-non-nullable fields still get
|
|
207
|
+
# dropped when nil, like any other nil. Everything else keeps .compact.
|
|
208
|
+
required_nullable = required_fields.select do |k|
|
|
209
|
+
t = properties[k] && properties[k]['type']
|
|
210
|
+
t.is_a?(Array) && t.include?('null')
|
|
211
|
+
end
|
|
212
|
+
if required_nullable.any?
|
|
213
|
+
keep_list = required_nullable.map { |k| "\"#{k}\"" }.join(', ')
|
|
214
|
+
puts " }.reject { |k, v| v.nil? && ![#{keep_list}].include?(k) }"
|
|
215
|
+
else
|
|
216
|
+
puts ' }.compact'
|
|
217
|
+
end
|
|
186
218
|
puts ' end'
|
|
187
219
|
puts ''
|
|
188
220
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: basecamp-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Basecamp
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -223,6 +223,7 @@ files:
|
|
|
223
223
|
- lib/basecamp/generated/services/uploads_service.rb
|
|
224
224
|
- lib/basecamp/generated/services/vaults_service.rb
|
|
225
225
|
- lib/basecamp/generated/services/webhooks_service.rb
|
|
226
|
+
- lib/basecamp/generated/services/wormholes_service.rb
|
|
226
227
|
- lib/basecamp/generated/types.rb
|
|
227
228
|
- lib/basecamp/hooks.rb
|
|
228
229
|
- lib/basecamp/http.rb
|