hubspot-api-client 7.3.0 → 8.0.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/lib/hubspot-api-client.rb +55 -24
  4. data/lib/hubspot/codegen/cms/hubdb/api/default_api.rb +2090 -0
  5. data/lib/hubspot/codegen/cms/hubdb/api_client.rb +422 -0
  6. data/lib/hubspot/codegen/cms/hubdb/api_error.rb +61 -0
  7. data/lib/hubspot/codegen/cms/hubdb/configuration.rb +251 -0
  8. data/lib/hubspot/codegen/cms/hubdb/models/batch_input_hub_db_table_row_v3.rb +217 -0
  9. data/lib/hubspot/codegen/cms/hubdb/models/batch_input_json_node.rb +215 -0
  10. data/lib/hubspot/codegen/cms/hubdb/models/batch_input_string.rb +217 -0
  11. data/lib/hubspot/codegen/cms/hubdb/models/batch_response_hub_db_table_row_v3_with_errors.rb +333 -0
  12. data/lib/hubspot/codegen/cms/hubdb/models/collection_response_with_total_hub_db_table_row_v3.rb +240 -0
  13. data/lib/hubspot/codegen/cms/hubdb/models/collection_response_with_total_hub_db_table_v3.rb +240 -0
  14. data/lib/hubspot/codegen/cms/hubdb/models/column.rb +388 -0
  15. data/lib/hubspot/codegen/cms/hubdb/models/column_input.rb +288 -0
  16. data/lib/hubspot/codegen/cms/hubdb/models/error.rb +292 -0
  17. data/lib/hubspot/codegen/cms/hubdb/models/error_detail.rb +258 -0
  18. data/lib/hubspot/codegen/cms/hubdb/models/foreign_id.rb +243 -0
  19. data/lib/hubspot/codegen/cms/hubdb/models/hub_db_table_clone_request.rb +241 -0
  20. data/lib/hubspot/codegen/cms/hubdb/models/hub_db_table_row_v3.rb +291 -0
  21. data/lib/hubspot/codegen/cms/hubdb/models/hub_db_table_row_v3_input.rb +243 -0
  22. data/lib/hubspot/codegen/cms/hubdb/models/hub_db_table_v3.rb +383 -0
  23. data/lib/hubspot/codegen/cms/hubdb/models/hub_db_table_v3_input.rb +295 -0
  24. data/lib/hubspot/codegen/cms/hubdb/models/hub_db_table_v3_live_input.rb +241 -0
  25. data/lib/hubspot/codegen/cms/hubdb/models/import_result.rb +263 -0
  26. data/lib/hubspot/codegen/cms/hubdb/models/next_page.rb +224 -0
  27. data/lib/hubspot/codegen/cms/hubdb/models/option.rb +257 -0
  28. data/lib/hubspot/codegen/cms/hubdb/models/paging.rb +219 -0
  29. data/lib/hubspot/codegen/cms/hubdb/models/previous_page.rb +224 -0
  30. data/lib/hubspot/codegen/cms/hubdb/models/simple_user.rb +257 -0
  31. data/lib/hubspot/version.rb +1 -1
  32. data/sample-apps/timeline-events-app/.env.template +1 -1
  33. data/sample-apps/timeline-events-app/Gemfile.lock +1 -1
  34. data/sample-apps/timeline-events-app/README.md +30 -0
  35. data/sample-apps/timeline-events-app/app/assets/stylesheets/application.css +78 -8
  36. data/sample-apps/timeline-events-app/app/controllers/timeline_events_controller.rb +1 -1
  37. data/sample-apps/timeline-events-app/app/views/timeline_events/index.html.erb +17 -19
  38. metadata +46 -12
