basecamp-sdk 0.18.0 → 0.20.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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/basecamp/api_error.rb +5 -3
  4. data/lib/basecamp/bucket_mismatch_error.rb +41 -0
  5. data/lib/basecamp/campfire_discovery_incomplete_error.rb +57 -0
  6. data/lib/basecamp/campfire_index.rb +398 -0
  7. data/lib/basecamp/client.rb +47 -9
  8. data/lib/basecamp/generated/metadata.json +728 -1
  9. data/lib/basecamp/generated/services/account_service.rb +2 -2
  10. data/lib/basecamp/generated/services/attachments_service.rb +1 -1
  11. data/lib/basecamp/generated/services/bookmarks_service.rb +2 -2
  12. data/lib/basecamp/generated/services/boosts_service.rb +3 -3
  13. data/lib/basecamp/generated/services/calendars_service.rb +2 -2
  14. data/lib/basecamp/generated/services/campfires_service.rb +7 -7
  15. data/lib/basecamp/generated/services/card_columns_service.rb +6 -6
  16. data/lib/basecamp/generated/services/card_steps_service.rb +4 -4
  17. data/lib/basecamp/generated/services/card_tables_service.rb +1 -1
  18. data/lib/basecamp/generated/services/cards_service.rb +3 -3
  19. data/lib/basecamp/generated/services/checkins_service.rb +9 -9
  20. data/lib/basecamp/generated/services/client_approvals_service.rb +1 -1
  21. data/lib/basecamp/generated/services/client_correspondences_service.rb +1 -1
  22. data/lib/basecamp/generated/services/client_replies_service.rb +1 -1
  23. data/lib/basecamp/generated/services/client_visibility_service.rb +1 -1
  24. data/lib/basecamp/generated/services/cloud_files_service.rb +3 -3
  25. data/lib/basecamp/generated/services/comments_service.rb +3 -3
  26. data/lib/basecamp/generated/services/documents_service.rb +3 -3
  27. data/lib/basecamp/generated/services/event_feed_service.rb +58 -0
  28. data/lib/basecamp/generated/services/everything_service.rb +2 -2
  29. data/lib/basecamp/generated/services/folders_service.rb +4 -4
  30. data/lib/basecamp/generated/services/forwards_service.rb +3 -3
  31. data/lib/basecamp/generated/services/gauges_service.rb +10 -6
  32. data/lib/basecamp/generated/services/google_documents_service.rb +3 -3
  33. data/lib/basecamp/generated/services/hill_charts_service.rb +2 -2
  34. data/lib/basecamp/generated/services/lineup_service.rb +8 -0
  35. data/lib/basecamp/generated/services/message_boards_service.rb +1 -1
  36. data/lib/basecamp/generated/services/message_types_service.rb +3 -3
  37. data/lib/basecamp/generated/services/messages_service.rb +3 -3
  38. data/lib/basecamp/generated/services/my_assignments_service.rb +3 -3
  39. data/lib/basecamp/generated/services/my_notes_service.rb +2 -2
  40. data/lib/basecamp/generated/services/my_notifications_service.rb +1 -1
  41. data/lib/basecamp/generated/services/people_service.rb +11 -11
  42. data/lib/basecamp/generated/services/projects_service.rb +4 -4
  43. data/lib/basecamp/generated/services/recordings_service.rb +1 -1
  44. data/lib/basecamp/generated/services/reports_service.rb +3 -3
  45. data/lib/basecamp/generated/services/schedules_service.rb +6 -6
  46. data/lib/basecamp/generated/services/search_service.rb +1 -1
  47. data/lib/basecamp/generated/services/subscriptions_service.rb +3 -3
  48. data/lib/basecamp/generated/services/templates_service.rb +8 -8
  49. data/lib/basecamp/generated/services/timesheets_service.rb +4 -4
  50. data/lib/basecamp/generated/services/todolist_groups_service.rb +1 -1
  51. data/lib/basecamp/generated/services/todolists_service.rb +3 -3
  52. data/lib/basecamp/generated/services/todos_service.rb +4 -4
  53. data/lib/basecamp/generated/services/todosets_service.rb +1 -1
  54. data/lib/basecamp/generated/services/tools_service.rb +3 -3
  55. data/lib/basecamp/generated/services/uploads_service.rb +4 -4
  56. data/lib/basecamp/generated/services/vaults_service.rb +3 -3
  57. data/lib/basecamp/generated/services/webhooks_service.rb +3 -3
  58. data/lib/basecamp/generated/services/wormholes_service.rb +2 -2
  59. data/lib/basecamp/generated/types.rb +108 -6
  60. data/lib/basecamp/http.rb +383 -60
  61. data/lib/basecamp/ids.rb +277 -0
  62. data/lib/basecamp/mentions.rb +1119 -0
  63. data/lib/basecamp/person_id_sites.rb +184 -0
  64. data/lib/basecamp/recording_routing_error.rb +50 -0
  65. data/lib/basecamp/recording_summary_error.rb +33 -0
  66. data/lib/basecamp/services/comments_extensions.rb +121 -0
  67. data/lib/basecamp/services/merge_safe.rb +37 -13
  68. data/lib/basecamp/services/recordings_extensions.rb +1305 -0
  69. data/lib/basecamp/services/todolists_extensions.rb +4 -3
  70. data/lib/basecamp/text.rb +94 -0
  71. data/lib/basecamp/unresolved_recording_error.rb +68 -0
  72. data/lib/basecamp/version.rb +1 -1
  73. data/lib/basecamp/webhooks/event.rb +4 -1
  74. data/lib/basecamp.rb +22 -4
  75. data/scripts/generate-metadata.rb +165 -9
  76. data/scripts/generate-services.rb +156 -30
  77. data/scripts/generate-types.rb +19 -0
  78. metadata +15 -3
  79. data/lib/basecamp/generated/services/automation_service.rb +0 -19
