imagekitio 3.0.0 → 4.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 (483) hide show
  1. checksums.yaml +4 -4
  2. data/.ignore +2 -0
  3. data/CHANGELOG.md +116 -0
  4. data/README.md +538 -679
  5. data/SECURITY.md +27 -0
  6. data/lib/imagekitio/client.rb +122 -195
  7. data/lib/imagekitio/errors.rb +226 -2
  8. data/lib/imagekitio/file_part.rb +58 -0
  9. data/lib/imagekitio/helpers/crypto_utils.rb +25 -0
  10. data/lib/imagekitio/helpers/helper.rb +689 -0
  11. data/lib/imagekitio/helpers/transformation_utils.rb +164 -0
  12. data/lib/imagekitio/helpers/uuid_utils.rb +18 -0
  13. data/lib/imagekitio/internal/transport/base_client.rb +567 -0
  14. data/lib/imagekitio/internal/transport/pooled_net_requester.rb +217 -0
  15. data/lib/imagekitio/internal/type/array_of.rb +168 -0
  16. data/lib/imagekitio/internal/type/base_model.rb +530 -0
  17. data/lib/imagekitio/internal/type/base_page.rb +55 -0
  18. data/lib/imagekitio/internal/type/boolean.rb +77 -0
  19. data/lib/imagekitio/internal/type/converter.rb +327 -0
  20. data/lib/imagekitio/internal/type/enum.rb +156 -0
  21. data/lib/imagekitio/internal/type/file_input.rb +111 -0
  22. data/lib/imagekitio/internal/type/hash_of.rb +188 -0
  23. data/lib/imagekitio/internal/type/request_parameters.rb +42 -0
  24. data/lib/imagekitio/internal/type/union.rb +250 -0
  25. data/lib/imagekitio/internal/type/unknown.rb +81 -0
  26. data/lib/imagekitio/internal/util.rb +915 -0
  27. data/lib/imagekitio/internal.rb +20 -0
  28. data/lib/imagekitio/models/accounts/origin_create_params.rb +24 -0
  29. data/lib/imagekitio/models/accounts/origin_delete_params.rb +16 -0
  30. data/lib/imagekitio/models/accounts/origin_get_params.rb +16 -0
  31. data/lib/imagekitio/models/accounts/origin_list_params.rb +16 -0
  32. data/lib/imagekitio/models/accounts/origin_list_response.rb +11 -0
  33. data/lib/imagekitio/models/accounts/origin_request.rb +547 -0
  34. data/lib/imagekitio/models/accounts/origin_response.rb +568 -0
  35. data/lib/imagekitio/models/accounts/origin_update_params.rb +24 -0
  36. data/lib/imagekitio/models/accounts/url_endpoint_create_params.rb +16 -0
  37. data/lib/imagekitio/models/accounts/url_endpoint_delete_params.rb +16 -0
  38. data/lib/imagekitio/models/accounts/url_endpoint_get_params.rb +16 -0
  39. data/lib/imagekitio/models/accounts/url_endpoint_list_params.rb +16 -0
  40. data/lib/imagekitio/models/accounts/url_endpoint_list_response.rb +11 -0
  41. data/lib/imagekitio/models/accounts/url_endpoint_request.rb +110 -0
  42. data/lib/imagekitio/models/accounts/url_endpoint_response.rb +123 -0
  43. data/lib/imagekitio/models/accounts/url_endpoint_update_params.rb +16 -0
  44. data/lib/imagekitio/models/accounts/usage_get_params.rb +37 -0
  45. data/lib/imagekitio/models/accounts/usage_get_response.rb +51 -0
  46. data/lib/imagekitio/models/asset_list_params.rb +158 -0
  47. data/lib/imagekitio/models/asset_list_response.rb +24 -0
  48. data/lib/imagekitio/models/base_overlay.rb +21 -0
  49. data/lib/imagekitio/models/base_webhook_event.rb +24 -0
  50. data/lib/imagekitio/models/beta/v2/file_upload_params.rb +510 -0
  51. data/lib/imagekitio/models/beta/v2/file_upload_response.rb +618 -0
  52. data/lib/imagekitio/models/cache/invalidation_create_params.rb +27 -0
  53. data/lib/imagekitio/models/cache/invalidation_create_response.rb +23 -0
  54. data/lib/imagekitio/models/cache/invalidation_get_params.rb +16 -0
  55. data/lib/imagekitio/models/cache/invalidation_get_response.rb +35 -0
  56. data/lib/imagekitio/models/custom_metadata_field.rb +243 -0
  57. data/lib/imagekitio/models/custom_metadata_field_create_params.rb +238 -0
  58. data/lib/imagekitio/models/custom_metadata_field_delete_params.rb +14 -0
  59. data/lib/imagekitio/models/custom_metadata_field_delete_response.rb +10 -0
  60. data/lib/imagekitio/models/custom_metadata_field_list_params.rb +36 -0
  61. data/lib/imagekitio/models/custom_metadata_field_list_response.rb +9 -0
  62. data/lib/imagekitio/models/custom_metadata_field_update_params.rb +212 -0
  63. data/lib/imagekitio/models/extensions.rb +136 -0
  64. data/lib/imagekitio/models/file.rb +497 -0
  65. data/lib/imagekitio/models/file_copy_params.rb +43 -0
  66. data/lib/imagekitio/models/file_copy_response.rb +10 -0
  67. data/lib/imagekitio/models/file_delete_params.rb +14 -0
  68. data/lib/imagekitio/models/file_get_params.rb +14 -0
  69. data/lib/imagekitio/models/file_move_params.rb +33 -0
  70. data/lib/imagekitio/models/file_move_response.rb +10 -0
  71. data/lib/imagekitio/models/file_rename_params.rb +61 -0
  72. data/lib/imagekitio/models/file_rename_response.rb +21 -0
  73. data/lib/imagekitio/models/file_update_params.rb +22 -0
  74. data/lib/imagekitio/models/file_update_response.rb +104 -0
  75. data/lib/imagekitio/models/file_upload_params.rb +540 -0
  76. data/lib/imagekitio/models/file_upload_response.rb +611 -0
  77. data/lib/imagekitio/models/files/bulk_add_tags_params.rb +35 -0
  78. data/lib/imagekitio/models/files/bulk_add_tags_response.rb +24 -0
  79. data/lib/imagekitio/models/files/bulk_delete_params.rb +27 -0
  80. data/lib/imagekitio/models/files/bulk_delete_response.rb +24 -0
  81. data/lib/imagekitio/models/files/bulk_remove_ai_tags_params.rb +35 -0
  82. data/lib/imagekitio/models/files/bulk_remove_ai_tags_response.rb +24 -0
  83. data/lib/imagekitio/models/files/bulk_remove_tags_params.rb +35 -0
  84. data/lib/imagekitio/models/files/bulk_remove_tags_response.rb +24 -0
  85. data/lib/imagekitio/models/files/metadata_get_from_url_params.rb +28 -0
  86. data/lib/imagekitio/models/files/metadata_get_params.rb +16 -0
  87. data/lib/imagekitio/models/files/version_delete_params.rb +22 -0
  88. data/lib/imagekitio/models/files/version_delete_response.rb +12 -0
  89. data/lib/imagekitio/models/files/version_get_params.rb +22 -0
  90. data/lib/imagekitio/models/files/version_list_params.rb +16 -0
  91. data/lib/imagekitio/models/files/version_list_response.rb +10 -0
  92. data/lib/imagekitio/models/files/version_restore_params.rb +22 -0
  93. data/lib/imagekitio/models/folder.rb +76 -0
  94. data/lib/imagekitio/models/folder_copy_params.rb +44 -0
  95. data/lib/imagekitio/models/folder_copy_response.rb +23 -0
  96. data/lib/imagekitio/models/folder_create_params.rb +43 -0
  97. data/lib/imagekitio/models/folder_create_response.rb +10 -0
  98. data/lib/imagekitio/models/folder_delete_params.rb +25 -0
  99. data/lib/imagekitio/models/folder_delete_response.rb +10 -0
  100. data/lib/imagekitio/models/folder_move_params.rb +34 -0
  101. data/lib/imagekitio/models/folder_move_response.rb +23 -0
  102. data/lib/imagekitio/models/folder_rename_params.rb +59 -0
  103. data/lib/imagekitio/models/folder_rename_response.rb +23 -0
  104. data/lib/imagekitio/models/folders/job_get_params.rb +16 -0
  105. data/lib/imagekitio/models/folders/job_get_response.rb +74 -0
  106. data/lib/imagekitio/models/get_image_attributes_options.rb +68 -0
  107. data/lib/imagekitio/models/image_overlay.rb +66 -0
  108. data/lib/imagekitio/models/metadata.rb +483 -0
  109. data/lib/imagekitio/models/overlay.rb +28 -0
  110. data/lib/imagekitio/models/overlay_position.rb +101 -0
  111. data/lib/imagekitio/models/overlay_timing.rb +97 -0
  112. data/lib/imagekitio/models/responsive_image_attributes.rb +48 -0
  113. data/lib/imagekitio/models/solid_color_overlay.rb +42 -0
  114. data/lib/imagekitio/models/solid_color_overlay_transformation.rb +135 -0
  115. data/lib/imagekitio/models/src_options.rb +96 -0
  116. data/lib/imagekitio/models/streaming_resolution.rb +22 -0
  117. data/lib/imagekitio/models/subtitle_overlay.rb +64 -0
  118. data/lib/imagekitio/models/subtitle_overlay_transformation.rb +113 -0
  119. data/lib/imagekitio/models/text_overlay.rb +65 -0
  120. data/lib/imagekitio/models/text_overlay_transformation.rb +267 -0
  121. data/lib/imagekitio/models/transformation.rb +1100 -0
  122. data/lib/imagekitio/models/transformation_position.rb +19 -0
  123. data/lib/imagekitio/models/unsafe_unwrap_webhook_event.rb +36 -0
  124. data/lib/imagekitio/models/unwrap_webhook_event.rb +36 -0
  125. data/lib/imagekitio/models/update_file_request.rb +164 -0
  126. data/lib/imagekitio/models/upload_post_transform_error_event.rb +180 -0
  127. data/lib/imagekitio/models/upload_post_transform_success_event.rb +143 -0
  128. data/lib/imagekitio/models/upload_pre_transform_error_event.rb +108 -0
  129. data/lib/imagekitio/models/upload_pre_transform_success_event.rb +690 -0
  130. data/lib/imagekitio/models/video_overlay.rb +64 -0
  131. data/lib/imagekitio/models/video_transformation_accepted_event.rb +279 -0
  132. data/lib/imagekitio/models/video_transformation_error_event.rb +326 -0
  133. data/lib/imagekitio/models/video_transformation_ready_event.rb +379 -0
  134. data/lib/imagekitio/models/webhook_unsafe_unwrap_params.rb +14 -0
  135. data/lib/imagekitio/models/webhook_unwrap_params.rb +14 -0
  136. data/lib/imagekitio/models.rb +160 -0
  137. data/lib/imagekitio/request_options.rb +77 -0
  138. data/lib/imagekitio/resources/accounts/origins.rb +145 -0
  139. data/lib/imagekitio/resources/accounts/url_endpoints.rb +151 -0
  140. data/lib/imagekitio/resources/accounts/usage.rb +46 -0
  141. data/lib/imagekitio/resources/accounts.rb +26 -0
  142. data/lib/imagekitio/resources/assets.rb +54 -0
  143. data/lib/imagekitio/resources/beta/v2/files.rb +110 -0
  144. data/lib/imagekitio/resources/beta/v2.rb +20 -0
  145. data/lib/imagekitio/resources/beta.rb +18 -0
  146. data/lib/imagekitio/resources/cache/invalidation.rb +66 -0
  147. data/lib/imagekitio/resources/cache.rb +18 -0
  148. data/lib/imagekitio/resources/custom_metadata_fields.rb +133 -0
  149. data/lib/imagekitio/resources/files/bulk.rb +131 -0
  150. data/lib/imagekitio/resources/files/metadata.rb +69 -0
  151. data/lib/imagekitio/resources/files/versions.rb +132 -0
  152. data/lib/imagekitio/resources/files.rb +305 -0
  153. data/lib/imagekitio/resources/folders/job.rb +39 -0
  154. data/lib/imagekitio/resources/folders.rb +166 -0
  155. data/lib/imagekitio/resources/webhooks.rb +30 -0
  156. data/lib/imagekitio/version.rb +5 -0
  157. data/lib/imagekitio.rb +181 -13
  158. data/manifest.yaml +15 -0
  159. data/rbi/imagekitio/client.rbi +92 -0
  160. data/rbi/imagekitio/errors.rbi +205 -0
  161. data/rbi/imagekitio/file_part.rbi +37 -0
  162. data/rbi/imagekitio/helpers/helper.rbi +41 -0
  163. data/rbi/imagekitio/internal/transport/base_client.rbi +295 -0
  164. data/rbi/imagekitio/internal/transport/pooled_net_requester.rbi +80 -0
  165. data/rbi/imagekitio/internal/type/array_of.rbi +104 -0
  166. data/rbi/imagekitio/internal/type/base_model.rbi +304 -0
  167. data/rbi/imagekitio/internal/type/base_page.rbi +42 -0
  168. data/rbi/imagekitio/internal/type/boolean.rbi +58 -0
  169. data/rbi/imagekitio/internal/type/converter.rbi +216 -0
  170. data/rbi/imagekitio/internal/type/enum.rbi +82 -0
  171. data/rbi/imagekitio/internal/type/file_input.rbi +59 -0
  172. data/rbi/imagekitio/internal/type/hash_of.rbi +104 -0
  173. data/rbi/imagekitio/internal/type/request_parameters.rbi +29 -0
  174. data/rbi/imagekitio/internal/type/union.rbi +128 -0
  175. data/rbi/imagekitio/internal/type/unknown.rbi +58 -0
  176. data/rbi/imagekitio/internal/util.rbi +487 -0
  177. data/rbi/imagekitio/internal.rbi +18 -0
  178. data/rbi/imagekitio/models/accounts/origin_create_params.rbi +81 -0
  179. data/rbi/imagekitio/models/accounts/origin_delete_params.rbi +34 -0
  180. data/rbi/imagekitio/models/accounts/origin_get_params.rbi +34 -0
  181. data/rbi/imagekitio/models/accounts/origin_list_params.rbi +34 -0
  182. data/rbi/imagekitio/models/accounts/origin_list_response.rbi +15 -0
  183. data/rbi/imagekitio/models/accounts/origin_request.rbi +775 -0
  184. data/rbi/imagekitio/models/accounts/origin_response.rbi +718 -0
  185. data/rbi/imagekitio/models/accounts/origin_update_params.rbi +81 -0
  186. data/rbi/imagekitio/models/accounts/url_endpoint_create_params.rbi +34 -0
  187. data/rbi/imagekitio/models/accounts/url_endpoint_delete_params.rbi +34 -0
  188. data/rbi/imagekitio/models/accounts/url_endpoint_get_params.rbi +34 -0
  189. data/rbi/imagekitio/models/accounts/url_endpoint_list_params.rbi +34 -0
  190. data/rbi/imagekitio/models/accounts/url_endpoint_list_response.rbi +15 -0
  191. data/rbi/imagekitio/models/accounts/url_endpoint_request.rbi +218 -0
  192. data/rbi/imagekitio/models/accounts/url_endpoint_response.rbi +213 -0
  193. data/rbi/imagekitio/models/accounts/url_endpoint_update_params.rbi +34 -0
  194. data/rbi/imagekitio/models/accounts/usage_get_params.rbi +60 -0
  195. data/rbi/imagekitio/models/accounts/usage_get_response.rbi +89 -0
  196. data/rbi/imagekitio/models/asset_list_params.rbi +281 -0
  197. data/rbi/imagekitio/models/asset_list_response.rbi +28 -0
  198. data/rbi/imagekitio/models/base_overlay.rbi +44 -0
  199. data/rbi/imagekitio/models/base_webhook_event.rbi +33 -0
  200. data/rbi/imagekitio/models/beta/v2/file_upload_params.rbi +861 -0
  201. data/rbi/imagekitio/models/beta/v2/file_upload_response.rbi +1197 -0
  202. data/rbi/imagekitio/models/cache/invalidation_create_params.rbi +45 -0
  203. data/rbi/imagekitio/models/cache/invalidation_create_response.rbi +37 -0
  204. data/rbi/imagekitio/models/cache/invalidation_get_params.rbi +34 -0
  205. data/rbi/imagekitio/models/cache/invalidation_get_response.rbi +93 -0
  206. data/rbi/imagekitio/models/custom_metadata_field.rbi +422 -0
  207. data/rbi/imagekitio/models/custom_metadata_field_create_params.rbi +443 -0
  208. data/rbi/imagekitio/models/custom_metadata_field_delete_params.rbi +30 -0
  209. data/rbi/imagekitio/models/custom_metadata_field_delete_response.rbi +23 -0
  210. data/rbi/imagekitio/models/custom_metadata_field_list_params.rbi +66 -0
  211. data/rbi/imagekitio/models/custom_metadata_field_list_response.rbi +11 -0
  212. data/rbi/imagekitio/models/custom_metadata_field_update_params.rbi +376 -0
  213. data/rbi/imagekitio/models/extensions.rbi +274 -0
  214. data/rbi/imagekitio/models/file.rbi +789 -0
  215. data/rbi/imagekitio/models/file_copy_params.rbi +66 -0
  216. data/rbi/imagekitio/models/file_copy_response.rbi +23 -0
  217. data/rbi/imagekitio/models/file_delete_params.rbi +27 -0
  218. data/rbi/imagekitio/models/file_get_params.rbi +27 -0
  219. data/rbi/imagekitio/models/file_move_params.rbi +51 -0
  220. data/rbi/imagekitio/models/file_move_response.rbi +23 -0
  221. data/rbi/imagekitio/models/file_rename_params.rbi +102 -0
  222. data/rbi/imagekitio/models/file_rename_response.rbi +35 -0
  223. data/rbi/imagekitio/models/file_update_params.rbi +58 -0
  224. data/rbi/imagekitio/models/file_update_response.rbi +322 -0
  225. data/rbi/imagekitio/models/file_upload_params.rbi +897 -0
  226. data/rbi/imagekitio/models/file_upload_response.rbi +1176 -0
  227. data/rbi/imagekitio/models/files/bulk_add_tags_params.rbi +56 -0
  228. data/rbi/imagekitio/models/files/bulk_add_tags_response.rbi +41 -0
  229. data/rbi/imagekitio/models/files/bulk_delete_params.rbi +48 -0
  230. data/rbi/imagekitio/models/files/bulk_delete_response.rbi +41 -0
  231. data/rbi/imagekitio/models/files/bulk_remove_ai_tags_params.rbi +56 -0
  232. data/rbi/imagekitio/models/files/bulk_remove_ai_tags_response.rbi +41 -0
  233. data/rbi/imagekitio/models/files/bulk_remove_tags_params.rbi +56 -0
  234. data/rbi/imagekitio/models/files/bulk_remove_tags_response.rbi +41 -0
  235. data/rbi/imagekitio/models/files/metadata_get_from_url_params.rbi +47 -0
  236. data/rbi/imagekitio/models/files/metadata_get_params.rbi +34 -0
  237. data/rbi/imagekitio/models/files/version_delete_params.rbi +40 -0
  238. data/rbi/imagekitio/models/files/version_delete_response.rbi +25 -0
  239. data/rbi/imagekitio/models/files/version_get_params.rbi +40 -0
  240. data/rbi/imagekitio/models/files/version_list_params.rbi +34 -0
  241. data/rbi/imagekitio/models/files/version_list_response.rbi +13 -0
  242. data/rbi/imagekitio/models/files/version_restore_params.rbi +40 -0
  243. data/rbi/imagekitio/models/folder.rbi +121 -0
  244. data/rbi/imagekitio/models/folder_copy_params.rbi +68 -0
  245. data/rbi/imagekitio/models/folder_copy_response.rbi +33 -0
  246. data/rbi/imagekitio/models/folder_create_params.rbi +71 -0
  247. data/rbi/imagekitio/models/folder_create_response.rbi +23 -0
  248. data/rbi/imagekitio/models/folder_delete_params.rbi +40 -0
  249. data/rbi/imagekitio/models/folder_delete_response.rbi +23 -0
  250. data/rbi/imagekitio/models/folder_move_params.rbi +53 -0
  251. data/rbi/imagekitio/models/folder_move_response.rbi +33 -0
  252. data/rbi/imagekitio/models/folder_rename_params.rbi +98 -0
  253. data/rbi/imagekitio/models/folder_rename_response.rbi +33 -0
  254. data/rbi/imagekitio/models/folders/job_get_params.rbi +34 -0
  255. data/rbi/imagekitio/models/folders/job_get_response.rbi +173 -0
  256. data/rbi/imagekitio/models/get_image_attributes_options.rbi +121 -0
  257. data/rbi/imagekitio/models/image_overlay.rbi +109 -0
  258. data/rbi/imagekitio/models/metadata.rbi +813 -0
  259. data/rbi/imagekitio/models/overlay.rbi +28 -0
  260. data/rbi/imagekitio/models/overlay_position.rbi +148 -0
  261. data/rbi/imagekitio/models/overlay_timing.rbi +135 -0
  262. data/rbi/imagekitio/models/responsive_image_attributes.rbi +74 -0
  263. data/rbi/imagekitio/models/solid_color_overlay.rbi +79 -0
  264. data/rbi/imagekitio/models/solid_color_overlay_transformation.rbi +218 -0
  265. data/rbi/imagekitio/models/src_options.rbi +159 -0
  266. data/rbi/imagekitio/models/streaming_resolution.rbi +38 -0
  267. data/rbi/imagekitio/models/subtitle_overlay.rbi +114 -0
  268. data/rbi/imagekitio/models/subtitle_overlay_transformation.rbi +215 -0
  269. data/rbi/imagekitio/models/text_overlay.rbi +110 -0
  270. data/rbi/imagekitio/models/text_overlay_transformation.rbi +451 -0
  271. data/rbi/imagekitio/models/transformation.rbi +1646 -0
  272. data/rbi/imagekitio/models/transformation_position.rbi +28 -0
  273. data/rbi/imagekitio/models/unsafe_unwrap_webhook_event.rbi +33 -0
  274. data/rbi/imagekitio/models/unwrap_webhook_event.rbi +31 -0
  275. data/rbi/imagekitio/models/update_file_request.rbi +316 -0
  276. data/rbi/imagekitio/models/upload_post_transform_error_event.rbi +434 -0
  277. data/rbi/imagekitio/models/upload_post_transform_success_event.rbi +327 -0
  278. data/rbi/imagekitio/models/upload_pre_transform_error_event.rbi +244 -0
  279. data/rbi/imagekitio/models/upload_pre_transform_success_event.rbi +1300 -0
  280. data/rbi/imagekitio/models/video_overlay.rbi +105 -0
  281. data/rbi/imagekitio/models/video_transformation_accepted_event.rbi +659 -0
  282. data/rbi/imagekitio/models/video_transformation_error_event.rbi +772 -0
  283. data/rbi/imagekitio/models/video_transformation_ready_event.rbi +864 -0
  284. data/rbi/imagekitio/models/webhook_unsafe_unwrap_params.rbi +30 -0
  285. data/rbi/imagekitio/models/webhook_unwrap_params.rbi +27 -0
  286. data/rbi/imagekitio/models.rbi +135 -0
  287. data/rbi/imagekitio/request_options.rbi +59 -0
  288. data/rbi/imagekitio/resources/accounts/origins.rbi +91 -0
  289. data/rbi/imagekitio/resources/accounts/url_endpoints.rbi +129 -0
  290. data/rbi/imagekitio/resources/accounts/usage.rbi +36 -0
  291. data/rbi/imagekitio/resources/accounts.rbi +21 -0
  292. data/rbi/imagekitio/resources/assets.rbi +74 -0
  293. data/rbi/imagekitio/resources/beta/v2/files.rbi +193 -0
  294. data/rbi/imagekitio/resources/beta/v2.rbi +17 -0
  295. data/rbi/imagekitio/resources/beta.rbi +15 -0
  296. data/rbi/imagekitio/resources/cache/invalidation.rbi +44 -0
  297. data/rbi/imagekitio/resources/cache.rbi +15 -0
  298. data/rbi/imagekitio/resources/custom_metadata_fields.rbi +106 -0
  299. data/rbi/imagekitio/resources/files/bulk.rbi +88 -0
  300. data/rbi/imagekitio/resources/files/metadata.rbi +49 -0
  301. data/rbi/imagekitio/resources/files/versions.rbi +89 -0
  302. data/rbi/imagekitio/resources/files.rbi +364 -0
  303. data/rbi/imagekitio/resources/folders/job.rbi +29 -0
  304. data/rbi/imagekitio/resources/folders.rbi +146 -0
  305. data/rbi/imagekitio/resources/webhooks.rbi +50 -0
  306. data/rbi/imagekitio/version.rbi +5 -0
  307. data/sig/imagekitio/client.rbs +47 -0
  308. data/sig/imagekitio/errors.rbs +117 -0
  309. data/sig/imagekitio/file_part.rbs +21 -0
  310. data/sig/imagekitio/helpers/helper.rbs +24 -0
  311. data/sig/imagekitio/internal/transport/base_client.rbs +131 -0
  312. data/sig/imagekitio/internal/transport/pooled_net_requester.rbs +45 -0
  313. data/sig/imagekitio/internal/type/array_of.rbs +48 -0
  314. data/sig/imagekitio/internal/type/base_model.rbs +102 -0
  315. data/sig/imagekitio/internal/type/base_page.rbs +24 -0
  316. data/sig/imagekitio/internal/type/boolean.rbs +26 -0
  317. data/sig/imagekitio/internal/type/converter.rbs +79 -0
  318. data/sig/imagekitio/internal/type/enum.rbs +32 -0
  319. data/sig/imagekitio/internal/type/file_input.rbs +25 -0
  320. data/sig/imagekitio/internal/type/hash_of.rbs +48 -0
  321. data/sig/imagekitio/internal/type/request_parameters.rbs +19 -0
  322. data/sig/imagekitio/internal/type/union.rbs +52 -0
  323. data/sig/imagekitio/internal/type/unknown.rbs +26 -0
  324. data/sig/imagekitio/internal/util.rbs +185 -0
  325. data/sig/imagekitio/internal.rbs +9 -0
  326. data/sig/imagekitio/models/accounts/origin_create_params.rbs +30 -0
  327. data/sig/imagekitio/models/accounts/origin_delete_params.rbs +17 -0
  328. data/sig/imagekitio/models/accounts/origin_get_params.rbs +17 -0
  329. data/sig/imagekitio/models/accounts/origin_list_params.rbs +17 -0
  330. data/sig/imagekitio/models/accounts/origin_list_response.rbs +10 -0
  331. data/sig/imagekitio/models/accounts/origin_request.rbs +468 -0
  332. data/sig/imagekitio/models/accounts/origin_response.rbs +418 -0
  333. data/sig/imagekitio/models/accounts/origin_update_params.rbs +30 -0
  334. data/sig/imagekitio/models/accounts/url_endpoint_create_params.rbs +17 -0
  335. data/sig/imagekitio/models/accounts/url_endpoint_delete_params.rbs +17 -0
  336. data/sig/imagekitio/models/accounts/url_endpoint_get_params.rbs +17 -0
  337. data/sig/imagekitio/models/accounts/url_endpoint_list_params.rbs +17 -0
  338. data/sig/imagekitio/models/accounts/url_endpoint_list_response.rbs +10 -0
  339. data/sig/imagekitio/models/accounts/url_endpoint_request.rbs +97 -0
  340. data/sig/imagekitio/models/accounts/url_endpoint_response.rbs +96 -0
  341. data/sig/imagekitio/models/accounts/url_endpoint_update_params.rbs +17 -0
  342. data/sig/imagekitio/models/accounts/usage_get_params.rbs +30 -0
  343. data/sig/imagekitio/models/accounts/usage_get_response.rbs +52 -0
  344. data/sig/imagekitio/models/asset_list_params.rbs +138 -0
  345. data/sig/imagekitio/models/asset_list_response.rbs +16 -0
  346. data/sig/imagekitio/models/base_overlay.rbs +31 -0
  347. data/sig/imagekitio/models/base_webhook_event.rbs +15 -0
  348. data/sig/imagekitio/models/beta/v2/file_upload_params.rbs +310 -0
  349. data/sig/imagekitio/models/beta/v2/file_upload_response.rbs +487 -0
  350. data/sig/imagekitio/models/cache/invalidation_create_params.rbs +25 -0
  351. data/sig/imagekitio/models/cache/invalidation_create_response.rbs +17 -0
  352. data/sig/imagekitio/models/cache/invalidation_get_params.rbs +17 -0
  353. data/sig/imagekitio/models/cache/invalidation_get_response.rbs +35 -0
  354. data/sig/imagekitio/models/custom_metadata_field.rbs +178 -0
  355. data/sig/imagekitio/models/custom_metadata_field_create_params.rbs +179 -0
  356. data/sig/imagekitio/models/custom_metadata_field_delete_params.rbs +15 -0
  357. data/sig/imagekitio/models/custom_metadata_field_delete_response.rbs +11 -0
  358. data/sig/imagekitio/models/custom_metadata_field_list_params.rbs +32 -0
  359. data/sig/imagekitio/models/custom_metadata_field_list_response.rbs +8 -0
  360. data/sig/imagekitio/models/custom_metadata_field_update_params.rbs +152 -0
  361. data/sig/imagekitio/models/extensions.rbs +132 -0
  362. data/sig/imagekitio/models/file.rbs +384 -0
  363. data/sig/imagekitio/models/file_copy_params.rbs +38 -0
  364. data/sig/imagekitio/models/file_copy_response.rbs +11 -0
  365. data/sig/imagekitio/models/file_delete_params.rbs +15 -0
  366. data/sig/imagekitio/models/file_get_params.rbs +14 -0
  367. data/sig/imagekitio/models/file_move_params.rbs +28 -0
  368. data/sig/imagekitio/models/file_move_response.rbs +11 -0
  369. data/sig/imagekitio/models/file_rename_params.rbs +34 -0
  370. data/sig/imagekitio/models/file_rename_response.rbs +15 -0
  371. data/sig/imagekitio/models/file_update_params.rbs +28 -0
  372. data/sig/imagekitio/models/file_update_response.rbs +120 -0
  373. data/sig/imagekitio/models/file_upload_params.rbs +327 -0
  374. data/sig/imagekitio/models/file_upload_response.rbs +483 -0
  375. data/sig/imagekitio/models/files/bulk_add_tags_params.rbs +30 -0
  376. data/sig/imagekitio/models/files/bulk_add_tags_response.rbs +20 -0
  377. data/sig/imagekitio/models/files/bulk_delete_params.rbs +26 -0
  378. data/sig/imagekitio/models/files/bulk_delete_response.rbs +20 -0
  379. data/sig/imagekitio/models/files/bulk_remove_ai_tags_params.rbs +30 -0
  380. data/sig/imagekitio/models/files/bulk_remove_ai_tags_response.rbs +20 -0
  381. data/sig/imagekitio/models/files/bulk_remove_tags_params.rbs +30 -0
  382. data/sig/imagekitio/models/files/bulk_remove_tags_response.rbs +20 -0
  383. data/sig/imagekitio/models/files/metadata_get_from_url_params.rbs +25 -0
  384. data/sig/imagekitio/models/files/metadata_get_params.rbs +17 -0
  385. data/sig/imagekitio/models/files/version_delete_params.rbs +25 -0
  386. data/sig/imagekitio/models/files/version_delete_response.rbs +13 -0
  387. data/sig/imagekitio/models/files/version_get_params.rbs +25 -0
  388. data/sig/imagekitio/models/files/version_list_params.rbs +17 -0
  389. data/sig/imagekitio/models/files/version_list_response.rbs +9 -0
  390. data/sig/imagekitio/models/files/version_restore_params.rbs +25 -0
  391. data/sig/imagekitio/models/folder.rbs +69 -0
  392. data/sig/imagekitio/models/folder_copy_params.rbs +38 -0
  393. data/sig/imagekitio/models/folder_copy_response.rbs +13 -0
  394. data/sig/imagekitio/models/folder_create_params.rbs +28 -0
  395. data/sig/imagekitio/models/folder_create_response.rbs +11 -0
  396. data/sig/imagekitio/models/folder_delete_params.rbs +23 -0
  397. data/sig/imagekitio/models/folder_delete_response.rbs +11 -0
  398. data/sig/imagekitio/models/folder_move_params.rbs +28 -0
  399. data/sig/imagekitio/models/folder_move_response.rbs +13 -0
  400. data/sig/imagekitio/models/folder_rename_params.rbs +34 -0
  401. data/sig/imagekitio/models/folder_rename_response.rbs +13 -0
  402. data/sig/imagekitio/models/folders/job_get_params.rbs +17 -0
  403. data/sig/imagekitio/models/folders/job_get_response.rbs +72 -0
  404. data/sig/imagekitio/models/get_image_attributes_options.rbs +43 -0
  405. data/sig/imagekitio/models/image_overlay.rbs +59 -0
  406. data/sig/imagekitio/models/metadata.rbs +546 -0
  407. data/sig/imagekitio/models/overlay.rbs +16 -0
  408. data/sig/imagekitio/models/overlay_position.rbs +85 -0
  409. data/sig/imagekitio/models/overlay_timing.rbs +66 -0
  410. data/sig/imagekitio/models/responsive_image_attributes.rbs +36 -0
  411. data/sig/imagekitio/models/solid_color_overlay.rbs +38 -0
  412. data/sig/imagekitio/models/solid_color_overlay_transformation.rbs +97 -0
  413. data/sig/imagekitio/models/src_options.rbs +64 -0
  414. data/sig/imagekitio/models/streaming_resolution.rbs +20 -0
  415. data/sig/imagekitio/models/subtitle_overlay.rbs +59 -0
  416. data/sig/imagekitio/models/subtitle_overlay_transformation.rbs +78 -0
  417. data/sig/imagekitio/models/text_overlay.rbs +59 -0
  418. data/sig/imagekitio/models/text_overlay_transformation.rbs +195 -0
  419. data/sig/imagekitio/models/transformation.rbs +763 -0
  420. data/sig/imagekitio/models/transformation_position.rbs +14 -0
  421. data/sig/imagekitio/models/unsafe_unwrap_webhook_event.rbs +18 -0
  422. data/sig/imagekitio/models/unwrap_webhook_event.rbs +18 -0
  423. data/sig/imagekitio/models/update_file_request.rbs +122 -0
  424. data/sig/imagekitio/models/upload_post_transform_error_event.rbs +192 -0
  425. data/sig/imagekitio/models/upload_post_transform_success_event.rbs +142 -0
  426. data/sig/imagekitio/models/upload_pre_transform_error_event.rbs +115 -0
  427. data/sig/imagekitio/models/upload_pre_transform_success_event.rbs +541 -0
  428. data/sig/imagekitio/models/video_overlay.rbs +59 -0
  429. data/sig/imagekitio/models/video_transformation_accepted_event.rbs +261 -0
  430. data/sig/imagekitio/models/video_transformation_error_event.rbs +300 -0
  431. data/sig/imagekitio/models/video_transformation_ready_event.rbs +359 -0
  432. data/sig/imagekitio/models/webhook_unsafe_unwrap_params.rbs +15 -0
  433. data/sig/imagekitio/models/webhook_unwrap_params.rbs +15 -0
  434. data/sig/imagekitio/models.rbs +119 -0
  435. data/sig/imagekitio/request_options.rbs +36 -0
  436. data/sig/imagekitio/resources/accounts/origins.rbs +34 -0
  437. data/sig/imagekitio/resources/accounts/url_endpoints.rbs +40 -0
  438. data/sig/imagekitio/resources/accounts/usage.rbs +15 -0
  439. data/sig/imagekitio/resources/accounts.rbs +13 -0
  440. data/sig/imagekitio/resources/assets.rbs +18 -0
  441. data/sig/imagekitio/resources/beta/v2/files.rbs +35 -0
  442. data/sig/imagekitio/resources/beta/v2.rbs +11 -0
  443. data/sig/imagekitio/resources/beta.rbs +9 -0
  444. data/sig/imagekitio/resources/cache/invalidation.rbs +19 -0
  445. data/sig/imagekitio/resources/cache.rbs +9 -0
  446. data/sig/imagekitio/resources/custom_metadata_fields.rbs +32 -0
  447. data/sig/imagekitio/resources/files/bulk.rbs +32 -0
  448. data/sig/imagekitio/resources/files/metadata.rbs +19 -0
  449. data/sig/imagekitio/resources/files/versions.rbs +32 -0
  450. data/sig/imagekitio/resources/files.rbs +76 -0
  451. data/sig/imagekitio/resources/folders/job.rbs +14 -0
  452. data/sig/imagekitio/resources/folders.rbs +40 -0
  453. data/sig/imagekitio/resources/webhooks.rbs +27 -0
  454. data/sig/imagekitio/version.rbs +3 -0
  455. metadata +470 -136
  456. data/Rakefile +0 -27
  457. data/lib/active_storage/active_storage.rb +0 -7
  458. data/lib/active_storage/service/ik_file.rb +0 -115
  459. data/lib/active_storage/service/image_kit_io_service.rb +0 -188
  460. data/lib/carrierwave/carrierwave.rb +0 -83
  461. data/lib/carrierwave/storage/ik_file.rb +0 -51
  462. data/lib/carrierwave/storage/imagekit_store.rb +0 -68
  463. data/lib/carrierwave/support/uri_filename.rb +0 -12
  464. data/lib/imagekitio/api_service/bulk.rb +0 -58
  465. data/lib/imagekitio/api_service/custom_metadata_field.rb +0 -52
  466. data/lib/imagekitio/api_service/file.rb +0 -221
  467. data/lib/imagekitio/api_service/folder.rb +0 -49
  468. data/lib/imagekitio/base.rb +0 -12
  469. data/lib/imagekitio/configurable.rb +0 -43
  470. data/lib/imagekitio/constant.rb +0 -36
  471. data/lib/imagekitio/constants/default.rb +0 -22
  472. data/lib/imagekitio/constants/error.rb +0 -69
  473. data/lib/imagekitio/constants/file.rb +0 -11
  474. data/lib/imagekitio/constants/supported_transformation.rb +0 -39
  475. data/lib/imagekitio/constants/url.rb +0 -14
  476. data/lib/imagekitio/railtie.rb +0 -4
  477. data/lib/imagekitio/request.rb +0 -98
  478. data/lib/imagekitio/sdk/version.rb +0 -5
  479. data/lib/imagekitio/url.rb +0 -216
  480. data/lib/imagekitio/utils/calculation.rb +0 -45
  481. data/lib/imagekitio/utils/formatter.rb +0 -48
  482. data/lib/imagekitio/utils/option_validator.rb +0 -36
  483. data/lib/tasks/imagekitio/imagekitio_tasks.rake +0 -4