@@ -0,0 +1,422 @@
1
+ =begin
2
+ #HubDB endpoints
3
+
4
+ #HubDB is a relational data store that presents data as rows, columns, and cells in a table, much like a spreadsheet. HubDB tables can be added or modified [in the HubSpot CMS](https://knowledge.hubspot.com/cos-general/how-to-edit-hubdb-tables), but you can also use the API endpoints documented here. For more information on HubDB tables and using their data on a HubSpot site, see the [CMS developers site](https://designers.hubspot.com/docs/tools/hubdb). You can also see the [documentation for dynamic pages](https://designers.hubspot.com/docs/tutorials/how-to-build-dynamic-pages-with-hubdb) for more details about the `useForPages` field. HubDB tables now support `DRAFT` and `PUBLISHED` versions. This allows you to update data in the table, either for testing or to allow for a manual approval process, without affecting any live pages using the existing data. Draft data can be reviewed and published by a user working in HubSpot or published via the API. Draft data can also be discarded, allowing users to go back to the live version of the data without disrupting it.
5
+
6
+ The version of the OpenAPI document: v3
7
+
8
+ Generated by: https://openapi-generator.tech
9
+ OpenAPI Generator version: 4.3.1
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'json'
15
+ require 'logger'
16
+ require 'tempfile'
17
+ require 'faraday'
18
+
19
+ module Hubspot
20
+ module Cms
21
+ module Hubdb
22
+ class ApiClient
23
+ # The Configuration object holding settings to be used in the API client.
24
+ attr_accessor :config
25
+
26
+ # Defines the headers to be used in HTTP requests of all API calls by default.
27
+ #
28
+ # @return [Hash]
29
+ attr_accessor :default_headers
30
+
31
+ # Initializes the ApiClient
32
+ # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
33
+ def initialize(config = Configuration.default)
34
+ @config = config
35
+ @user_agent = "hubspot-api-client-ruby; #{VERSION}"
36
+ @default_headers = {
37
+ 'Content-Type' => 'application/json',
38
+ 'User-Agent' => @user_agent
39
+ }
40
+ end
41
+
42
+ def self.default
43
+ @@default ||= ApiClient.new
44
+ end
45
+
46
+ # Call an API with given options.
47
+ #
48
+ # @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
49
+ # the data deserialized from response body (could be nil), response status code and response headers.
50
+ def call_api(http_method, path, opts = {})
51
+ ssl_options = {
52
+ :ca_file => @config.ssl_ca_file,
53
+ :verify => @config.ssl_verify,
54
+ :verify_mode => @config.ssl_verify_mode,
55
+ :client_cert => @config.ssl_client_cert,
56
+ :client_key => @config.ssl_client_key
57
+ }
58
+
59
+ connection = Faraday.new(:url => config.base_url, :ssl => ssl_options) do |conn|
60
+ conn.basic_auth(config.username, config.password)
61
+ if opts[:header_params]["Content-Type"] == "multipart/form-data"
62
+ conn.request :multipart
63
+ conn.request :url_encoded
64
+ end
65
+ conn.adapter(Faraday.default_adapter)
66
+ conn.options[:params_encoder] = Faraday::FlatParamsEncoder
67
+
68
+ # Errors handler settings
69
+ if !config.error_handler.empty?
70
+ config.error_handler.each do |statuses, opts|
71
+ statuses = statuses.is_a?(Integer) ? [statuses] : statuses
72
+ retry_options = {
73
+ max: opts[:max_retries],
74
+ interval: opts[:seconds_delay],
75
+ retry_statuses: statuses,
76
+ methods: %i[post delete get head options put],
77
+ retry_block: -> (env, options, retries, exc) { opts[:retry_block].call }
78
+ }
79
+ conn.request :retry, retry_options
80
+ end
81
+ end
82
+ end
83
+
84
+ begin
85
+ response = connection.public_send(http_method.to_sym.downcase) do |req|
86
+ build_request(http_method, path, req, opts)
87
+ end
88
+
89
+ if @config.debugging
90
+ @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
91
+ end
92
+
93
+ unless response.success?
94
+ if response.status == 0
95
+ # Errors from libcurl will be made visible here
96
+ fail ApiError.new(:code => 0,
97
+ :message => response.return_message)
98
+ else
99
+ fail ApiError.new(:code => response.status,
100
+ :response_headers => response.headers,
101
+ :response_body => response.body),
102
+ response.reason_phrase
103
+ end
104
+ end
105
+ rescue Faraday::TimeoutError
106
+ fail ApiError.new('Connection timed out')
107
+ end
108
+
109
+ return_type = opts[:return_type] || opts[:return_types_map][response.status]
110
+ data = return_type ? deserialize(response, return_type) : nil
111
+
112
+ return data, response.status, response.headers
113
+ end
114
+
115
+ # Builds the HTTP request
116
+ #
117
+ # @param [String] http_method HTTP method/verb (e.g. POST)
118
+ # @param [String] path URL path (e.g. /account/new)
119
+ # @option opts [Hash] :header_params Header parameters
120
+ # @option opts [Hash] :query_params Query parameters
121
+ # @option opts [Hash] :form_params Query parameters
122
+ # @option opts [Object] :body HTTP body (JSON/XML)
123
+ # @return [Typhoeus::Request] A Typhoeus Request
124
+ def build_request(http_method, path, request, opts = {})
125
+ url = build_request_url(path)
126
+ http_method = http_method.to_sym.downcase
127
+
128
+ header_params = @default_headers.merge(opts[:header_params] || {})
129
+ query_params = opts[:query_params] || {}
130
+ form_params = opts[:form_params] || {}
131
+
132
+ update_params_for_auth! header_params, query_params, opts[:auth_names]
133
+
134
+ req_opts = {
135
+ :method => http_method,
136
+ :headers => header_params,
137
+ :params => query_params,
138
+ :params_encoding => @config.params_encoding,
139
+ :timeout => @config.timeout,
140
+ :verbose => @config.debugging
141
+ }
142
+
143
+ if [:post, :patch, :put, :delete].include?(http_method)
144
+ req_body = build_request_body(header_params, form_params, opts[:body])
145
+ req_opts.update :body => req_body
146
+ if @config.debugging
147
+ @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
148
+ end
149
+ end
150
+ request.headers = header_params
151
+ request.body = req_body
152
+ request.url url
153
+ request.params = query_params
154
+ download_file(request) if opts[:return_type] == 'File'
155
+ request
156
+ end
157
+
158
+ # Builds the HTTP request body
159
+ #
160
+ # @param [Hash] header_params Header parameters
161
+ # @param [Hash] form_params Query parameters
162
+ # @param [Object] body HTTP body (JSON/XML)
163
+ # @return [String] HTTP body data in the form of string
164
+ def build_request_body(header_params, form_params, body)
165
+ # http form
166
+ if header_params['Content-Type'] == 'application/x-www-form-urlencoded'
167
+ data = URI.encode_www_form(form_params)
168
+ elsif header_params['Content-Type'] == 'multipart/form-data'
169
+ data = {}
170
+ form_params.each do |key, value|
171
+ case value
172
+ when ::File, ::Tempfile
173
+ # TODO hardcode to application/octet-stream, need better way to detect content type
174
+ data[key] = Faraday::UploadIO.new(value.path, 'application/octet-stream', value.path)
175
+ when ::Array, nil
176
+ # let Faraday handle Array and nil parameters
177
+ data[key] = value
178
+ else
179
+ data[key] = value.to_s
180
+ end
181
+ end
182
+ elsif body
183
+ data = body.is_a?(String) ? body : body.to_json
184
+ else
185
+ data = nil
186
+ end
187
+ data
188
+ end
189
+
190
+ # Check if the given MIME is a JSON MIME.
191
+ # JSON MIME examples:
192
+ # application/json
193
+ # application/json; charset=UTF8
194
+ # APPLICATION/JSON
195
+ # */*
196
+ # @param [String] mime MIME
197
+ # @return [Boolean] True if the MIME is application/json
198
+ def json_mime?(mime)
199
+ (mime == '*/*') || !(mime =~ /Application\/.*json(?!p)(;.*)?/i).nil?
200
+ end
201
+
202
+ # Deserialize the response to the given return type.
203
+ #
204
+ # @param [Response] response HTTP response
205
+ # @param [String] return_type some examples: "User", "Array<User>", "Hash<String, Integer>"
206
+ def deserialize(response, return_type)
207
+ body = response.body
208
+
209
+ # handle file downloading - return the File instance processed in request callbacks
210
+ # note that response body is empty when the file is written in chunks in request on_body callback
211
+ return @tempfile if return_type == 'File'
212
+
213
+ return nil if body.nil? || body.empty?
214
+
215
+ # return response body directly for String return type
216
+ return body if return_type == 'String'
217
+
218
+ # ensuring a default content type
219
+ content_type = response.headers['Content-Type'] || 'application/json'
220
+
221
+ fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type)
222
+
223
+ begin
224
+ data = JSON.parse("[#{body}]", :symbolize_names => true)[0]
225
+ rescue JSON::ParserError => e
226
+ if %w(String Date DateTime).include?(return_type)
227
+ data = body
228
+ else
229
+ raise e
230
+ end
231
+ end
232
+
233
+ convert_to_type data, return_type
234
+ end
235
+
236
+ # Convert data to the given return type.
237
+ # @param [Object] data Data to be converted
238
+ # @param [String] return_type Return type
239
+ # @return [Mixed] Data in a particular type
240
+ def convert_to_type(data, return_type)
241
+ return nil if data.nil?
242
+ case return_type
243
+ when 'String'
244
+ data.to_s
245
+ when 'Integer'
246
+ data.to_i
247
+ when 'Float'
248
+ data.to_f
249
+ when 'Boolean'
250
+ data == true
251
+ when 'DateTime'
252
+ # parse date time (expecting ISO 8601 format)
253
+ DateTime.parse data
254
+ when 'Date'
255
+ # parse date time (expecting ISO 8601 format)
256
+ Date.parse data
257
+ when 'Object'
258
+ # generic object (usually a Hash), return directly
259
+ data
260
+ when /\AArray<(.+)>\z/
261
+ # e.g. Array<Pet>
262
+ sub_type = $1
263
+ data.map { |item| convert_to_type(item, sub_type) }
264
+ when /\AHash\<String, (.+)\>\z/
265
+ # e.g. Hash<String, Integer>
266
+ sub_type = $1
267
+ {}.tap do |hash|
268
+ data.each { |k, v| hash[k] = convert_to_type(v, sub_type) }
269
+ end
270
+ else
271
+ # models, e.g. Pet
272
+ Hubspot::Cms::Hubdb.const_get(return_type).build_from_hash(data)
273
+ end
274
+ end
275
+
276
+ # Save response body into a file in (the defined) temporary folder, using the filename
277
+ # from the "Content-Disposition" header if provided, otherwise a random filename.
278
+ # The response body is written to the file in chunks in order to handle files which
279
+ # size is larger than maximum Ruby String or even larger than the maximum memory a Ruby
280
+ # process can use.
281
+ #
282
+ # @see Configuration#temp_folder_path
283
+ def download_file(request)
284
+ tempfile = nil
285
+ encoding = nil
286
+ request.on_headers do |response|
287
+ content_disposition = response.headers['Content-Disposition']
288
+ if content_disposition && content_disposition =~ /filename=/i
289
+ filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
290
+ prefix = sanitize_filename(filename)
291
+ else
292
+ prefix = 'download-'
293
+ end
294
+ prefix = prefix + '-' unless prefix.end_with?('-')
295
+ encoding = response.body.encoding
296
+ tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
297
+ @tempfile = tempfile
298
+ end
299
+ request.on_body do |chunk|
300
+ chunk.force_encoding(encoding)
301
+ tempfile.write(chunk)
302
+ end
303
+ request.on_complete do |response|
304
+ if tempfile
305
+ tempfile.close
306
+ @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\
307
+ "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\
308
+ "will be deleted automatically with GC. It's also recommended to delete the temp file "\
309
+ "explicitly with `tempfile.delete`"
310
+ end
311
+ end
312
+ end
313
+
314
+ # Sanitize filename by removing path.
315
+ # e.g. ../../sun.gif becomes sun.gif
316
+ #
317
+ # @param [String] filename the filename to be sanitized
318
+ # @return [String] the sanitized filename
319
+ def sanitize_filename(filename)
320
+ filename.gsub(/.*[\/\\]/, '')
321
+ end
322
+
323
+ def build_request_url(path)
324
+ # Add leading and trailing slashes to path
325
+ path = "/#{path}".gsub(/\/+/, '/')
326
+ @config.base_url + path
327
+ end
328
+
329
+ # Update hearder and query params based on authentication settings.
330
+ #
331
+ # @param [Hash] header_params Header parameters
332
+ # @param [Hash] query_params Query parameters
333
+ # @param [String] auth_names Authentication scheme name
334
+ def update_params_for_auth!(header_params, query_params, auth_names)
335
+ Array(auth_names).each do |auth_name|
336
+ auth_setting = @config.auth_settings[auth_name]
337
+ next unless auth_setting
338
+ case auth_setting[:in]
339
+ when 'header' then header_params[auth_setting[:key]] = auth_setting[:value]
340
+ when 'query' then query_params[auth_setting[:key]] = auth_setting[:value]
341
+ else fail ArgumentError, 'Authentication token must be in `query` of `header`'
342
+ end
343
+ end
344
+ end
345
+
346
+ # Sets user agent in HTTP header
347
+ #
348
+ # @param [String] user_agent User agent (e.g. openapi-generator/ruby/1.0.0)
349
+ def user_agent=(user_agent)
350
+ @user_agent = user_agent
351
+ @default_headers['User-Agent'] = @user_agent
352
+ end
353
+
354
+ # Return Accept header based on an array of accepts provided.
355
+ # @param [Array] accepts array for Accept
356
+ # @return [String] the Accept header (e.g. application/json)
357
+ def select_header_accept(accepts)
358
+ return nil if accepts.nil? || accepts.empty?
359
+ # use JSON when present, otherwise use all of the provided
360
+ json_accept = accepts.find { |s| json_mime?(s) }
361
+ json_accept || accepts.join(',')
362
+ end
363
+
364
+ # Return Content-Type header based on an array of content types provided.
365
+ # @param [Array] content_types array for Content-Type
366
+ # @return [String] the Content-Type header (e.g. application/json)
367
+ def select_header_content_type(content_types)
368
+ # use application/json by default
369
+ return 'application/json' if content_types.nil? || content_types.empty?
370
+ # use JSON when present, otherwise use the first one
371
+ json_content_type = content_types.find { |s| json_mime?(s) }
372
+ json_content_type || content_types.first
373
+ end
374
+
375
+ # Convert object (array, hash, object, etc) to JSON string.
376
+ # @param [Object] model object to be converted into JSON string
377
+ # @return [String] JSON string representation of the object
378
+ def object_to_http_body(model)
379
+ return model if model.nil? || model.is_a?(String)
380
+ local_body = nil
381
+ if model.is_a?(Array)
382
+ local_body = model.map { |m| object_to_hash(m) }
383
+ else
384
+ local_body = object_to_hash(model)
385
+ end
386
+ local_body.to_json
387
+ end
388
+
389
+ # Convert object(non-array) to hash.
390
+ # @param [Object] obj object to be converted into JSON string
391
+ # @return [String] JSON string representation of the object
392
+ def object_to_hash(obj)
393
+ if obj.respond_to?(:to_hash)
394
+ obj.to_hash
395
+ else
396
+ obj
397
+ end
398
+ end
399
+
400
+ # Build parameter value according to the given collection format.
401
+ # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
402
+ def build_collection_param(param, collection_format)
403
+ case collection_format
404
+ when :csv
405
+ param.join(',')
406
+ when :ssv
407
+ param.join(' ')
408
+ when :tsv
409
+ param.join("\t")
410
+ when :pipes
411
+ param.join('|')
412
+ when :multi
413
+ # return the array directly as typhoeus will handle it as expected
414
+ param
415
+ else
416
+ fail "unknown collection format: #{collection_format.inspect}"
417
+ end
418
+ end
419
+ end
420
+ end
421
+ end
422
+ end
@@ -0,0 +1,61 @@
1
+ =begin
2
+ #HubDB endpoints
3
+
4
+ #HubDB is a relational data store that presents data as rows, columns, and cells in a table, much like a spreadsheet. HubDB tables can be added or modified [in the HubSpot CMS](https://knowledge.hubspot.com/cos-general/how-to-edit-hubdb-tables), but you can also use the API endpoints documented here. For more information on HubDB tables and using their data on a HubSpot site, see the [CMS developers site](https://designers.hubspot.com/docs/tools/hubdb). You can also see the [documentation for dynamic pages](https://designers.hubspot.com/docs/tutorials/how-to-build-dynamic-pages-with-hubdb) for more details about the `useForPages` field. HubDB tables now support `DRAFT` and `PUBLISHED` versions. This allows you to update data in the table, either for testing or to allow for a manual approval process, without affecting any live pages using the existing data. Draft data can be reviewed and published by a user working in HubSpot or published via the API. Draft data can also be discarded, allowing users to go back to the live version of the data without disrupting it.
5
+
6
+ The version of the OpenAPI document: v3
7
+
8
+ Generated by: https://openapi-generator.tech
9
+ OpenAPI Generator version: 4.3.1
10
+
11
+ =end
12
+
13
+ module Hubspot
14
+ module Cms
15
+ module Hubdb
16
+ class ApiError < StandardError
17
+ attr_reader :code, :response_headers, :response_body
18
+
19
+ # Usage examples:
20
+ # ApiError.new
21
+ # ApiError.new("message")
22
+ # ApiError.new(:code => 500, :response_headers => {}, :response_body => "")
23
+ # ApiError.new(:code => 404, :message => "Not Found")
24
+ def initialize(arg = nil)
25
+ if arg.is_a? Hash
26
+ if arg.key?(:message) || arg.key?('message')
27
+ super(arg[:message] || arg['message'])
28
+ else
29
+ super arg
30
+ end
31
+
32
+ arg.each do |k, v|
33
+ instance_variable_set "@#{k}", v
34
+ end
35
+ else
36
+ super arg
37
+ end
38
+ end
39
+
40
+ # Override to_s to display a friendly error message
41
+ def to_s
42
+ message
43
+ end
44
+
45
+ def message
46
+ if @message.nil?
47
+ msg = "Error message: the server returns an error"
48
+ else
49
+ msg = @message
50
+ end
51
+
52
+ msg += "\nHTTP status code: #{code}" if code
53
+ msg += "\nResponse headers: #{response_headers}" if response_headers
54
+ msg += "\nResponse body: #{response_body}" if response_body
55
+
56
+ msg
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end