@@ -17,7 +17,54 @@ require 'set'
17
17
 
18
18
  # Service generator for Ruby SDK
19
19
  class ServiceGenerator
20
- METHODS = %w[get post put patch delete].freeze
20
+ # A Path Item Object is read by EXCLUSION. Its non-operation fields are a
21
+ # closed, spec-defined set and its extensions are `x-` prefixed, so every
22
+ # OTHER field is an operation. Enumerating the verbs instead is the defect
23
+ # this replaces (#925): Smithy's `@http` trait takes the method as a
24
+ # free-form string it "will use literally and will perform no validation
25
+ # on", so a model author writing `method: "HEAD"` produced a valid model, a
26
+ # valid openapi.json, and no method on any service — the verb was not in the
27
+ # list, so the operation was stepped over in silence.
28
+ NON_OPERATION_FIELDS = %w[summary description servers parameters].freeze
29
+
30
+ # Discovery above is total; emission is bounded by the ONE declaration every
31
+ # generator reads (spec/generated-verbs.json), whose header carries the
32
+ # reasoning. Each verb in it has an `Http` helper (`http_get`, `http_post`, …)
33
+ # the emitted method body calls. An operation on any other verb stops this
34
+ # generator by name instead of vanishing from the SDK — a loud refusal is the
35
+ # acceptable outcome, a silent drop never was.
36
+ #
37
+ # The declaration is ORDERED, and that order is emission order. Ordering is a
38
+ # different job from deciding membership and cannot reproduce #925: membership
39
+ # is decided by exclusion above, so a verb absent from the declaration is
40
+ # refused, never skipped.
41
+ # The self-test points this at a crafted declaration to prove the bound is
42
+ # sourced from the shared file rather than a private literal; production runs
43
+ # never set it.
44
+ GENERATED_VERBS_FILE = ENV.fetch(
45
+ 'BASECAMP_GENERATED_VERBS', File.expand_path('../../spec/generated-verbs.json', __dir__)
46
+ )
47
+
48
+ EMITTABLE_METHODS = begin
49
+ verbs = JSON.parse(File.read(GENERATED_VERBS_FILE, encoding: 'UTF-8'))['verbs']
50
+ # An HTTP method is a TOKEN, so the rule is a positive character class rather
51
+ # than a blankness predicate: `[a-z]+`, identical in all six loaders. Two
52
+ # review rounds chased "blank" across languages — Kotlin and Rust rejected a
53
+ # space while the others accepted it, then Ruby's ASCII `strip` accepted a
54
+ # non-breaking space the Unicode-aware ones rejected — and the next
55
+ # disagreement was guaranteed, because every language defines whitespace
56
+ # differently (Java's Character.isWhitespace excludes U+00A0; Rust's
57
+ # char::is_whitespace includes it; Ruby's String#strip is ASCII-only). A
58
+ # closed positive rule has no such seam: "", " ", "\u00a0", "GET" and 1 are
59
+ # all rejected the same way everywhere.
60
+ unless verbs.is_a?(Array) && !verbs.empty? && verbs.all? { |v| v.is_a?(String) && v.match?(/\A[a-z]+\z/) }
61
+ abort "Error: #{GENERATED_VERBS_FILE} must declare a non-empty `verbs` array of lowercase " \
62
+ 'ASCII method names (/\A[a-z]+\z/).'
63
+ end
64
+ verbs.freeze
65
+ rescue Errno::ENOENT, JSON::ParserError => e
66
+ abort "Error: cannot read the generated-verb declaration #{GENERATED_VERBS_FILE}: #{e.message}"
67
+ end
21
68
 