@@ -0,0 +1,689 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "transformation_utils"
4
+ require_relative "crypto_utils"
5
+ require_relative "uuid_utils"
6
+
7
+ module Imagekitio
8
+ class Helper
9
+ TRANSFORMATION_PARAMETER = "tr"
10
+ SIGNATURE_PARAMETER = "ik-s"
11
+ TIMESTAMP_PARAMETER = "ik-t"
12
+ DEFAULT_TIMESTAMP = 9_999_999_999
13
+ SIMPLE_OVERLAY_PATH_REGEX = %r{^[a-zA-Z0-9\-._/ ]*$}
14
+ SIMPLE_OVERLAY_TEXT_REGEX = /^[a-zA-Z0-9\-._ ]*$/
15
+
16
+ private_constant :TRANSFORMATION_PARAMETER,
17
+ :SIGNATURE_PARAMETER,
18
+ :TIMESTAMP_PARAMETER,
19
+ :DEFAULT_TIMESTAMP,
20
+ :SIMPLE_OVERLAY_PATH_REGEX,
21
+ :SIMPLE_OVERLAY_TEXT_REGEX
22
+
23
+ # Builds a URL with transformations applied
24
+ #
25
+ # @param options [Imagekitio::Models::SrcOptions] Options for generating ImageKit URLs with transformations
26
+ # @return [String] The built URL with transformations
27
+ def build_url(options)
28
+ # Convert model to hash - all inputs are expected to be BaseModel objects
29
+ opts = options.to_h
30
+
31
+ # Set defaults
32
+ opts[:url_endpoint] ||= ""
33
+ opts[:src] ||= ""
34
+ opts[:transformation_position] ||= :query
35
+
36
+ return "" if opts[:src].nil? || opts[:src].empty?
37
+
38
+ src = opts[:src].to_s
39
+ is_absolute_url = src.start_with?("http://", "https://")
40
+
41
+ begin
42
+ if is_absolute_url
43
+ url_obj = URI.parse(src)
44
+ is_src_parameter_used_for_url = true
45
+ else
46
+ url_obj = URI.parse(opts[:url_endpoint].to_s)
47
+ end
48
+ rescue URI::InvalidURIError
49
+ return ""
50
+ end
51
+
52
+ # Add query parameters
53
+ query_params = opts[:query_parameters] || {}
54
+ existing_params = CGI.parse(url_obj.query || "")
55
+ query_params.each do |key, value|
56
+ existing_params[key.to_s] = [value.to_s]
57
+ end
58
+
59
+ # Build transformation string
60
+ transformation_string = build_transformation_string(opts[:transformation])
61
+
62
+ add_as_query = Imagekitio::TransformationUtils.add_as_query_parameter?(opts) ||
63
+ is_src_parameter_used_for_url
64
+ transformation_placeholder = "PLEASEREPLACEJUSTBEFORESIGN"
65
+
66
+ unless is_absolute_url
67
+ # For non-absolute URLs, construct the path
68
+ endpoint_path = url_obj.path
69
+ path_parts = []
70
+
71
+ # Add endpoint path if it's not empty
72
+ if !endpoint_path.empty? && endpoint_path != "/"
73
+ path_parts << endpoint_path
74
+ end
75
+
76
+ if !transformation_string.empty? && !add_as_query
77
+ path_parts << "#{TRANSFORMATION_PARAMETER}#{Imagekitio::TransformationUtils.get_chain_transform_delimiter}#{transformation_placeholder}"
78
+ end
79
+
80
+ path_parts << src
81
+ url_obj.path = path_join(path_parts)
82
+ end
83
+
84
+ # Build query string
85
+ unless existing_params.empty?
86
+ url_obj.query = existing_params.map { |k, v| "#{CGI.escape(k)}=#{CGI.escape(v.first)}" }.join("&")
87
+ end
88
+
89
+ # Build final URL
90
+ final_url = url_obj.to_s
91
+
92
+ # Add transformation parameter manually to avoid URL encoding
93
+ if !transformation_string.empty? && add_as_query
94
+ separator = url_obj.query && !url_obj.query.empty? ? "&" : "?"
95
+ final_url = "#{final_url}#{separator}#{TRANSFORMATION_PARAMETER}=#{transformation_placeholder}"
96
+ end
97
+
98
+ # Replace placeholder with actual transformation string
99
+ unless transformation_string.empty?
100
+ final_url = final_url.gsub(transformation_placeholder, transformation_string)
101
+ end
102
+
103
+ # Sign the URL if needed
104
+ if opts[:signed] == true || (opts[:expires_in] && opts[:expires_in].to_i.positive?)
105
+ expiry_timestamp = get_signature_timestamp(opts[:expires_in])
106
+
107
+ url_signature = get_signature(
108
+ private_key: @client.private_key,
109
+ url: final_url,
110
+ url_endpoint: opts[:url_endpoint].to_s,
111
+ expiry_timestamp: expiry_timestamp
112
+ )
113
+
114
+ # Add signature parameters
115
+ final_url_uri = URI.parse(final_url)
116
+ has_existing_params = final_url_uri.query && !final_url_uri.query.empty?
117
+ separator = has_existing_params ? "&" : "?"
118
+
119
+ if expiry_timestamp && expiry_timestamp != DEFAULT_TIMESTAMP
120
+ final_url = "#{final_url}#{separator}#{TIMESTAMP_PARAMETER}=#{expiry_timestamp}"
121
+ final_url = "#{final_url}&#{SIGNATURE_PARAMETER}=#{url_signature}"
122
+ else
123
+ final_url = "#{final_url}#{separator}#{SIGNATURE_PARAMETER}=#{url_signature}"
124
+ end
125
+ end
126
+
127
+ final_url
128
+ end
129
+
130
+ # Generates transformation string from transformation objects
131
+ #
132
+ # @param transformations [Array<Imagekitio::Models::Transformation>] Array of transformation objects
133
+ # @return [String] The transformation string (e.g., "w-400,h-300")
134
+ def build_transformation_string(transformations)
135
+ return "" unless transformations.is_a?(Array)
136
+
137
+ parsed_transforms = []
138
+
139
+ # rubocop:disable Metrics/BlockLength
140
+ transformations.each do |transform|
141
+ next unless transform
142
+
143
+ # Convert model to hash - all transformation inputs are expected to be BaseModel objects
144
+ current_transform = transform.to_h
145
+
146
+ parsed_transform_step = []
147
+
148
+ # rubocop:disable Metrics/BlockLength
149
+ current_transform.each do |key, value|
150
+ next if value.nil? || value.to_s.empty?
151
+
152
+ # Handle overlay separately
153
+ if key.to_s == "overlay" && value
154
+ # Pass model object directly to process_overlay
155
+ raw_string = process_overlay(value)
156
+ if raw_string && !raw_string.strip.empty?
157
+ parsed_transform_step << raw_string
158
+ end
159
+ next
160
+ end
161
+
162
+ transform_key = Imagekitio::TransformationUtils.get_transform_key(key)
163
+ transform_key = key.to_s if transform_key.empty?
164
+
165
+ next if transform_key.empty?
166
+
167
+ # Handle special boolean effects
168
+ boolean_effects = %w[e-grayscale e-contrast e-removedotbg e-bgremove e-upscale e-retouch e-genvar]
169
+ if boolean_effects.include?(transform_key)
170
+ if value == true || value == "-" || value == "true"
171
+ parsed_transform_step << transform_key
172
+ end
173
+ next
174
+ end
175
+
176
+ # Handle effects that can be boolean or have values
177
+ value_effects = %w[e-sharpen e-shadow e-gradient e-usm e-dropshadow]
178
+ if value_effects.include?(transform_key) &&
179
+ (value.to_s.strip.empty? || value == true || value == "true")
180
+ parsed_transform_step << transform_key
181
+ next
182
+ end
183
+
184
+ # Handle raw parameter
185
+ if key.to_s == "raw"
186
+ parsed_transform_step << value.to_s
187
+ next
188
+ end
189
+
190
+ # Handle special cases for di and ff (need special encoding)
191
+ if %w[di ff].include?(transform_key)
192
+ processed_value = remove_leading_slash(remove_trailing_slash(value.to_s))
193
+ processed_value = processed_value.gsub("/", "@@")
194
+ value = processed_value
195
+ end
196
+
197
+ # Handle streaming resolutions array
198
+ if transform_key == "sr" && value.is_a?(Array)
199
+ value = value.join("_")
200
+ end
201
+
202
+ # Special case for trim with empty string
203
+ if transform_key == "t" && value.to_s.strip.empty?
204
+ value = "true"
205
+ end
206
+
207
+ # Convert numeric values to integers if they're whole numbers
208
+ if value.is_a?(Numeric)
209
+ value = value.to_i if value == value.to_i
210
+ end
211
+
212
+ parsed_transform_step << "#{transform_key}#{Imagekitio::TransformationUtils.get_transform_key_value_delimiter}#{value}"
213
+ end
214
+ # rubocop:enable Metrics/BlockLength
215
+
216
+ unless parsed_transform_step.empty?
217
+ parsed_transforms << parsed_transform_step.join(Imagekitio::TransformationUtils.get_transform_delimiter)
218
+ end
219
+ end
220
+ # rubocop:enable Metrics/BlockLength
221
+
222
+ parsed_transforms.join(Imagekitio::TransformationUtils.get_chain_transform_delimiter)
223
+ end
224
+
225
+ # Generates authentication parameters for client-side file uploads using ImageKit's Upload API V1.
226
+ #
227
+ # This method creates the required authentication signature that allows secure file uploads
228
+ # directly from the browser or mobile applications without exposing your private API key.
229
+ # The generated parameters include a unique token, expiration timestamp, and HMAC signature.
230
+ #
231
+ # @param token [String, nil] Custom token for the upload session. If not provided, a UUID v4 will be generated automatically.
232
+ # @param expire [Integer, nil] Expiration time in seconds from now. If not provided, defaults to 1800 seconds (30 minutes).
233
+ # @return [Hash{Symbol => String, Integer}] Authentication parameters object containing:
234
+ # - :token (String): Unique identifier for this upload session
235
+ # - :expire (Integer): Unix timestamp when these parameters expire
236
+ # - :signature (String): HMAC-SHA1 signature for authenticating the upload
237
+ def get_authentication_parameters(token: nil, expire: nil)
238
+ default_time_diff = 60 * 30
239
+ default_expire = Time.now.to_i + default_time_diff
240
+
241
+ # Handle falsy values - empty string and nil should generate new token
242
+ final_token = token.nil? || token.to_s.empty? ? generate_token : token
243
+ # Handle falsy values - nil and 0 should use default expire
244
+ final_expire = expire.nil? || expire.zero? ? default_expire : expire
245
+
246
+ get_authentication_parameters_internal(final_token, final_expire, @client.private_key)
247
+ end
248
+
249
+ # Generates responsive image attributes for use in HTML <img> tags.
250
+ #
251
+ # This method creates optimized srcset and sizes attributes for responsive images,
252
+ # enabling browsers to select the most appropriate image size based on the device's
253
+ # screen width and resolution. Supports three strategies:
254
+ # - Width-based (w descriptors): When sizes attribute is provided
255
+ # - DPR-based (x descriptors): When width is provided without sizes
256
+ # - Fallback (w descriptors): Uses device breakpoints when neither is provided
257
+ #
258
+ # @param options [Imagekitio::Models::GetImageAttributesOptions] Options for generating responsive image attributes
259
+ # @return [Imagekitio::Models::ResponsiveImageAttributes] Responsive image attributes suitable for an HTML <img> element
260
+ def get_responsive_image_attributes(options)
261
+ # Convert model to hash for easier access
262
+ opts = options.is_a?(Imagekitio::Internal::Type::BaseModel) ? options.to_h : options
263
+
264
+ # Default breakpoint pools
265
+ default_device_breakpoints = [640, 750, 828, 1080, 1200, 1920, 2048, 3840]
266
+ default_image_breakpoints = [16, 32, 48, 64, 96, 128, 256, 384]
267
+
268
+ # Extract options
269
+ src = opts[:src]
270
+ url_endpoint = opts[:url_endpoint]
271
+ width = opts[:width]
272
+ sizes = opts[:sizes]
273
+ device_breakpoints = opts[:device_breakpoints] || default_device_breakpoints
274
+ image_breakpoints = opts[:image_breakpoints] || default_image_breakpoints
275
+ transformation = opts[:transformation] || []
276
+ transformation_position = opts[:transformation_position]
277
+ query_parameters = opts[:query_parameters]
278
+ expires_in = opts[:expires_in]
279
+ signed = opts[:signed]
280
+
281
+ # Sort and merge breakpoints
282
+ sorted_device_breakpoints = device_breakpoints.sort
283
+ sorted_image_breakpoints = image_breakpoints.sort
284
+ all_breakpoints = (sorted_image_breakpoints + sorted_device_breakpoints).sort.uniq
285
+
286
+ # Compute candidate widths and descriptor kind
287
+ result = compute_candidate_widths(
288
+ all_breakpoints: all_breakpoints,
289
+ device_breakpoints: sorted_device_breakpoints,
290
+ explicit_width: width,
291
+ sizes_attr: sizes
292
+ )
293
+ candidates = result[:candidates]
294
+ descriptor_kind = result[:descriptor_kind]
295
+
296
+ # Helper to build a single ImageKit URL
297
+ build_url_fn = lambda do |w|
298
+ build_url(
299
+ Imagekitio::Models::SrcOptions.new(
300
+ src: src,
301
+ url_endpoint: url_endpoint,
302
+ query_parameters: query_parameters,
303
+ transformation_position: transformation_position,
304
+ expires_in: expires_in,
305
+ signed: signed,
306
+ transformation: transformation + [
307
+ Imagekitio::Models::Transformation.new(width: w, crop: "at_max") # never upscale beyond original
308
+ ]
309
+ )
310
+ )
311
+ end
312
+
313
+ # Build srcset
314
+ src_set_entries = candidates.map.with_index do |w, i|
315
+ # Ensure width is an integer for proper descriptor format (e.g., "640w" not "640.0w")
316
+ width_int = w.to_i
317
+ descriptor = descriptor_kind == :w ? "#{width_int}w" : "#{i + 1}x"
318
+ "#{build_url_fn.call(width_int)} #{descriptor}"
319
+ end
320
+ src_set = src_set_entries.empty? ? nil : src_set_entries.join(", ")
321
+
322
+ final_sizes = sizes || (descriptor_kind == :w ? "100vw" : nil)
323
+
324
+ # Build and return ResponsiveImageAttributes model
325
+ Imagekitio::Models::ResponsiveImageAttributes.new(
326
+ src: build_url_fn.call(candidates.last.to_i), # largest candidate as integer
327
+ src_set: src_set,
328
+ sizes: final_sizes,
329
+ width: width
330
+ )
331
+ end
332
+
333
+ # @api private
334
+ #
335
+ # @param client [Imagekitio::Client]
336
+ def initialize(client:)
337
+ @client = client
338
+ end
339
+
340
+ private
341
+
342
+ # Compute candidate widths for responsive images.
343
+ # Implements three strategies:
344
+ # 1. Width-based srcSet (w) when sizes attribute contains vw units
345
+ # 2. Fallback to device breakpoints when no width or sizes provided
346
+ # 3. DPR-based srcSet (x) with 1x and 2x variants when width is provided
347
+ def compute_candidate_widths(
348
+ all_breakpoints:,
349
+ device_breakpoints:,
350
+ explicit_width: nil,
351
+ sizes_attr: nil
352
+ )
353
+ # Strategy 1: Width-based srcSet (w) using viewport vw hints
354
+ if sizes_attr
355
+ vw_tokens = sizes_attr.scan(/(?:^|\s)(1?\d{1,2})vw/).flatten.map(&:to_i)
356
+
357
+ if vw_tokens.any?
358
+ # Find the smallest vw percentage
359
+ smallest_ratio = vw_tokens.min / 100.0
360
+ # Calculate minimum required pixels
361
+ min_required_px = device_breakpoints.first * smallest_ratio
362
+ # Filter breakpoints >= min_required_px
363
+ candidates = all_breakpoints.select { |bp| bp >= min_required_px }
364
+ return {candidates: candidates, descriptor_kind: :w}
365
+ end
366
+
367
+ # No usable vw found: fallback to all breakpoints
368
+ return {candidates: all_breakpoints, descriptor_kind: :w}
369
+ end
370
+
371
+ # Strategy 2: Fallback using device breakpoints if no explicit width
372
+ return {candidates: device_breakpoints, descriptor_kind: :w} unless explicit_width
373
+
374
+ # Strategy 3: Use 1x and 2x nearest breakpoints for x descriptor
375
+ # Find the first breakpoint >= target (or use the largest)
376
+ nearest = lambda do |target|
377
+ all_breakpoints.find { |bp| bp >= target } || all_breakpoints.last
378
+ end
379
+
380
+ # Generate unique 1x and 2x variants
381
+ unique = [nearest.call(explicit_width), nearest.call(explicit_width * 2)].uniq
382
+
383
+ {candidates: unique, descriptor_kind: :x}
384
+ end
385
+
386
+ # Generate a 32-character hex token
387
+ def generate_token
388
+ # Generate 16 random bytes and convert to hex (32 characters)
389
+ require("securerandom")
390
+ SecureRandom.hex(16)
391
+ end
392
+
393
+ # Internal method to generate authentication parameters
394
+ def get_authentication_parameters_internal(token, expire, private_key)
395
+ auth_parameters = {
396
+ token: token,
397
+ expire: expire,
398
+ signature: ""
399
+ }
400
+
401
+ signature = Imagekitio::CryptoUtils.create_hmac_sha1(private_key, token.to_s + expire.to_s)
402
+ auth_parameters[:signature] = signature
403
+
404
+ auth_parameters
405
+ end
406
+
407
+ # Remove trailing slash from string
408
+ def remove_trailing_slash(str)
409
+ return str unless str.is_a?(String) && str.end_with?("/")
410
+ str.chomp("/")
411
+ end
412
+
413
+ # Remove leading slash from string
414
+ def remove_leading_slash(str)
415
+ return str unless str.is_a?(String) && str.start_with?("/")
416
+ str[1..]
417
+ end
418
+
419
+ # RFC 3986 path encoding - matches Node.js encodeURIPath exactly
420
+ # From Node.js: str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent)
421
+ def encode_uri_path(str)
422
+ # Only encode characters that are NOT in the RFC 3986 path character set
423
+ # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
424
+ # sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
425
+ # pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
426
+ str.gsub(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/) { |match| CGI.escape(match) }
427
+ end
428
+
429
+ # Join path parts (Node.js pathJoin algorithm without encoding)
430
+ def path_join(parts, separator = "/")
431
+ return "" if parts.nil? || parts.empty?
432
+
433
+ # Clean up parts and join
434
+ cleaned_parts = []
435
+
436
+ parts.each do |part|
437
+ part = part.to_s.strip
438
+ next if part.empty?
439
+
440
+ # Remove leading slashes from all parts
441
+ part = part[1..] while part.start_with?(separator)
442
+
443
+ # Remove trailing slashes from all parts
444
+ part = part[0..-2] while part.end_with?(separator)
445
+
446
+ cleaned_parts << part unless part.empty?
447
+ end
448
+
449
+ return "" if cleaned_parts.empty?
450
+
451
+ # Join with separator and add leading slash (Node.js style)
452
+ result = separator + cleaned_parts.join(separator)
453
+
454
+ # Apply encoding to special characters only, preserving path structure
455
+ result.gsub(/[^\x00-\x7F]/) { |char| CGI.escape(char) }
456
+ end
457
+
458
+ # Process overlay transformation (full implementation)
459
+ def process_overlay(overlay)
460
+ return "" unless overlay
461
+
462
+ # Support both BaseModel objects and plain hashes
463
+ type = if overlay.is_a?(Hash)
464
+ overlay[:type] || overlay["type"]
465
+ else
466
+ overlay.type
467
+ end
468
+ return "" unless type
469
+
470
+ # Determine overlay type based on explicit type field
471
+ case type.to_s
472
+ when "text"
473
+ process_text_overlay(overlay)
474
+ when "image"
475
+ process_image_overlay(overlay)
476
+ when "video"
477
+ process_video_overlay(overlay)
478
+ when "subtitle"
479
+ process_subtitle_overlay(overlay)
480
+ when "solidColor"
481
+ process_solid_color_overlay(overlay)
482
+ else
483
+ ""
484
+ end
485
+ end
486
+
487
+ # Process input path for image/video/subtitle overlays (matching Node.js processInputPath)
488
+ def process_input_path(str, encoding)
489
+ # Remove leading and trailing slashes
490
+ str = remove_trailing_slash(remove_leading_slash(str))
491
+
492
+ case encoding.to_s
493
+ when "plain"
494
+ "i-#{str.gsub('/', '@@')}"
495
+ when "base64"
496
+ "ie-#{CGI.escape(Base64.strict_encode64(str))}"
497
+ else # auto
498
+ if str.match?(SIMPLE_OVERLAY_PATH_REGEX)
499
+ "i-#{str.gsub('/', '@@')}"
500
+ else
501
+ "ie-#{CGI.escape(Base64.strict_encode64(str))}"
502
+ end
503
+ end
504
+ end
505
+
506
+ # Process text content for text overlays (matching Node.js processText)
507
+ def process_text(str, encoding)
508
+ case encoding.to_s
509
+ when "plain"
510
+ "i-#{uri_encode(str)}"
511
+ when "base64"
512
+ "ie-#{uri_encode(Base64.strict_encode64(str))}"
513
+ else # auto
514
+ if str.match?(SIMPLE_OVERLAY_TEXT_REGEX)
515
+ "i-#{uri_encode(str)}"
516
+ else
517
+ "ie-#{uri_encode(Base64.strict_encode64(str))}"
518
+ end
519
+ end
520
+ end
521
+
522
+ # URI encode like JavaScript's encodeURIComponent (uses %20 instead of +)
523
+ def uri_encode(str)
524
+ CGI.escape(str).gsub("+", "%20")
525
+ end
526
+
527
+ # Process text overlay
528
+ def process_text_overlay(overlay)
529
+ text = safe_get(overlay, :text)
530
+ return "" unless text && !text.to_s.empty?
531
+
532
+ parts = ["l-text"]
533
+
534
+ # Handle encoding using the processText function
535
+ encoding = safe_get(overlay, :encoding) || "auto"
536
+ parts << process_text(text, encoding)
537
+
538
+ # Add other overlay properties (position, timing, transformations)
539
+ add_overlay_properties(parts, overlay)
540
+
541
+ parts << "l-end"
542
+ parts.join(",")
543
+ end
544
+
545
+ # Process image overlay
546
+ def process_image_overlay(overlay)
547
+ input = safe_get(overlay, :input)
548
+ return "" unless input && !input.to_s.empty?
549
+
550
+ parts = ["l-image"]
551
+
552
+ # Handle encoding using the process_input_path function
553
+ encoding = safe_get(overlay, :encoding) || "auto"
554
+ parts << process_input_path(input, encoding)
555
+
556
+ # Add other overlay properties
557
+ add_overlay_properties(parts, overlay)
558
+
559
+ parts << "l-end"
560
+ parts.join(",")
561
+ end
562
+
563
+ # Process video overlay
564
+ def process_video_overlay(overlay)
565
+ input = safe_get(overlay, :input)
566
+ return "" unless input && !input.to_s.empty?
567
+
568
+ parts = ["l-video"]
569
+
570
+ # Handle encoding using the process_input_path function
571
+ encoding = safe_get(overlay, :encoding) || "auto"
572
+ parts << process_input_path(input, encoding)
573
+
574
+ # Add other overlay properties
575
+ add_overlay_properties(parts, overlay)
576
+
577
+ parts << "l-end"
578
+ parts.join(",")
579
+ end
580
+
581
+ # Process subtitle overlay
582
+ def process_subtitle_overlay(overlay)
583
+ input = safe_get(overlay, :input)
584
+ return "" unless input && !input.to_s.empty?
585
+
586
+ parts = ["l-subtitle"]
587
+
588
+ # Handle encoding using the process_input_path function
589
+ encoding = safe_get(overlay, :encoding) || "auto"
590
+ parts << process_input_path(input, encoding)
591
+
592
+ # Add other overlay properties
593
+ add_overlay_properties(parts, overlay)
594
+
595
+ parts << "l-end"
596
+ parts.join(",")
597
+ end
598
+
599
+ # Process solid color overlay
600
+ def process_solid_color_overlay(overlay)
601
+ color = safe_get(overlay, :color)
602
+ return "" unless color && !color.to_s.empty?
603
+
604
+ parts = ["l-image", "i-ik_canvas", "bg-#{color}"]
605
+
606
+ # Add other overlay properties
607
+ add_overlay_properties(parts, overlay)
608
+
609
+ parts << "l-end"
610
+ parts.join(",")
611
+ end
612
+
613
+ # Safe property access for model objects and hashes
614
+ def safe_get(obj, key)
615
+ return nil unless obj
616
+
617
+ # Support both BaseModel objects and plain hashes
618
+ if obj.is_a?(Hash)
619
+ obj[key.to_sym] || obj[key.to_s]
620
+ elsif obj.respond_to?(key.to_sym)
621
+ obj.send(key.to_sym)
622
+ else
623
+ nil
624
+ end
625
+ end
626
+
627
+ # Add overlay properties like position, timing, transformations (matching Node.js)
628
+ def add_overlay_properties(parts, overlay)
629
+ # Add position properties
630
+ position = safe_get(overlay, :position)
631
+ if position
632
+ x = safe_get(position, :x)
633
+ y = safe_get(position, :y_)
634
+ focus = safe_get(position, :focus)
635
+
636
+ parts << "lx-#{x}" if x
637
+ parts << "ly-#{y}" if y
638
+ parts << "lfo-#{focus}" if focus
639
+ end
640
+
641
+ # Add timing properties
642
+ timing = safe_get(overlay, :timing)
643
+ if timing
644
+ start = safe_get(timing, :start)
645
+ end_time = safe_get(timing, :end_)
646
+ duration = safe_get(timing, :duration)
647
+
648
+ parts << "lso-#{start.to_i}" if start
649
+ parts << "leo-#{end_time.to_i}" if end_time
650
+ parts << "ldu-#{duration}" if duration
651
+ end
652
+
653
+ # Add transformation properties
654
+ transformations = safe_get(overlay, :transformation)
655
+ return unless transformations && transformations.is_a?(Array)
656
+ transformation_string = build_transformation_string(transformations)
657
+ return unless transformation_string && !transformation_string.strip.empty?
658
+ parts << transformation_string
659
+ end
660
+
661
+ # Calculate expiry timestamp for URL signing
662
+ def get_signature_timestamp(seconds)
663
+ return DEFAULT_TIMESTAMP unless seconds && seconds.to_i.positive?
664
+
665
+ sec = seconds.to_i
666
+ return DEFAULT_TIMESTAMP if sec <= 0
667
+
668
+ Time.now.to_i + sec
669
+ end
670
+
671
+ # Generate HMAC-SHA1 signature for URL signing
672
+ def get_signature(private_key:, url:, url_endpoint:, expiry_timestamp:)
673
+ return "" if private_key.nil? || private_key.empty? || url.nil? || url.empty? || url_endpoint.nil?
674
+
675
+ # Create string to sign: relative path + expiry timestamp
676
+ endpoint_with_slash = add_trailing_slash(url_endpoint)
677
+ string_to_sign = url.gsub(endpoint_with_slash, "") + expiry_timestamp.to_s
678
+
679
+ Imagekitio::CryptoUtils.create_hmac_sha1(private_key, string_to_sign)
680
+ end
681
+
682
+ # Add trailing slash to string if not present
683
+ def add_trailing_slash(str)
684
+ return str unless str.is_a?(String)
685
+ return str if str.end_with?("/")
686
+ "#{str}/"
687
+ end
688
+ end
689
+ end