uploadcare-ruby 4.4.2 → 5.0.0.rc1

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 (178) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +7 -0
  3. data/.github/workflows/gem-push.yml +1 -1
  4. data/.github/workflows/ruby.yml +10 -13
  5. data/.gitignore +9 -0
  6. data/.rubocop.yml +95 -8
  7. data/CHANGELOG.md +78 -0
  8. data/Gemfile +23 -6
  9. data/MIGRATING_V5.md +290 -0
  10. data/README.md +422 -671
  11. data/Rakefile +5 -1
  12. data/api_examples/README.md +77 -0
  13. data/api_examples/rest_api/delete_files_storage.rb +3 -5
  14. data/api_examples/rest_api/delete_files_uuid_metadata_key.rb +3 -4
  15. data/api_examples/rest_api/delete_files_uuid_storage.rb +3 -4
  16. data/api_examples/rest_api/delete_groups_uuid.rb +3 -4
  17. data/api_examples/rest_api/delete_webhooks_unsubscribe.rb +3 -4
  18. data/api_examples/rest_api/get_addons_aws_rekognition_detect_labels_execute_status.rb +3 -6
  19. data/api_examples/rest_api/get_addons_aws_rekognition_detect_moderation_labels_execute_status.rb +3 -6
  20. data/api_examples/rest_api/get_addons_remove_bg_execute_status.rb +3 -6
  21. data/api_examples/rest_api/get_addons_uc_clamav_virus_scan_execute_status.rb +3 -6
  22. data/api_examples/rest_api/get_convert_document_status_token.rb +3 -5
  23. data/api_examples/rest_api/get_convert_document_uuid.rb +3 -5
  24. data/api_examples/rest_api/get_convert_video_status_token.rb +3 -5
  25. data/api_examples/rest_api/get_files.rb +3 -5
  26. data/api_examples/rest_api/get_files_uuid.rb +3 -5
  27. data/api_examples/rest_api/get_files_uuid_metadata.rb +3 -5
  28. data/api_examples/rest_api/get_files_uuid_metadata_key.rb +3 -5
  29. data/api_examples/rest_api/get_groups.rb +3 -5
  30. data/api_examples/rest_api/get_groups_uuid.rb +3 -5
  31. data/api_examples/rest_api/get_project.rb +3 -5
  32. data/api_examples/rest_api/get_webhooks.rb +3 -5
  33. data/api_examples/rest_api/post_addons_aws_rekognition_detect_labels_execute.rb +3 -5
  34. data/api_examples/rest_api/post_addons_aws_rekognition_detect_moderation_labels_execute.rb +3 -5
  35. data/api_examples/rest_api/post_addons_remove_bg_execute.rb +3 -5
  36. data/api_examples/rest_api/post_addons_uc_clamav_virus_scan_execute.rb +3 -5
  37. data/api_examples/rest_api/post_convert_document.rb +3 -6
  38. data/api_examples/rest_api/post_convert_video.rb +3 -10
  39. data/api_examples/rest_api/post_files_local_copy.rb +3 -6
  40. data/api_examples/rest_api/post_files_remote_copy.rb +3 -7
  41. data/api_examples/rest_api/post_webhooks.rb +3 -9
  42. data/api_examples/rest_api/put_files_storage.rb +3 -8
  43. data/api_examples/rest_api/put_files_uuid_metadata_key.rb +3 -7
  44. data/api_examples/rest_api/put_files_uuid_storage.rb +3 -5
  45. data/api_examples/rest_api/put_webhooks_id.rb +3 -11
  46. data/api_examples/support/example_helper.rb +250 -0
  47. data/api_examples/support/run_rest_example.rb +161 -0
  48. data/api_examples/support/run_upload_example.rb +88 -0
  49. data/api_examples/upload_api/get_from_url_status.rb +3 -5
  50. data/api_examples/upload_api/get_group_info.rb +3 -6
  51. data/api_examples/upload_api/get_info.rb +3 -6
  52. data/api_examples/upload_api/post_base.rb +3 -5
  53. data/api_examples/upload_api/post_from_url.rb +3 -5
  54. data/api_examples/upload_api/post_group.rb +3 -8
  55. data/api_examples/upload_api/post_multipart_complete.rb +3 -7
  56. data/api_examples/upload_api/post_multipart_start.rb +3 -7
  57. data/api_examples/upload_api/put_multipart_part.rb +4 -0
  58. data/bin/console +1 -1
  59. data/docs/release-notes-5.0.0.rc1.md +34 -0
  60. data/examples/README.md +39 -0
  61. data/examples/batch_upload.rb +54 -0
  62. data/examples/group_creation.rb +88 -0
  63. data/examples/large_file_upload.rb +88 -0
  64. data/examples/simple_upload.rb +39 -0
  65. data/examples/upload_with_progress.rb +84 -0
  66. data/examples/url_upload.rb +56 -0
  67. data/lib/uploadcare/api/rest/addons.rb +107 -0
  68. data/lib/uploadcare/api/rest/document_conversions.rb +65 -0
  69. data/lib/uploadcare/api/rest/file_metadata.rb +71 -0
  70. data/lib/uploadcare/api/rest/files.rb +112 -0
  71. data/lib/uploadcare/api/rest/groups.rb +49 -0
  72. data/lib/uploadcare/api/rest/project.rb +23 -0
  73. data/lib/uploadcare/api/rest/video_conversions.rb +52 -0
  74. data/lib/uploadcare/api/rest/webhooks.rb +74 -0
  75. data/lib/uploadcare/api/rest.rb +254 -0
  76. data/lib/uploadcare/api/upload/files.rb +313 -0
  77. data/lib/uploadcare/api/upload/groups.rb +72 -0
  78. data/lib/uploadcare/api/upload.rb +272 -0
  79. data/lib/uploadcare/client/addons_accessor.rb +85 -0
  80. data/lib/uploadcare/client/api.rb +33 -0
  81. data/lib/uploadcare/client/conversions_accessor.rb +33 -0
  82. data/lib/uploadcare/client/document_conversions_accessor.rb +41 -0
  83. data/lib/uploadcare/client/file_metadata_accessor.rb +46 -0
  84. data/lib/uploadcare/client/files_accessor.rb +82 -0
  85. data/lib/uploadcare/client/groups_accessor.rb +35 -0
  86. data/lib/uploadcare/client/project_accessor.rb +17 -0
  87. data/lib/uploadcare/client/video_conversions_accessor.rb +33 -0
  88. data/lib/uploadcare/client/webhooks_accessor.rb +42 -0
  89. data/lib/uploadcare/client.rb +127 -0
  90. data/lib/uploadcare/cname_generator.rb +68 -0
  91. data/lib/uploadcare/collections/batch_result.rb +35 -0
  92. data/lib/uploadcare/collections/paginated.rb +165 -0
  93. data/lib/uploadcare/configuration.rb +81 -0
  94. data/lib/uploadcare/exception/auth_error.rb +2 -6
  95. data/lib/uploadcare/exception/configuration_error.rb +4 -0
  96. data/lib/uploadcare/exception/conversion_error.rb +2 -6
  97. data/lib/uploadcare/exception/invalid_request_error.rb +4 -0
  98. data/lib/uploadcare/exception/multipart_upload_error.rb +4 -0
  99. data/lib/uploadcare/exception/not_found_error.rb +4 -0
  100. data/lib/uploadcare/exception/request_error.rb +2 -6
  101. data/lib/uploadcare/exception/retry_error.rb +2 -6
  102. data/lib/uploadcare/exception/throttle_error.rb +7 -11
  103. data/lib/uploadcare/exception/unknown_status_error.rb +4 -0
  104. data/lib/uploadcare/exception/upload_error.rb +4 -0
  105. data/lib/uploadcare/exception/upload_timeout_error.rb +4 -0
  106. data/lib/uploadcare/internal/authenticator.rb +101 -0
  107. data/lib/uploadcare/internal/error_handler.rb +102 -0
  108. data/lib/uploadcare/internal/signature_generator.rb +31 -0
  109. data/lib/uploadcare/internal/throttle_handler.rb +36 -0
  110. data/lib/uploadcare/internal/upload_io.rb +110 -0
  111. data/lib/uploadcare/internal/upload_params_generator.rb +86 -0
  112. data/lib/uploadcare/internal/user_agent.rb +22 -0
  113. data/lib/uploadcare/operations/multipart_upload.rb +213 -0
  114. data/lib/uploadcare/operations/upload_router.rb +162 -0
  115. data/lib/uploadcare/resources/addon_execution.rb +97 -0
  116. data/lib/uploadcare/resources/base_resource.rb +61 -0
  117. data/lib/uploadcare/resources/document_conversion.rb +81 -0
  118. data/lib/uploadcare/resources/file.rb +366 -0
  119. data/lib/uploadcare/resources/file_metadata.rb +135 -0
  120. data/lib/uploadcare/resources/group.rb +142 -0
  121. data/lib/uploadcare/resources/project.rb +26 -0
  122. data/lib/uploadcare/resources/video_conversion.rb +59 -0
  123. data/lib/uploadcare/resources/webhook.rb +85 -0
  124. data/lib/uploadcare/result.rb +85 -0
  125. data/lib/uploadcare/signed_url_generators/akamai_generator.rb +60 -56
  126. data/lib/uploadcare/signed_url_generators/base_generator.rb +15 -15
  127. data/lib/uploadcare/version.rb +7 -0
  128. data/lib/uploadcare/webhook_signature_verifier.rb +60 -0
  129. data/lib/uploadcare.rb +84 -50
  130. data/mise.toml +2 -0
  131. data/uploadcare-ruby.gemspec +8 -7
  132. metadata +102 -74
  133. data/api_examples/upload_api/put_presigned_url_x.rb +0 -8
  134. data/lib/uploadcare/api/api.rb +0 -25
  135. data/lib/uploadcare/client/addons_client.rb +0 -69
  136. data/lib/uploadcare/client/conversion/base_conversion_client.rb +0 -59
  137. data/lib/uploadcare/client/conversion/document_conversion_client.rb +0 -45
  138. data/lib/uploadcare/client/conversion/video_conversion_client.rb +0 -46
  139. data/lib/uploadcare/client/file_client.rb +0 -48
  140. data/lib/uploadcare/client/file_list_client.rb +0 -46
  141. data/lib/uploadcare/client/file_metadata_client.rb +0 -36
  142. data/lib/uploadcare/client/group_client.rb +0 -45
  143. data/lib/uploadcare/client/multipart_upload/chunks_client.rb +0 -58
  144. data/lib/uploadcare/client/multipart_upload_client.rb +0 -64
  145. data/lib/uploadcare/client/project_client.rb +0 -20
  146. data/lib/uploadcare/client/rest_client.rb +0 -77
  147. data/lib/uploadcare/client/rest_group_client.rb +0 -43
  148. data/lib/uploadcare/client/upload_client.rb +0 -46
  149. data/lib/uploadcare/client/uploader_client.rb +0 -128
  150. data/lib/uploadcare/client/webhook_client.rb +0 -49
  151. data/lib/uploadcare/concern/error_handler.rb +0 -54
  152. data/lib/uploadcare/concern/throttle_handler.rb +0 -25
  153. data/lib/uploadcare/concern/upload_error_handler.rb +0 -32
  154. data/lib/uploadcare/entity/addons.rb +0 -14
  155. data/lib/uploadcare/entity/conversion/base_converter.rb +0 -43
  156. data/lib/uploadcare/entity/conversion/document_converter.rb +0 -15
  157. data/lib/uploadcare/entity/conversion/video_converter.rb +0 -15
  158. data/lib/uploadcare/entity/decorator/paginator.rb +0 -79
  159. data/lib/uploadcare/entity/entity.rb +0 -18
  160. data/lib/uploadcare/entity/file.rb +0 -103
  161. data/lib/uploadcare/entity/file_list.rb +0 -32
  162. data/lib/uploadcare/entity/file_metadata.rb +0 -30
  163. data/lib/uploadcare/entity/group.rb +0 -49
  164. data/lib/uploadcare/entity/group_list.rb +0 -24
  165. data/lib/uploadcare/entity/project.rb +0 -13
  166. data/lib/uploadcare/entity/uploader.rb +0 -93
  167. data/lib/uploadcare/entity/webhook.rb +0 -14
  168. data/lib/uploadcare/param/authentication_header.rb +0 -37
  169. data/lib/uploadcare/param/conversion/document/processing_job_url_builder.rb +0 -39
  170. data/lib/uploadcare/param/conversion/video/processing_job_url_builder.rb +0 -64
  171. data/lib/uploadcare/param/param.rb +0 -10
  172. data/lib/uploadcare/param/secure_auth_header.rb +0 -51
  173. data/lib/uploadcare/param/simple_auth_header.rb +0 -14
  174. data/lib/uploadcare/param/upload/signature_generator.rb +0 -24
  175. data/lib/uploadcare/param/upload/upload_params_generator.rb +0 -41
  176. data/lib/uploadcare/param/user_agent.rb +0 -21
  177. data/lib/uploadcare/param/webhook_signature_verifier.rb +0 -23
  178. data/lib/uploadcare/ruby/version.rb +0 -5
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ # REST API endpoint for file metadata operations.
6
+ #
7
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File-metadata
8
+ class Uploadcare::Api::Rest::FileMetadata
9
+ # @return [Uploadcare::Api::Rest] Parent REST client
10
+ attr_reader :rest
11
+
12
+ # @param rest [Uploadcare::Api::Rest] Parent REST client
13
+ def initialize(rest:)
14
+ @rest = rest
15
+ end
16
+
17
+ # Get all metadata for a file.
18
+ #
19
+ # @param uuid [String] File UUID
20
+ # @param request_options [Hash] Request options
21
+ # @return [Uploadcare::Result] Hash of metadata key-value pairs
22
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File-metadata/operation/_fileMetadata
23
+ def index(uuid:, request_options: {})
24
+ encoded_uuid = URI.encode_www_form_component(uuid)
25
+ rest.get(path: "/files/#{encoded_uuid}/metadata/", params: {}, headers: {},
26
+ request_options: request_options)
27
+ end
28
+
29
+ # Get the value of a specific metadata key.
30
+ #
31
+ # @param uuid [String] File UUID
32
+ # @param key [String] Metadata key
33
+ # @param request_options [Hash] Request options
34
+ # @return [Uploadcare::Result] Metadata value
35
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File-metadata/operation/fileMetadata
36
+ def show(uuid:, key:, request_options: {})
37
+ encoded_uuid = URI.encode_www_form_component(uuid)
38
+ encoded_key = URI.encode_www_form_component(key)
39
+ rest.get(path: "/files/#{encoded_uuid}/metadata/#{encoded_key}/", params: {}, headers: {},
40
+ request_options: request_options)
41
+ end
42
+
43
+ # Update or create a metadata key for a file.
44
+ #
45
+ # @param uuid [String] File UUID
46
+ # @param key [String] Metadata key
47
+ # @param value [String] Metadata value
48
+ # @param request_options [Hash] Request options
49
+ # @return [Uploadcare::Result] Updated value
50
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File-metadata/operation/updateFileMetadataKey
51
+ def update(uuid:, key:, value:, request_options: {})
52
+ encoded_uuid = URI.encode_www_form_component(uuid)
53
+ encoded_key = URI.encode_www_form_component(key)
54
+ rest.put(path: "/files/#{encoded_uuid}/metadata/#{encoded_key}/", params: value.to_json, headers: {},
55
+ request_options: request_options)
56
+ end
57
+
58
+ # Delete a metadata key for a file.
59
+ #
60
+ # @param uuid [String] File UUID
61
+ # @param key [String] Metadata key to delete
62
+ # @param request_options [Hash] Request options
63
+ # @return [Uploadcare::Result]
64
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File-metadata/operation/deleteFileMetadata
65
+ def delete(uuid:, key:, request_options: {})
66
+ encoded_uuid = URI.encode_www_form_component(uuid)
67
+ encoded_key = URI.encode_www_form_component(key)
68
+ rest.request(method: :delete, path: "/files/#{encoded_uuid}/metadata/#{encoded_key}/",
69
+ params: {}, headers: {}, request_options: request_options)
70
+ end
71
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ # REST API endpoint for file operations.
4
+ #
5
+ # Provides methods for listing, retrieving, storing, deleting, and copying files.
6
+ #
7
+ # @example
8
+ # rest = Uploadcare::Api::Rest.new(config: config)
9
+ # rest.files.list(params: { limit: 10 })
10
+ # rest.files.info(uuid: "file-uuid")
11
+ #
12
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File
13
+ class Uploadcare::Api::Rest::Files
14
+ # @return [Uploadcare::Api::Rest] Parent REST client
15
+ attr_reader :rest
16
+
17
+ # @param rest [Uploadcare::Api::Rest] Parent REST client
18
+ def initialize(rest:)
19
+ @rest = rest
20
+ end
21
+
22
+ # List files with optional filtering and pagination.
23
+ #
24
+ # @param params [Hash] Query parameters (limit, ordering, etc.)
25
+ # @param request_options [Hash] Request options
26
+ # @return [Uploadcare::Result] Paginated file list
27
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File/operation/filesList
28
+ def list(params: {}, request_options: {})
29
+ rest.get(path: '/files/', params: params, headers: {}, request_options: request_options)
30
+ end
31
+
32
+ # Get file information by UUID.
33
+ #
34
+ # @param uuid [String] The file UUID
35
+ # @param params [Hash] Optional parameters (e.g., include: "appdata")
36
+ # @param request_options [Hash] Request options
37
+ # @return [Uploadcare::Result] File details
38
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File/operation/fileInfo
39
+ def info(uuid:, params: {}, request_options: {})
40
+ encoded_uuid = URI.encode_www_form_component(uuid.to_s)
41
+ rest.get(path: "/files/#{encoded_uuid}/", params: params, headers: {}, request_options: request_options)
42
+ end
43
+
44
+ # Store a file by UUID, making it permanently available.
45
+ #
46
+ # @param uuid [String] The file UUID
47
+ # @param request_options [Hash] Request options
48
+ # @return [Uploadcare::Result] Updated file details
49
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File/operation/filesStore
50
+ def store(uuid:, request_options: {})
51
+ encoded_uuid = URI.encode_www_form_component(uuid.to_s)
52
+ rest.put(path: "/files/#{encoded_uuid}/storage/", params: {}, headers: {}, request_options: request_options)
53
+ end
54
+
55
+ # Delete a file by UUID.
56
+ #
57
+ # @param uuid [String] The file UUID
58
+ # @param request_options [Hash] Request options
59
+ # @return [Uploadcare::Result] Deleted file details
60
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File/operation/deleteFileStorage
61
+ def delete(uuid:, request_options: {})
62
+ encoded_uuid = URI.encode_www_form_component(uuid.to_s)
63
+ rest.request(method: :delete, path: "/files/#{encoded_uuid}/storage/", params: {}, headers: {},
64
+ request_options: request_options)
65
+ end
66
+
67
+ # Batch store files by UUIDs.
68
+ #
69
+ # @param uuids [Array<String>] List of file UUIDs to store
70
+ # @param request_options [Hash] Request options
71
+ # @return [Uploadcare::Result] Hash with 'result' and 'problems' keys
72
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File/operation/filesStoring
73
+ def batch_store(uuids:, request_options: {})
74
+ rest.put(path: '/files/storage/', params: uuids, headers: {}, request_options: request_options)
75
+ end
76
+
77
+ # Batch delete files by UUIDs.
78
+ #
79
+ # @param uuids [Array<String>] List of file UUIDs to delete
80
+ # @param request_options [Hash] Request options
81
+ # @return [Uploadcare::Result] Hash with 'result' and 'problems' keys
82
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File/operation/filesDelete
83
+ def batch_delete(uuids:, request_options: {})
84
+ rest.request(method: :delete, path: '/files/storage/', params: uuids, headers: {},
85
+ request_options: request_options)
86
+ end
87
+
88
+ # Copy a file to local storage.
89
+ #
90
+ # @param source [String] CDN URL or UUID of the file to copy
91
+ # @param options [Hash] Optional parameters (:store, :metadata)
92
+ # @param request_options [Hash] Request options
93
+ # @return [Uploadcare::Result] Hash with 'type' and 'result' keys
94
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/createLocalCopy
95
+ def local_copy(source:, options: {}, request_options: {})
96
+ params = { source: source }.merge(options)
97
+ rest.post(path: '/files/local_copy/', params: params, headers: {}, request_options: request_options)
98
+ end
99
+
100
+ # Copy a file to remote storage.
101
+ #
102
+ # @param source [String] CDN URL or UUID of the file to copy
103
+ # @param target [String] Name of the custom storage
104
+ # @param options [Hash] Optional parameters (:make_public, :pattern)
105
+ # @param request_options [Hash] Request options
106
+ # @return [Uploadcare::Result] Hash with 'type' and 'result' keys
107
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/createRemoteCopy
108
+ def remote_copy(source:, target:, options: {}, request_options: {})
109
+ params = { source: source, target: target }.merge(options)
110
+ rest.post(path: '/files/remote_copy/', params: params, headers: {}, request_options: request_options)
111
+ end
112
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ # REST API endpoint for group operations.
6
+ #
7
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Group
8
+ class Uploadcare::Api::Rest::Groups
9
+ # @return [Uploadcare::Api::Rest] Parent REST client
10
+ attr_reader :rest
11
+
12
+ # @param rest [Uploadcare::Api::Rest] Parent REST client
13
+ def initialize(rest:)
14
+ @rest = rest
15
+ end
16
+
17
+ # List groups with optional filtering and pagination.
18
+ #
19
+ # @param params [Hash] Query parameters (limit, ordering, etc.)
20
+ # @param request_options [Hash] Request options
21
+ # @return [Uploadcare::Result] Paginated group list
22
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Group/operation/groupsList
23
+ def list(params: {}, request_options: {})
24
+ rest.get(path: '/groups/', params: params, headers: {}, request_options: request_options)
25
+ end
26
+
27
+ # Get group information by UUID.
28
+ #
29
+ # @param uuid [String] Group UUID (formatted as UUID~size)
30
+ # @param request_options [Hash] Request options
31
+ # @return [Uploadcare::Result] Group details
32
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Group/operation/groupInfo
33
+ def info(uuid:, request_options: {})
34
+ encoded_uuid = URI::DEFAULT_PARSER.escape(uuid.to_s, /[^A-Za-z0-9\-._~]/)
35
+ rest.get(path: "/groups/#{encoded_uuid}/", params: {}, headers: {}, request_options: request_options)
36
+ end
37
+
38
+ # Delete a group by UUID.
39
+ #
40
+ # @param uuid [String] Group UUID (formatted as UUID~size)
41
+ # @param request_options [Hash] Request options
42
+ # @return [Uploadcare::Result]
43
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Group/operation/deleteGroup
44
+ def delete(uuid:, request_options: {})
45
+ encoded_uuid = URI::DEFAULT_PARSER.escape(uuid.to_s, /[^A-Za-z0-9\-._~]/)
46
+ rest.request(method: :delete, path: "/groups/#{encoded_uuid}/", params: {}, headers: {},
47
+ request_options: request_options)
48
+ end
49
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # REST API endpoint for project information.
4
+ #
5
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Project
6
+ class Uploadcare::Api::Rest::Project
7
+ # @return [Uploadcare::Api::Rest] Parent REST client
8
+ attr_reader :rest
9
+
10
+ # @param rest [Uploadcare::Api::Rest] Parent REST client
11
+ def initialize(rest:)
12
+ @rest = rest
13
+ end
14
+
15
+ # Get current project information.
16
+ #
17
+ # @param request_options [Hash] Request options
18
+ # @return [Uploadcare::Result] Project details (name, pub_key, autostore_enabled, collaborators)
19
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Project
20
+ def show(request_options: {})
21
+ rest.get(path: '/project/', params: {}, headers: {}, request_options: request_options)
22
+ end
23
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # REST API endpoint for video conversion operations.
4
+ #
5
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Video
6
+ class Uploadcare::Api::Rest::VideoConversions
7
+ # @return [Uploadcare::Api::Rest] Parent REST client
8
+ attr_reader :rest
9
+
10
+ # @param rest [Uploadcare::Api::Rest] Parent REST client
11
+ def initialize(rest:)
12
+ @rest = rest
13
+ end
14
+
15
+ # Convert a video to a specified format.
16
+ #
17
+ # @param paths [Array<String>] Conversion paths (e.g., ["uuid/video/-/format/mp4/-/quality/normal/"])
18
+ # @param options [Hash] Optional parameters (:store)
19
+ # @param request_options [Hash] Request options
20
+ # @return [Uploadcare::Result] Conversion details
21
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Video/operation/convertVideo
22
+ def convert(paths:, options: {}, request_options: {})
23
+ params = { paths: paths }
24
+ params[:store] = normalize_bool_param(options[:store]) if options.key?(:store)
25
+ params.merge!(options.except(:store))
26
+ params.compact!
27
+ rest.post(path: '/convert/video/', params: params, headers: {}, request_options: request_options)
28
+ end
29
+
30
+ # Get video conversion job status.
31
+ #
32
+ # @param token [String, Integer] Conversion job token
33
+ # @param request_options [Hash] Request options
34
+ # @return [Uploadcare::Result] Job status and result
35
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Conversion/operation/videoConvertStatus
36
+ def status(token:, request_options: {})
37
+ rest.get(path: "/convert/video/status/#{token}/", params: {}, headers: {},
38
+ request_options: request_options)
39
+ end
40
+
41
+ private
42
+
43
+ def normalize_bool_param(value)
44
+ normalized = value.is_a?(String) ? value.strip.downcase : value
45
+
46
+ case normalized
47
+ when true, 1, '1', 'true' then '1'
48
+ when false, 0, '0', 'false' then '0'
49
+ else value
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ # REST API endpoint for webhook operations.
4
+ #
5
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Webhook
6
+ class Uploadcare::Api::Rest::Webhooks
7
+ # @return [Uploadcare::Api::Rest] Parent REST client
8
+ attr_reader :rest
9
+
10
+ # @param rest [Uploadcare::Api::Rest] Parent REST client
11
+ def initialize(rest:)
12
+ @rest = rest
13
+ end
14
+
15
+ # List all project webhooks.
16
+ #
17
+ # @param request_options [Hash] Request options
18
+ # @return [Uploadcare::Result] Array of webhook hashes
19
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Webhook/operation/webhooksList
20
+ def list(request_options: {})
21
+ rest.get(path: '/webhooks/', params: {}, headers: {}, request_options: request_options)
22
+ end
23
+
24
+ # Create a new webhook.
25
+ #
26
+ # @param options [Hash] Webhook options
27
+ # @option options [String] :target_url Webhook target URL (required)
28
+ # @option options [String] :event Event type (default: "file.uploaded")
29
+ # @option options [Boolean] :is_active Active flag (default: true)
30
+ # @option options [String] :signing_secret Signing secret
31
+ # @option options [String] :version Webhook payload version
32
+ # @param request_options [Hash] Request options
33
+ # @return [Uploadcare::Result] Created webhook attributes
34
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Webhook/operation/webhookCreate
35
+ def create(options: {}, request_options: {})
36
+ payload = {
37
+ target_url: options[:target_url],
38
+ event: options[:event] || 'file.uploaded',
39
+ is_active: options[:is_active].nil? || options[:is_active]
40
+ }
41
+ payload.merge!({ signing_secret: options[:signing_secret] }.compact)
42
+ payload.merge!({ version: options[:version] }.compact)
43
+
44
+ rest.post(path: '/webhooks/', params: payload, headers: {}, request_options: request_options)
45
+ end
46
+
47
+ # Update a webhook.
48
+ #
49
+ # @param id [Integer] Webhook ID
50
+ # @param options [Hash] Webhook options to update
51
+ # @option options [String] :target_url Target URL
52
+ # @option options [String] :event Event type
53
+ # @option options [Boolean] :is_active Active flag
54
+ # @option options [String] :signing_secret Signing secret
55
+ # @option options [String] :version Webhook payload version
56
+ # @param request_options [Hash] Request options
57
+ # @return [Uploadcare::Result] Updated webhook attributes
58
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Webhook/operation/updateWebhook
59
+ def update(id:, options: {}, request_options: {})
60
+ rest.put(path: "/webhooks/#{id}/", params: options, headers: {}, request_options: request_options)
61
+ end
62
+
63
+ # Delete a webhook by target URL.
64
+ #
65
+ # @param target_url [String] Target URL of the webhook to delete
66
+ # @param request_options [Hash] Request options
67
+ # @return [Uploadcare::Result]
68
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Webhook/operation/webhookUnsubscribe
69
+ def delete(target_url:, request_options: {})
70
+ payload = { target_url: target_url }
71
+ rest.request(method: :delete, path: '/webhooks/unsubscribe/', params: payload, headers: {},
72
+ request_options: request_options)
73
+ end
74
+ end
@@ -0,0 +1,254 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ require 'uri'
5
+
6
+ # Base client for the Uploadcare REST API.
7
+ #
8
+ # Provides authenticated HTTP methods (GET, POST, PUT, DELETE) for all REST API
9
+ # endpoints. Includes automatic error handling and throttle retry logic.
10
+ #
11
+ # Endpoint classes are accessed via lazy-loaded accessors:
12
+ # rest = Uploadcare::Api::Rest.new(config: config)
13
+ # rest.files.list
14
+ # rest.groups.info(uuid: "...")
15
+ #
16
+ # @see https://uploadcare.com/api-refs/rest-api/v0.7.0/
17
+ class Uploadcare::Api::Rest
18
+ include Uploadcare::Internal::ErrorHandler
19
+ include Uploadcare::Internal::ThrottleHandler
20
+
21
+ # Verb name used when deciding whether params belong in the query string.
22
+ HTTP_GET = 'GET'
23
+
24
+ # @return [Uploadcare::Configuration]
25
+ attr_reader :config
26
+
27
+ # @return [Faraday::Connection]
28
+ attr_reader :connection
29
+
30
+ # @return [Uploadcare::Internal::Authenticator]
31
+ attr_reader :authenticator
32
+
33
+ # Initialize a new REST API client.
34
+ #
35
+ # @param config [Uploadcare::Configuration] Configuration object (defaults to global config)
36
+ def initialize(config: Uploadcare.configuration)
37
+ @config = config
38
+ @memo_mutex = Mutex.new
39
+ @connection = Faraday.new(url: config.rest_api_root) do |conn|
40
+ conn.request :json
41
+ conn.response :json, content_type: /\bjson$/
42
+ conn.response :raise_error
43
+ end
44
+ @authenticator = Uploadcare::Internal::Authenticator.new(config: config)
45
+ end
46
+
47
+ # --- Endpoint accessors ---
48
+
49
+ # @return [Uploadcare::Api::Rest::Files] File operations endpoint
50
+ def files
51
+ memoized(:@files) { Uploadcare::Api::Rest::Files.new(rest: self) }
52
+ end
53
+
54
+ # @return [Uploadcare::Api::Rest::Groups] Group operations endpoint
55
+ def groups
56
+ memoized(:@groups) { Uploadcare::Api::Rest::Groups.new(rest: self) }
57
+ end
58
+
59
+ # @return [Uploadcare::Api::Rest::Project] Project information endpoint
60
+ def project
61
+ memoized(:@project) { Uploadcare::Api::Rest::Project.new(rest: self) }
62
+ end
63
+
64
+ # @return [Uploadcare::Api::Rest::Webhooks] Webhook operations endpoint
65
+ def webhooks
66
+ memoized(:@webhooks) { Uploadcare::Api::Rest::Webhooks.new(rest: self) }
67
+ end
68
+
69
+ # @return [Uploadcare::Api::Rest::FileMetadata] File metadata operations endpoint
70
+ def file_metadata
71
+ memoized(:@file_metadata) { Uploadcare::Api::Rest::FileMetadata.new(rest: self) }
72
+ end
73
+
74
+ # @return [Uploadcare::Api::Rest::Addons] Add-on operations endpoint
75
+ def addons
76
+ memoized(:@addons) { Uploadcare::Api::Rest::Addons.new(rest: self) }
77
+ end
78
+
79
+ # @return [Uploadcare::Api::Rest::DocumentConversions] Document conversion endpoint
80
+ def document_conversions
81
+ memoized(:@document_conversions) { Uploadcare::Api::Rest::DocumentConversions.new(rest: self) }
82
+ end
83
+
84
+ # @return [Uploadcare::Api::Rest::VideoConversions] Video conversion endpoint
85
+ def video_conversions
86
+ memoized(:@video_conversions) { Uploadcare::Api::Rest::VideoConversions.new(rest: self) }
87
+ end
88
+
89
+ # --- HTTP methods ---
90
+
91
+ # Make an HTTP request to the REST API.
92
+ #
93
+ # @param method [Symbol] HTTP method (:get, :post, :put, :delete)
94
+ # @param path [String] API endpoint path
95
+ # @param params [Hash, Array, String] Request parameters
96
+ # @param headers [Hash] Additional request headers
97
+ # @param request_options [Hash] Request options (timeout, etc.)
98
+ # @return [Hash, Array, nil] Parsed JSON response body
99
+ # @raise [Uploadcare::Exception::RequestError] on API errors
100
+ def make_request(method:, path:, params: {}, headers: {}, request_options: {})
101
+ handle_throttling(max_attempts: request_options[:max_throttle_attempts]) do
102
+ response = connection.public_send(method, path) do |req|
103
+ prepare_request(req, method, path, params, headers, request_options)
104
+ end
105
+ response.body
106
+ end
107
+ rescue Faraday::Error => e
108
+ handle_error(e)
109
+ end
110
+
111
+ # Make a POST request wrapped in a Result.
112
+ #
113
+ # @param path [String] API endpoint path
114
+ # @param params [Hash] Request body parameters
115
+ # @param headers [Hash] Additional request headers
116
+ # @param request_options [Hash] Request options
117
+ # @return [Uploadcare::Result]
118
+ def post(path:, params: {}, headers: {}, request_options: {})
119
+ request(method: :post, path: path, params: params, headers: headers, request_options: request_options)
120
+ end
121
+
122
+ # Make a GET request wrapped in a Result.
123
+ #
124
+ # @param path [String] API endpoint path
125
+ # @param params [Hash] Query parameters
126
+ # @param headers [Hash] Additional request headers
127
+ # @param request_options [Hash] Request options
128
+ # @return [Uploadcare::Result]
129
+ def get(path:, params: {}, headers: {}, request_options: {})
130
+ request(method: :get, path: path, params: params, headers: headers, request_options: request_options)
131
+ end
132
+
133
+ # Make a PUT request wrapped in a Result.
134
+ #
135
+ # @param path [String] API endpoint path
136
+ # @param params [Hash] Request body parameters
137
+ # @param headers [Hash] Additional request headers
138
+ # @param request_options [Hash] Request options
139
+ # @return [Uploadcare::Result]
140
+ def put(path:, params: {}, headers: {}, request_options: {})
141
+ request(method: :put, path: path, params: params, headers: headers, request_options: request_options)
142
+ end
143
+
144
+ # Make a DELETE request wrapped in a Result.
145
+ #
146
+ # @param path [String] API endpoint path
147
+ # @param params [Hash] Request body parameters
148
+ # @param headers [Hash] Additional request headers
149
+ # @param request_options [Hash] Request options
150
+ # @return [Uploadcare::Result]
151
+ def delete(path:, params: {}, headers: {}, request_options: {})
152
+ request(method: :delete, path: path, params: params, headers: headers, request_options: request_options)
153
+ end
154
+
155
+ # Wraps a request in a Result object.
156
+ #
157
+ # @param method [Symbol] HTTP method
158
+ # @param path [String] API path
159
+ # @param params [Hash] Request parameters
160
+ # @param headers [Hash] Request headers
161
+ # @param request_options [Hash] Request options
162
+ # @return [Uploadcare::Result]
163
+ def request(method:, path:, params: {}, headers: {}, request_options: {})
164
+ Uploadcare::Result.capture do
165
+ make_request(method: method, path: path, params: params, headers: headers, request_options: request_options)
166
+ end
167
+ end
168
+
169
+ private
170
+
171
+ def prepare_request(req, method, path, params, headers, request_options)
172
+ upcase_method_name = method.to_s.upcase
173
+ uri = build_request_uri(path, params, upcase_method_name)
174
+
175
+ prepare_headers(req, upcase_method_name, uri, params, headers)
176
+ prepare_body_or_params(req, upcase_method_name, params)
177
+ apply_request_options(req, request_options)
178
+ end
179
+
180
+ def build_request_uri(path, params, method)
181
+ if method == HTTP_GET && !params.nil? && params.is_a?(Hash) && !params.empty?
182
+ build_uri(path, params)
183
+ else
184
+ path
185
+ end
186
+ end
187
+
188
+ def prepare_headers(req, method, uri, params, headers)
189
+ body_content = body_content_for_signature(method, params)
190
+ content_type = extract_content_type(headers) || authenticator.default_headers['Content-Type']
191
+ auth_headers = authenticator.headers(method, uri, body_content, content_type)
192
+ normalized_headers = normalize_content_type_header(headers, content_type)
193
+ req.headers.merge!(auth_headers)
194
+ req.headers.merge!(normalized_headers)
195
+ end
196
+
197
+ def body_content_for_signature(method, params)
198
+ return '' if method == HTTP_GET
199
+ return '' if params.nil? || (params.respond_to?(:empty?) && params.empty?)
200
+ return params if params.is_a?(String)
201
+
202
+ params.to_json
203
+ end
204
+
205
+ def prepare_body_or_params(req, method, params)
206
+ if method == HTTP_GET
207
+ req.params.update(params) unless params.nil? || params.empty?
208
+ else
209
+ return if params.nil? || params.empty?
210
+
211
+ req.body = params
212
+ end
213
+ end
214
+
215
+ def apply_request_options(req, request_options)
216
+ return if request_options.nil? || request_options.empty?
217
+
218
+ req.options.timeout = request_options[:timeout] if request_options[:timeout]
219
+ req.options.open_timeout = request_options[:open_timeout] if request_options[:open_timeout]
220
+ end
221
+
222
+ def extract_content_type(headers)
223
+ headers['Content-Type'] || headers['content-type'] || headers[:content_type] || headers[:'Content-Type']
224
+ end
225
+
226
+ def normalize_content_type_header(headers, content_type)
227
+ normalized_headers = headers.dup
228
+ normalized_headers.delete('content-type')
229
+ normalized_headers.delete(:content_type)
230
+ normalized_headers.delete(:'Content-Type')
231
+ normalized_headers['Content-Type'] = content_type if content_type
232
+ normalized_headers
233
+ end
234
+
235
+ def build_uri(path, query_params = {})
236
+ if query_params.empty?
237
+ path
238
+ else
239
+ separator = path.include?('?') ? '&' : '?'
240
+ params_encoder = connection.options.params_encoder || Faraday::Utils.default_params_encoder
241
+ encoded_query = params_encoder.encode(query_params)
242
+ "#{path}#{separator}#{encoded_query}"
243
+ end
244
+ end
245
+
246
+ def memoized(ivar)
247
+ cached = instance_variable_get(ivar)
248
+ return cached if cached
249
+
250
+ @memo_mutex.synchronize do
251
+ instance_variable_get(ivar) || instance_variable_set(ivar, yield)
252
+ end
253
+ end
254
+ end