22
69
  # Schema reference cache for resolving $ref
23
70
  attr_reader :schemas
@@ -33,7 +80,6 @@ class ServiceGenerator
33
80
  'Schedule' => 'Schedules',
34
81
  'People' => 'People',
35
82
  'Projects' => 'Projects',
36
- 'Automation' => 'Automation',
37
83
  'ClientFeatures' => 'ClientFeatures',
38
84
  'Boosts' => 'Boosts',
39
85
  'Untagged' => 'Miscellaneous'
@@ -56,6 +102,7 @@ class ServiceGenerator
56
102
  GetCardColumn UpdateCardColumn SetCardColumnColor
57
103
  EnableCardColumnOnHold DisableCardColumnOnHold
58
104
  CreateCardColumn MoveCardColumn
105
+ SubscribeToCardColumn UnsubscribeFromCardColumn
59
106
  ],
60
107
  'CardSteps' => %w[
61
108
  GetCardStep CreateCardStep UpdateCardStep SetCardStepCompletion
@@ -71,22 +118,11 @@ class ServiceGenerator
71
118
  'CloudFiles' => %w[GetCloudFile CreateCloudFile UpdateCloudFile],
72
119
  'GoogleDocuments' => %w[GetGoogleDocument CreateGoogleDocument UpdateGoogleDocument]
73
120
  },
74
- 'Automation' => {
75
- 'Tools' => %w[GetTool UpdateTool DeleteTool CreateTool EnableTool DisableTool RepositionTool],
76
- 'Recordings' => %w[ArchiveRecording UnarchiveRecording TrashRecording ListRecordings SpotlightRecording UnspotlightRecording],
77
- 'Webhooks' => %w[ListWebhooks CreateWebhook GetWebhook UpdateWebhook DeleteWebhook],
78
- 'Events' => %w[ListEvents],
79
- 'Lineup' => %w[CreateLineupMarker UpdateLineupMarker DeleteLineupMarker],
80
- 'Search' => %w[Search GetSearchMetadata],
81
- 'Templates' => %w[
82
- ListTemplates CreateTemplate GetTemplate UpdateTemplate
83
- DeleteTemplate CreateProjectFromTemplate GetProjectConstruction
84
- GetTemplateLibrary CreateTemplateLibraryCopy GetTemplateLibraryCopy
85
- ],
86
- 'Checkins' => %w[
87
- GetQuestionnaire ListQuestions CreateQuestion GetQuestion
88
- UpdateQuestion ListAnswers CreateAnswer GetAnswer UpdateAnswer
89
- ]
121
+ 'Dock' => {
122
+ 'Tools' => %w[GetTool UpdateTool DeleteTool CreateTool EnableTool DisableTool RepositionTool]
123
+ },
124
+ 'Recordings' => {
125
+ 'Events' => %w[ListEvents]
90
126
  },
91
127
  'Messages' => {
92
128
  'Messages' => %w[GetMessage UpdateMessage CreateMessage ListMessages PinMessage UnpinMessage],
@@ -365,14 +401,78 @@ class ServiceGenerator
365
401
 
366
402
  private
367
403
 
404
+ # Yields [verb, operation] for every operation in a path item, identifying an
405
+ # operation by what it is NOT (see NON_OPERATION_FIELDS). Anything this
406
+ # generator cannot render aborts the run naming the operation.
407
+ def each_operation(path, path_item)
408
+ unless path_item.is_a?(Hash)
409
+ abort "Error: openapi.json path #{path} is a #{path_item.class}, not a path item object."
410
+ end
411
+
412
+ # A `$ref` path item points at operations this generator cannot see without
413
+ # resolving the reference. Skipping it is the same silent under-count the
414
+ # exclusion walk exists to prevent, so refuse until someone teaches it to
415
+ # follow one.
416
+ if path_item.key?('$ref')
417
+ abort "Error: openapi.json path #{path} is a $ref to #{path_item['$ref'].inspect}. " \
418
+ 'This generator cannot resolve a path-item reference, and skipping it would hide ' \
419
+ 'every operation behind it from the SDK. Inline the path item, or teach this ' \
420
+ 'generator to resolve local references.'
421
+ end
422
+
423
+ # OpenAPI 3.2's `additionalOperations` is a MAP of method to Operation, not an
424
+ # operation. Read as one it carries no operationId, so it would drop every
425
+ # operation inside it without saying so. Refuse by name until the walk learns
426
+ # the map shape.
427
+ if path_item.key?('additionalOperations')
428
+ abort "Error: openapi.json path #{path} declares `additionalOperations`, which OpenAPI 3.2 " \
429
+ 'defines as a map of method to Operation. This walk reads a path-item field as a ' \
430
+ 'single operation, so it would drop every operation inside it. Teach the walk the map ' \
431
+ 'shape, or take the field out of the spec.'
432
+ end
433
+
434
+ fields = path_item.keys.reject { |f| NON_OPERATION_FIELDS.include?(f) || f.start_with?('x-') }
435
+ fields.sort_by! { |f| [ EMITTABLE_METHODS.index(f) || EMITTABLE_METHODS.length, f ] }
436
+
437
+ fields.each do |field|
438
+ operation = path_item[field]
439
+
440
+ unless operation.is_a?(Hash)
441
+ abort "Error: openapi.json path #{path} field #{field.inspect} is a #{operation.class}, " \
442
+ 'which is neither a known non-operation field nor an operation object. If a later ' \
443
+ 'OpenAPI version added it, add it to NON_OPERATION_FIELDS with a reason.'
444
+ end
445
+
446
+ unless EMITTABLE_METHODS.include?(field)
447
+ op_id = operation['operationId'] || '(no operationId)'
448
+ abort "Error: openapi.json declares #{field.upcase} #{path} (#{op_id}), and this generator " \
449
+ "emits only #{EMITTABLE_METHODS.map(&:upcase).join('/')}. Generating the rest of the " \
450
+ 'SDK without it would drop the operation from every Ruby client in silence, which is ' \
451
+ 'the failure #925 closed. Give Basecamp::Http a ' \
452
+ "http_#{field} helper, add #{field.inspect} to spec/generated-verbs.json (read that " \
453
+ 'file first — the other five SDKs need the same helper), or take the operation out ' \
454
+ 'of the Smithy model.'
455
+ end
456
+
457
+ # An operation has to be IDENTIFIABLE. OpenAPI lets operationId be omitted,
458
+ # and every walker here used to step over one that was — a silent drop of a
459
+ # real operation, which is #925 wearing a different field.
460
+ op_id = operation['operationId']
461
+ unless op_id.is_a?(String) && !op_id.empty?
462
+ abort "Error: openapi.json declares #{field.upcase} #{path} with no operationId. " \
463
+ 'Everything downstream is keyed by it, and skipping the operation would drop it ' \
464
+ 'from the SDK in silence.'
465
+ end
466
+
467
+ yield field, operation
468
+ end
469
+ end
470
+
368
471
  def group_operations
369
472
  services = {}
370
473
 
371
474
  @openapi['paths'].each do |path, path_item|
372
- METHODS.each do |method|
373
- operation = path_item[method]
374
- next unless operation
375
-
475
+ each_operation(path, path_item) do |method, operation|
376
476
  tag = operation['tags']&.first || 'Untagged'
377
477
  parsed = parse_operation(path, method, operation)
378
478
 
@@ -440,6 +540,14 @@ class ServiceGenerator
440
540
  # Extract body parameters from schema
441
541
  body_params = extract_body_params(body_schema_ref)
442
542
 
543
+ # Only "link" and "cursor" are implemented. Anything else -- a typo, or the
544
+ # "page" style the trait used to advertise -- must fail loudly: read as "not
545
+ # paginated" it would silently ship a method that never walks.
546
+ pagination_style = operation.dig('x-basecamp-pagination', 'style')
547
+ if operation['x-basecamp-pagination'] && !%w[ link cursor ].include?(pagination_style)
548
+ raise "#{operation_id}: unsupported pagination style #{pagination_style.inspect} (expected \"link\" or \"cursor\")"
549
+ end
550
+
443
551
  # Check response
444
552
  success_response = operation.dig('responses', '200') || operation.dig('responses', '201')
445
553
  response_schema = success_response&.dig('content', 'application/json', 'schema')
@@ -470,8 +578,18 @@ class ServiceGenerator
470
578
  returns_array: returns_array,
471
579
  returns_bare_array: returns_bare_array,
472
580
  is_mutation: http_method != 'GET',
473
- has_pagination: !!operation['x-basecamp-pagination'],
474
- pagination_key: operation.dig('x-basecamp-pagination', 'key')
581
+ # Auto-pagination is the "link" style alone: the generated method follows
582
+ # Link: rel="next" and flattens the walk into one array. The "cursor"
583
+ # style is declared for the catalogue and generates none -- each call
584
+ # returns one page carrying its own opaque position, and flattening would
585
+ # swallow every intermediate one.
586
+ has_pagination: pagination_style == 'link',
587
+ # Carried separately because has_pagination is false for cursor, and the
588
+ # bare-array gate below would otherwise walk it anyway.
589
+ cursor_pagination: pagination_style == 'cursor',
590
+ # Link-style only: the key drives envelope unwrapping, and a cursor
591
+ # operation must be typed as its envelope rather than the item under it.
592
+ pagination_key: (pagination_style == 'link' ? operation.dig('x-basecamp-pagination', 'key') : nil)
475
593
  }
476
594
  end
477
595
 
@@ -657,7 +775,10 @@ class ServiceGenerator
657
775
  def generate_method(op, service_name:)
658
776
  lines = []
659
777
 
660
- is_paginated = (op[:returns_array] || op[:has_pagination]) && !op[:pagination_key]
778
+ # A cursor operation never walks, whatever its response shape: has_pagination
779
+ # is already false for it, but a bare-array response would otherwise send it
780
+ # down the Link-following path through returns_array.
781
+ is_paginated = !op[:cursor_pagination] && (op[:returns_array] || op[:has_pagination]) && !op[:pagination_key]
661
782
  is_wrapped_paginated = op[:has_pagination] && op[:pagination_key]
662
783
 
663
784
  # Method signature (paginated operations gain a trailing max_items: kwarg)
@@ -903,6 +1024,11 @@ class ServiceGenerator
903
1024
  # Only GETs are retry-governed in Ruby, and only Http#get accepts the
904
1025
  # operation keyword — mutations go through single_request with no retry.
905
1026
  operation_arg = http_method == 'get' ? ", operation: \"#{op[:operation_id]}\"" : ''
1027
+ # Every verb names its operation to the body decode, which is a separate
1028
+ # channel from the retry keyword above: the typed person-id decode
1029
+ # (Basecamp::PersonIdSites) is keyed by operation id, and a mutation's
1030
+ # response carries people exactly as a read's does.
1031
+ json_call = ".json(operation: \"#{op[:operation_id]}\")"
906
1032
 
907
1033
  if op[:has_binary_body]
908
1034
  # Binary upload - use raw body and set Content-Type header
@@ -914,18 +1040,18 @@ class ServiceGenerator
914
1040
  query_string = query_parts.join('&')
915
1041
  # Modify path_expr to include query string
916
1042
  path_expr_with_query = path_expr.sub(/"$/, "?#{query_string}\"")
917
- lines << " http_#{http_method}_raw(#{path_expr_with_query}, body: data, content_type: content_type).json"
1043
+ lines << " http_#{http_method}_raw(#{path_expr_with_query}, body: data, content_type: content_type)#{json_call}"
918
1044
  else
919
- lines << " http_#{http_method}_raw(#{path_expr}, body: data, content_type: content_type).json"
1045
+ lines << " http_#{http_method}_raw(#{path_expr}, body: data, content_type: content_type)#{json_call}"
920
1046
  end
921
1047
  elsif op[:has_body]
922
1048
  body_expr = build_body_expression(op)
923
- lines << " http_#{http_method}(#{path_expr}, body: #{body_expr}).json"
1049
+ lines << " http_#{http_method}(#{path_expr}, body: #{body_expr})#{json_call}"
924
1050
  elsif op[:query_params].any?
925
1051
  param_names = op[:query_params].map { |q| "#{to_snake_case(q[:name])}: #{to_snake_case(q[:name])}" }
926
- lines << " http_#{http_method}(#{path_expr}, params: compact_query_params(#{param_names.join(', ')})#{operation_arg}).json"
1052
+ lines << " http_#{http_method}(#{path_expr}, params: compact_query_params(#{param_names.join(', ')})#{operation_arg})#{json_call}"
927
1053
  else
928
- lines << " http_#{http_method}(#{path_expr}#{operation_arg}).json"
1054
+ lines << " http_#{http_method}(#{path_expr}#{operation_arg})#{json_call}"
929
1055
  end
930
1056
 
931
1057
  lines
@@ -47,6 +47,23 @@ def generate_helpers
47
47
  value.to_i
48
48
  end
49
49
 
50
+ # A PERSON's id: the one field in this model the reference decodes
51
+ # flexibly (x-go-type: types.FlexibleInt64), and the only one that may
52
+ # arrive as a JSON string.
53
+ #
54
+ # Read with Basecamp::Ids.person_from_wire, which is Go's
55
+ # strconv.ParseInt(s, 10, 64) and is already the rule at the other two
56
+ # person-id sites (the pre-decode normalizer in Basecamp::Http and the
57
+ # flexible reader itself). NOT parse_integer, whose to_i answers 0 for
58
+ # "basecamp" without recording the label, 8 for "010", and — since the
59
+ # normalizer now leaves an out-of-range id as a String for the reader to
60
+ # refuse — a bignum for "18446744073709551616x", which is not an id any
61
+ # API can hold. A refused id is nil here, the same nil a malformed value
62
+ # of any other type gets.
63
+ def parse_flexible_person_id(value)
64
+ Basecamp::Ids.person_from_wire(value)
65
+ end
66
+
50
67
  def parse_float(value)
51
68
  return nil if value.nil?
52
69
  value.to_f
@@ -203,6 +220,8 @@ if __FILE__ == $PROGRAM_NAME
203
220
  elsif prop_schema['type'] == 'array' && prop_schema.dig('items', '$ref')
204
221
  ref_name = prop_schema['items']['$ref'].split('/').last
205
222
  "parse_array(data[\"#{prop_name}\"], \"#{ref_name}\")"
223
+ elsif prop_schema['x-go-type']&.include?('FlexibleInt64')
224
+ "parse_flexible_person_id(data[\"#{prop_name}\"])"
206
225
  elsif prop_schema['type'] == 'integer'
207
226
  "parse_integer(data[\"#{prop_name}\"])"
208
227
  elsif prop_schema['type'] == 'number'
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.18.0
4
+ version: 0.20.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-09-10 00:00:00.000000000 Z
11
+ date: 2026-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -169,6 +169,9 @@ files:
169
169
  - lib/basecamp/auth_error.rb
170
170
  - lib/basecamp/auth_strategy.rb
171
171
  - lib/basecamp/bearer_auth.rb
172
+ - lib/basecamp/bucket_mismatch_error.rb
173
+ - lib/basecamp/campfire_discovery_incomplete_error.rb
174
+ - lib/basecamp/campfire_index.rb
172
175
  - lib/basecamp/chain_hooks.rb
173
176
  - lib/basecamp/client.rb
174
177
  - lib/basecamp/config.rb
@@ -180,7 +183,6 @@ files:
180
183
  - lib/basecamp/generated/metadata.json
181
184
  - lib/basecamp/generated/services/account_service.rb
182
185
  - lib/basecamp/generated/services/attachments_service.rb
183
- - lib/basecamp/generated/services/automation_service.rb
184
186
  - lib/basecamp/generated/services/base_service.rb
185
187
  - lib/basecamp/generated/services/bookmarks_service.rb
186
188
  - lib/basecamp/generated/services/boosts_service.rb
@@ -200,6 +202,7 @@ files:
200
202
  - lib/basecamp/generated/services/comments_service.rb
201
203
  - lib/basecamp/generated/services/documents_service.rb
202
204
  - lib/basecamp/generated/services/drafts_service.rb
205
+ - lib/basecamp/generated/services/event_feed_service.rb
203
206
  - lib/basecamp/generated/services/events_service.rb
204
207
  - lib/basecamp/generated/services/everything_service.rb
205
208
  - lib/basecamp/generated/services/folders_service.rb
@@ -236,10 +239,12 @@ files:
236
239
  - lib/basecamp/generated/types.rb
237
240
  - lib/basecamp/hooks.rb
238
241
  - lib/basecamp/http.rb
242
+ - lib/basecamp/ids.rb
239
243
  - lib/basecamp/limit_exceeded_error.rb
240
244
  - lib/basecamp/list_enumerator.rb
241
245
  - lib/basecamp/list_meta.rb
242
246
  - lib/basecamp/logger_hooks.rb
247
+ - lib/basecamp/mentions.rb
243
248
  - lib/basecamp/network_error.rb
244
249
  - lib/basecamp/noop_hooks.rb
245
250
  - lib/basecamp/not_found_error.rb
@@ -264,19 +269,26 @@ files:
264
269
  - lib/basecamp/operation_info.rb
265
270
  - lib/basecamp/operation_result.rb
266
271
  - lib/basecamp/people_confirmation_required_error.rb
272
+ - lib/basecamp/person_id_sites.rb
267
273
  - lib/basecamp/rate_limit_error.rb
274
+ - lib/basecamp/recording_routing_error.rb
275
+ - lib/basecamp/recording_summary_error.rb
268
276
  - lib/basecamp/request_info.rb
269
277
  - lib/basecamp/request_result.rb
270
278
  - lib/basecamp/security.rb
271
279
  - lib/basecamp/services/authorization_service.rb
272
280
  - lib/basecamp/services/cards_extensions.rb
281
+ - lib/basecamp/services/comments_extensions.rb
273
282
  - lib/basecamp/services/documents_extensions.rb
274
283
  - lib/basecamp/services/merge_safe.rb
284
+ - lib/basecamp/services/recordings_extensions.rb
275
285
  - lib/basecamp/services/schedules_extensions.rb
276
286
  - lib/basecamp/services/todolists_extensions.rb
277
287
  - lib/basecamp/services/todos_extensions.rb
278
288
  - lib/basecamp/static_token_provider.rb
289
+ - lib/basecamp/text.rb
279
290
  - lib/basecamp/token_provider.rb
291
+ - lib/basecamp/unresolved_recording_error.rb
280
292
  - lib/basecamp/usage_error.rb
281
293
  - lib/basecamp/validation_error.rb
282
294
  - lib/basecamp/version.rb
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Basecamp
4
- module Services
5
- # Service for Automation operations
6
- #
7
- # @generated from OpenAPI spec
8
- class AutomationService < BaseService
9
-
10
- # List all lineup markers for the account
11
- # @return [Array<Hash>] response data
12
- def list_lineup_markers()
13
- with_operation(service: "automation", operation: "list_lineup_markers", is_mutation: false) do
14
- http_get("/lineup/markers.json", operation: "ListLineupMarkers").json
15
- end
16
- end
17
- end
18
- end
19
- end