@llumiverse/drivers 1.3.0 → 1.4.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 (409) hide show
  1. package/lib/{types/adobe → adobe}/firefly.d.ts +2 -1
  2. package/lib/adobe/firefly.d.ts.map +1 -0
  3. package/lib/adobe/firefly.js +120 -0
  4. package/lib/adobe/firefly.js.map +1 -0
  5. package/lib/{types/anthropic → anthropic}/index.d.ts +4 -2
  6. package/lib/anthropic/index.d.ts.map +1 -0
  7. package/lib/{esm/anthropic → anthropic}/index.js +19 -8
  8. package/lib/anthropic/index.js.map +1 -0
  9. package/lib/{types/azure → azure}/azure_foundry.d.ts +9 -7
  10. package/lib/azure/azure_foundry.d.ts.map +1 -0
  11. package/lib/{esm/azure → azure}/azure_foundry.js +138 -124
  12. package/lib/azure/azure_foundry.js.map +1 -0
  13. package/lib/{types/bedrock → bedrock}/converse.d.ts +2 -2
  14. package/lib/bedrock/converse.d.ts.map +1 -0
  15. package/lib/{esm/bedrock → bedrock}/converse.js +86 -79
  16. package/lib/bedrock/converse.js.map +1 -0
  17. package/lib/bedrock/embeddings.d.ts +4 -0
  18. package/lib/bedrock/embeddings.d.ts.map +1 -0
  19. package/lib/bedrock/embeddings.js +359 -0
  20. package/lib/bedrock/embeddings.js.map +1 -0
  21. package/lib/{types/bedrock → bedrock}/index.d.ts +33 -9
  22. package/lib/bedrock/index.d.ts.map +1 -0
  23. package/lib/{esm/bedrock → bedrock}/index.js +599 -324
  24. package/lib/bedrock/index.js.map +1 -0
  25. package/lib/{types/bedrock → bedrock}/nova-image-payload.d.ts +5 -5
  26. package/lib/bedrock/nova-image-payload.d.ts.map +1 -0
  27. package/lib/{esm/bedrock → bedrock}/nova-image-payload.js +31 -36
  28. package/lib/bedrock/nova-image-payload.js.map +1 -0
  29. package/lib/{types/bedrock → bedrock}/payloads.d.ts +1 -1
  30. package/lib/bedrock/payloads.d.ts.map +1 -0
  31. package/lib/{cjs/bedrock → bedrock}/payloads.js.map +1 -1
  32. package/lib/{types/bedrock → bedrock}/s3.d.ts +3 -2
  33. package/lib/bedrock/s3.d.ts.map +1 -0
  34. package/lib/{esm/bedrock → bedrock}/s3.js +27 -23
  35. package/lib/bedrock/s3.js.map +1 -0
  36. package/lib/{types/bedrock → bedrock}/twelvelabs.d.ts +8 -9
  37. package/lib/bedrock/twelvelabs.d.ts.map +1 -0
  38. package/lib/{esm/bedrock → bedrock}/twelvelabs.js +17 -21
  39. package/lib/bedrock/twelvelabs.js.map +1 -0
  40. package/lib/{types/groq → groq}/index.d.ts +6 -4
  41. package/lib/groq/index.d.ts.map +1 -0
  42. package/lib/{esm/groq → groq}/index.js +72 -39
  43. package/lib/groq/index.js.map +1 -0
  44. package/lib/{types/huggingface_ie.d.ts → huggingface_ie.d.ts} +4 -3
  45. package/lib/huggingface_ie.d.ts.map +1 -0
  46. package/lib/{esm/huggingface_ie.js → huggingface_ie.js} +32 -31
  47. package/lib/huggingface_ie.js.map +1 -0
  48. package/lib/index.d.ts +16 -0
  49. package/lib/index.d.ts.map +1 -0
  50. package/lib/index.js +16 -0
  51. package/lib/index.js.map +1 -0
  52. package/lib/{types/mistral → mistral}/index.d.ts +6 -5
  53. package/lib/mistral/index.d.ts.map +1 -0
  54. package/lib/{esm/mistral → mistral}/index.js +66 -38
  55. package/lib/mistral/index.js.map +1 -0
  56. package/lib/{types/mistral → mistral}/types.d.ts +1 -0
  57. package/lib/mistral/types.d.ts.map +1 -0
  58. package/lib/mistral/types.js.map +1 -0
  59. package/lib/{types/openai → openai}/azure_openai.d.ts +5 -4
  60. package/lib/openai/azure_openai.d.ts.map +1 -0
  61. package/lib/{esm/openai → openai}/azure_openai.js +17 -14
  62. package/lib/openai/azure_openai.js.map +1 -0
  63. package/lib/openai/drivers.d.ts +4 -0
  64. package/lib/openai/drivers.d.ts.map +1 -0
  65. package/lib/openai/drivers.js +9 -0
  66. package/lib/openai/drivers.js.map +1 -0
  67. package/lib/{types/openai → openai}/index.d.ts +16 -5
  68. package/lib/openai/index.d.ts.map +1 -0
  69. package/lib/{esm/openai → openai}/index.js +242 -141
  70. package/lib/openai/index.js.map +1 -0
  71. package/lib/{types/openai → openai}/openai.d.ts +3 -3
  72. package/lib/openai/openai.d.ts.map +1 -0
  73. package/lib/openai/openai.js +15 -0
  74. package/lib/openai/openai.js.map +1 -0
  75. package/lib/{types/openai → openai}/openai_compatible.d.ts +3 -3
  76. package/lib/openai/openai_compatible.d.ts.map +1 -0
  77. package/lib/{esm/openai → openai}/openai_compatible.js +14 -11
  78. package/lib/openai/openai_compatible.js.map +1 -0
  79. package/lib/{types/openai → openai}/openai_format.d.ts +3 -2
  80. package/lib/openai/openai_format.d.ts.map +1 -0
  81. package/lib/{esm/openai → openai}/openai_format.js +66 -24
  82. package/lib/openai/openai_format.js.map +1 -0
  83. package/lib/{types/replicate.d.ts → replicate.d.ts} +3 -2
  84. package/lib/replicate.d.ts.map +1 -0
  85. package/lib/{esm/replicate.js → replicate.js} +59 -49
  86. package/lib/replicate.js.map +1 -0
  87. package/lib/{types/shared → shared}/claude-messages.d.ts +25 -1
  88. package/lib/shared/claude-messages.d.ts.map +1 -0
  89. package/lib/{esm/shared → shared}/claude-messages.js +212 -59
  90. package/lib/shared/claude-messages.js.map +1 -0
  91. package/lib/{types/shared → shared}/claude-thinking.d.ts +1 -1
  92. package/lib/shared/claude-thinking.d.ts.map +1 -0
  93. package/lib/{esm/shared → shared}/claude-thinking.js +5 -7
  94. package/lib/shared/claude-thinking.js.map +1 -0
  95. package/lib/shared/debug-prompt.d.ts +5 -0
  96. package/lib/shared/debug-prompt.d.ts.map +1 -0
  97. package/lib/shared/debug-prompt.js +25 -0
  98. package/lib/shared/debug-prompt.js.map +1 -0
  99. package/lib/{types/test-driver → test-driver}/TestErrorCompletionStream.d.ts +1 -1
  100. package/lib/test-driver/TestErrorCompletionStream.d.ts.map +1 -0
  101. package/lib/test-driver/TestErrorCompletionStream.js +16 -0
  102. package/lib/test-driver/TestErrorCompletionStream.js.map +1 -0
  103. package/lib/{types/test-driver → test-driver}/TestValidationErrorCompletionStream.d.ts +1 -1
  104. package/lib/test-driver/TestValidationErrorCompletionStream.d.ts.map +1 -0
  105. package/lib/{esm/test-driver → test-driver}/TestValidationErrorCompletionStream.js +4 -4
  106. package/lib/test-driver/TestValidationErrorCompletionStream.js.map +1 -0
  107. package/lib/{types/test-driver → test-driver}/index.d.ts +3 -3
  108. package/lib/test-driver/index.d.ts.map +1 -0
  109. package/lib/{esm/test-driver → test-driver}/index.js +20 -20
  110. package/lib/test-driver/index.js.map +1 -0
  111. package/lib/{types/test-driver → test-driver}/utils.d.ts +1 -1
  112. package/lib/test-driver/utils.d.ts.map +1 -0
  113. package/lib/{esm/test-driver → test-driver}/utils.js +4 -4
  114. package/lib/test-driver/utils.js.map +1 -0
  115. package/lib/togetherai/index.d.ts +15 -0
  116. package/lib/togetherai/index.d.ts.map +1 -0
  117. package/lib/togetherai/index.js +54 -0
  118. package/lib/togetherai/index.js.map +1 -0
  119. package/lib/{types/togetherai → togetherai}/interfaces.d.ts +1 -1
  120. package/lib/togetherai/interfaces.d.ts.map +1 -0
  121. package/lib/{cjs/watsonx → togetherai}/interfaces.js.map +1 -1
  122. package/lib/vertexai/debug.d.ts +2 -0
  123. package/lib/vertexai/debug.d.ts.map +1 -0
  124. package/lib/{esm/vertexai → vertexai}/debug.js +1 -1
  125. package/lib/vertexai/debug.js.map +1 -0
  126. package/lib/vertexai/embeddings/embed-legacy-multimodal.d.ts +9 -0
  127. package/lib/vertexai/embeddings/embed-legacy-multimodal.d.ts.map +1 -0
  128. package/lib/vertexai/embeddings/embed-legacy-multimodal.js +141 -0
  129. package/lib/vertexai/embeddings/embed-legacy-multimodal.js.map +1 -0
  130. package/lib/vertexai/embeddings/embed.d.ts +13 -0
  131. package/lib/vertexai/embeddings/embed.d.ts.map +1 -0
  132. package/lib/vertexai/embeddings/embed.js +162 -0
  133. package/lib/vertexai/embeddings/embed.js.map +1 -0
  134. package/lib/vertexai/embeddings/source-utils.d.ts +9 -0
  135. package/lib/vertexai/embeddings/source-utils.d.ts.map +1 -0
  136. package/lib/vertexai/embeddings/source-utils.js +18 -0
  137. package/lib/vertexai/embeddings/source-utils.js.map +1 -0
  138. package/lib/{types/vertexai → vertexai}/index.d.ts +31 -19
  139. package/lib/vertexai/index.d.ts.map +1 -0
  140. package/lib/{esm/vertexai → vertexai}/index.js +221 -159
  141. package/lib/vertexai/index.js.map +1 -0
  142. package/lib/{types/vertexai → vertexai}/models/claude.d.ts +4 -4
  143. package/lib/vertexai/models/claude.d.ts.map +1 -0
  144. package/lib/{esm/vertexai → vertexai}/models/claude.js +17 -20
  145. package/lib/vertexai/models/claude.js.map +1 -0
  146. package/lib/{types/vertexai → vertexai}/models/gemini.d.ts +28 -4
  147. package/lib/vertexai/models/gemini.d.ts.map +1 -0
  148. package/lib/{esm/vertexai → vertexai}/models/gemini.js +238 -116
  149. package/lib/vertexai/models/gemini.js.map +1 -0
  150. package/lib/{types/vertexai → vertexai}/models/imagen.d.ts +12 -11
  151. package/lib/vertexai/models/imagen.d.ts.map +1 -0
  152. package/lib/{esm/vertexai → vertexai}/models/imagen.js +74 -47
  153. package/lib/vertexai/models/imagen.js.map +1 -0
  154. package/lib/{types/vertexai → vertexai}/models/llama.d.ts +4 -4
  155. package/lib/vertexai/models/llama.d.ts.map +1 -0
  156. package/lib/{esm/vertexai → vertexai}/models/llama.js +37 -33
  157. package/lib/vertexai/models/llama.js.map +1 -0
  158. package/lib/vertexai/models.d.ts +21 -0
  159. package/lib/vertexai/models.d.ts.map +1 -0
  160. package/lib/{esm/vertexai → vertexai}/models.js +12 -9
  161. package/lib/vertexai/models.js.map +1 -0
  162. package/lib/{types/watsonx → watsonx}/index.d.ts +4 -3
  163. package/lib/watsonx/index.d.ts.map +1 -0
  164. package/lib/{esm/watsonx → watsonx}/index.js +69 -41
  165. package/lib/watsonx/index.js.map +1 -0
  166. package/lib/watsonx/interfaces.d.ts.map +1 -0
  167. package/lib/{esm/watsonx → watsonx}/interfaces.js.map +1 -1
  168. package/lib/{types/xai → xai}/index.d.ts +4 -4
  169. package/lib/xai/index.d.ts.map +1 -0
  170. package/lib/{esm/xai → xai}/index.js +22 -18
  171. package/lib/xai/index.js.map +1 -0
  172. package/package.json +87 -36
  173. package/src/adobe/firefly.ts +60 -43
  174. package/src/anthropic/index.ts +37 -20
  175. package/src/azure/azure_foundry.ts +210 -165
  176. package/src/bedrock/converse.ts +124 -101
  177. package/src/bedrock/embeddings.test.ts +508 -0
  178. package/src/bedrock/embeddings.ts +517 -0
  179. package/src/bedrock/error-handling.test.ts +62 -14
  180. package/src/bedrock/index.ts +832 -466
  181. package/src/bedrock/nova-image-payload.ts +98 -91
  182. package/src/bedrock/payloads.ts +9 -9
  183. package/src/bedrock/s3.test.ts +39 -0
  184. package/src/bedrock/s3.ts +57 -38
  185. package/src/bedrock/streaming-tool-use.test.ts +86 -69
  186. package/src/bedrock/twelvelabs.ts +35 -32
  187. package/src/groq/index.ts +143 -60
  188. package/src/http-timeout-wiring.test.ts +263 -0
  189. package/src/huggingface_ie.ts +45 -61
  190. package/src/index.ts +15 -16
  191. package/src/mistral/index.ts +97 -48
  192. package/src/mistral/types.ts +13 -12
  193. package/src/openai/azure_openai.ts +35 -27
  194. package/src/openai/drivers.ts +9 -0
  195. package/src/openai/error-handling.test.ts +308 -113
  196. package/src/openai/index.ts +378 -248
  197. package/src/openai/openai.ts +6 -13
  198. package/src/openai/openai_compatible.ts +35 -25
  199. package/src/openai/openai_format.ts +90 -40
  200. package/src/replicate.ts +108 -86
  201. package/src/shared/claude-messages.test.ts +37 -0
  202. package/src/shared/claude-messages.ts +303 -97
  203. package/src/shared/claude-thinking.ts +6 -12
  204. package/src/shared/debug-prompt.ts +28 -0
  205. package/src/test-driver/TestErrorCompletionStream.ts +9 -10
  206. package/src/test-driver/TestValidationErrorCompletionStream.ts +9 -10
  207. package/src/test-driver/index.ts +43 -27
  208. package/src/test-driver/utils.ts +8 -8
  209. package/src/togetherai/index.test.ts +32 -0
  210. package/src/togetherai/index.ts +64 -128
  211. package/src/togetherai/interfaces.ts +5 -5
  212. package/src/vertexai/debug.ts +3 -3
  213. package/src/vertexai/embeddings/embed-legacy-multimodal.ts +211 -0
  214. package/src/vertexai/embeddings/embed.ts +206 -0
  215. package/src/vertexai/embeddings/embeddings.test.ts +497 -0
  216. package/src/vertexai/embeddings/source-utils.test.ts +54 -0
  217. package/src/vertexai/embeddings/source-utils.ts +29 -0
  218. package/src/vertexai/index.ts +331 -244
  219. package/src/vertexai/models/claude-error-handling.test.ts +83 -36
  220. package/src/vertexai/models/claude-streaming-spacing.test.ts +82 -75
  221. package/src/vertexai/models/claude.ts +55 -40
  222. package/src/vertexai/models/gemini-conversation-mutation.test.ts +65 -23
  223. package/src/vertexai/models/gemini-error-handling.test.ts +126 -10
  224. package/src/vertexai/models/gemini-orphaned-tool-result.test.ts +118 -0
  225. package/src/vertexai/models/gemini.ts +349 -172
  226. package/src/vertexai/models/imagen.ts +164 -100
  227. package/src/vertexai/models/llama.ts +70 -48
  228. package/src/vertexai/models.ts +36 -16
  229. package/src/watsonx/index.ts +101 -65
  230. package/src/watsonx/interfaces.ts +10 -15
  231. package/src/xai/index.ts +30 -30
  232. package/lib/cjs/adobe/firefly.js +0 -120
  233. package/lib/cjs/adobe/firefly.js.map +0 -1
  234. package/lib/cjs/anthropic/index.js +0 -64
  235. package/lib/cjs/anthropic/index.js.map +0 -1
  236. package/lib/cjs/azure/azure_foundry.js +0 -432
  237. package/lib/cjs/azure/azure_foundry.js.map +0 -1
  238. package/lib/cjs/bedrock/converse.js +0 -359
  239. package/lib/cjs/bedrock/converse.js.map +0 -1
  240. package/lib/cjs/bedrock/index.js +0 -1508
  241. package/lib/cjs/bedrock/index.js.map +0 -1
  242. package/lib/cjs/bedrock/nova-image-payload.js +0 -207
  243. package/lib/cjs/bedrock/nova-image-payload.js.map +0 -1
  244. package/lib/cjs/bedrock/payloads.js +0 -3
  245. package/lib/cjs/bedrock/s3.js +0 -107
  246. package/lib/cjs/bedrock/s3.js.map +0 -1
  247. package/lib/cjs/bedrock/twelvelabs.js +0 -87
  248. package/lib/cjs/bedrock/twelvelabs.js.map +0 -1
  249. package/lib/cjs/groq/index.js +0 -328
  250. package/lib/cjs/groq/index.js.map +0 -1
  251. package/lib/cjs/huggingface_ie.js +0 -201
  252. package/lib/cjs/huggingface_ie.js.map +0 -1
  253. package/lib/cjs/index.js +0 -32
  254. package/lib/cjs/index.js.map +0 -1
  255. package/lib/cjs/mistral/index.js +0 -176
  256. package/lib/cjs/mistral/index.js.map +0 -1
  257. package/lib/cjs/mistral/types.js +0 -83
  258. package/lib/cjs/mistral/types.js.map +0 -1
  259. package/lib/cjs/openai/azure_openai.js +0 -72
  260. package/lib/cjs/openai/azure_openai.js.map +0 -1
  261. package/lib/cjs/openai/index.js +0 -1135
  262. package/lib/cjs/openai/index.js.map +0 -1
  263. package/lib/cjs/openai/openai.js +0 -21
  264. package/lib/cjs/openai/openai.js.map +0 -1
  265. package/lib/cjs/openai/openai_compatible.js +0 -63
  266. package/lib/cjs/openai/openai_compatible.js.map +0 -1
  267. package/lib/cjs/openai/openai_format.js +0 -131
  268. package/lib/cjs/openai/openai_format.js.map +0 -1
  269. package/lib/cjs/package.json +0 -3
  270. package/lib/cjs/replicate.js +0 -275
  271. package/lib/cjs/replicate.js.map +0 -1
  272. package/lib/cjs/shared/claude-messages.js +0 -737
  273. package/lib/cjs/shared/claude-messages.js.map +0 -1
  274. package/lib/cjs/shared/claude-thinking.js +0 -60
  275. package/lib/cjs/shared/claude-thinking.js.map +0 -1
  276. package/lib/cjs/test-driver/TestErrorCompletionStream.js +0 -20
  277. package/lib/cjs/test-driver/TestErrorCompletionStream.js.map +0 -1
  278. package/lib/cjs/test-driver/TestValidationErrorCompletionStream.js +0 -24
  279. package/lib/cjs/test-driver/TestValidationErrorCompletionStream.js.map +0 -1
  280. package/lib/cjs/test-driver/index.js +0 -109
  281. package/lib/cjs/test-driver/index.js.map +0 -1
  282. package/lib/cjs/test-driver/utils.js +0 -30
  283. package/lib/cjs/test-driver/utils.js.map +0 -1
  284. package/lib/cjs/togetherai/index.js +0 -126
  285. package/lib/cjs/togetherai/index.js.map +0 -1
  286. package/lib/cjs/togetherai/interfaces.js +0 -3
  287. package/lib/cjs/togetherai/interfaces.js.map +0 -1
  288. package/lib/cjs/vertexai/debug.js +0 -12
  289. package/lib/cjs/vertexai/debug.js.map +0 -1
  290. package/lib/cjs/vertexai/embeddings/embeddings-image.js +0 -27
  291. package/lib/cjs/vertexai/embeddings/embeddings-image.js.map +0 -1
  292. package/lib/cjs/vertexai/embeddings/embeddings-text.js +0 -23
  293. package/lib/cjs/vertexai/embeddings/embeddings-text.js.map +0 -1
  294. package/lib/cjs/vertexai/index.js +0 -644
  295. package/lib/cjs/vertexai/index.js.map +0 -1
  296. package/lib/cjs/vertexai/models/claude.js +0 -72
  297. package/lib/cjs/vertexai/models/claude.js.map +0 -1
  298. package/lib/cjs/vertexai/models/gemini.js +0 -864
  299. package/lib/cjs/vertexai/models/gemini.js.map +0 -1
  300. package/lib/cjs/vertexai/models/imagen.js +0 -303
  301. package/lib/cjs/vertexai/models/imagen.js.map +0 -1
  302. package/lib/cjs/vertexai/models/llama.js +0 -183
  303. package/lib/cjs/vertexai/models/llama.js.map +0 -1
  304. package/lib/cjs/vertexai/models.js +0 -35
  305. package/lib/cjs/vertexai/models.js.map +0 -1
  306. package/lib/cjs/watsonx/index.js +0 -161
  307. package/lib/cjs/watsonx/index.js.map +0 -1
  308. package/lib/cjs/watsonx/interfaces.js +0 -3
  309. package/lib/cjs/xai/index.js +0 -65
  310. package/lib/cjs/xai/index.js.map +0 -1
  311. package/lib/esm/adobe/firefly.js +0 -116
  312. package/lib/esm/adobe/firefly.js.map +0 -1
  313. package/lib/esm/anthropic/index.js.map +0 -1
  314. package/lib/esm/azure/azure_foundry.js.map +0 -1
  315. package/lib/esm/bedrock/converse.js.map +0 -1
  316. package/lib/esm/bedrock/index.js.map +0 -1
  317. package/lib/esm/bedrock/nova-image-payload.js.map +0 -1
  318. package/lib/esm/bedrock/payloads.js.map +0 -1
  319. package/lib/esm/bedrock/s3.js.map +0 -1
  320. package/lib/esm/bedrock/twelvelabs.js.map +0 -1
  321. package/lib/esm/groq/index.js.map +0 -1
  322. package/lib/esm/huggingface_ie.js.map +0 -1
  323. package/lib/esm/index.js +0 -16
  324. package/lib/esm/index.js.map +0 -1
  325. package/lib/esm/mistral/index.js.map +0 -1
  326. package/lib/esm/mistral/types.js.map +0 -1
  327. package/lib/esm/openai/azure_openai.js.map +0 -1
  328. package/lib/esm/openai/index.js.map +0 -1
  329. package/lib/esm/openai/openai.js +0 -14
  330. package/lib/esm/openai/openai.js.map +0 -1
  331. package/lib/esm/openai/openai_compatible.js.map +0 -1
  332. package/lib/esm/openai/openai_format.js.map +0 -1
  333. package/lib/esm/replicate.js.map +0 -1
  334. package/lib/esm/shared/claude-messages.js.map +0 -1
  335. package/lib/esm/shared/claude-thinking.js.map +0 -1
  336. package/lib/esm/test-driver/TestErrorCompletionStream.js +0 -16
  337. package/lib/esm/test-driver/TestErrorCompletionStream.js.map +0 -1
  338. package/lib/esm/test-driver/TestValidationErrorCompletionStream.js.map +0 -1
  339. package/lib/esm/test-driver/index.js.map +0 -1
  340. package/lib/esm/test-driver/utils.js.map +0 -1
  341. package/lib/esm/togetherai/index.js +0 -122
  342. package/lib/esm/togetherai/index.js.map +0 -1
  343. package/lib/esm/togetherai/interfaces.js.map +0 -1
  344. package/lib/esm/vertexai/debug.js.map +0 -1
  345. package/lib/esm/vertexai/embeddings/embeddings-image.js +0 -24
  346. package/lib/esm/vertexai/embeddings/embeddings-image.js.map +0 -1
  347. package/lib/esm/vertexai/embeddings/embeddings-text.js +0 -20
  348. package/lib/esm/vertexai/embeddings/embeddings-text.js.map +0 -1
  349. package/lib/esm/vertexai/index.js.map +0 -1
  350. package/lib/esm/vertexai/models/claude.js.map +0 -1
  351. package/lib/esm/vertexai/models/gemini.js.map +0 -1
  352. package/lib/esm/vertexai/models/imagen.js.map +0 -1
  353. package/lib/esm/vertexai/models/llama.js.map +0 -1
  354. package/lib/esm/vertexai/models.js.map +0 -1
  355. package/lib/esm/watsonx/index.js.map +0 -1
  356. package/lib/esm/xai/index.js.map +0 -1
  357. package/lib/types/adobe/firefly.d.ts.map +0 -1
  358. package/lib/types/anthropic/index.d.ts.map +0 -1
  359. package/lib/types/azure/azure_foundry.d.ts.map +0 -1
  360. package/lib/types/bedrock/converse.d.ts.map +0 -1
  361. package/lib/types/bedrock/index.d.ts.map +0 -1
  362. package/lib/types/bedrock/nova-image-payload.d.ts.map +0 -1
  363. package/lib/types/bedrock/payloads.d.ts.map +0 -1
  364. package/lib/types/bedrock/s3.d.ts.map +0 -1
  365. package/lib/types/bedrock/twelvelabs.d.ts.map +0 -1
  366. package/lib/types/groq/index.d.ts.map +0 -1
  367. package/lib/types/huggingface_ie.d.ts.map +0 -1
  368. package/lib/types/index.d.ts +0 -16
  369. package/lib/types/index.d.ts.map +0 -1
  370. package/lib/types/mistral/index.d.ts.map +0 -1
  371. package/lib/types/mistral/types.d.ts.map +0 -1
  372. package/lib/types/openai/azure_openai.d.ts.map +0 -1
  373. package/lib/types/openai/index.d.ts.map +0 -1
  374. package/lib/types/openai/openai.d.ts.map +0 -1
  375. package/lib/types/openai/openai_compatible.d.ts.map +0 -1
  376. package/lib/types/openai/openai_format.d.ts.map +0 -1
  377. package/lib/types/replicate.d.ts.map +0 -1
  378. package/lib/types/shared/claude-messages.d.ts.map +0 -1
  379. package/lib/types/shared/claude-thinking.d.ts.map +0 -1
  380. package/lib/types/test-driver/TestErrorCompletionStream.d.ts.map +0 -1
  381. package/lib/types/test-driver/TestValidationErrorCompletionStream.d.ts.map +0 -1
  382. package/lib/types/test-driver/index.d.ts.map +0 -1
  383. package/lib/types/test-driver/utils.d.ts.map +0 -1
  384. package/lib/types/togetherai/index.d.ts +0 -23
  385. package/lib/types/togetherai/index.d.ts.map +0 -1
  386. package/lib/types/togetherai/interfaces.d.ts.map +0 -1
  387. package/lib/types/vertexai/debug.d.ts +0 -2
  388. package/lib/types/vertexai/debug.d.ts.map +0 -1
  389. package/lib/types/vertexai/embeddings/embeddings-image.d.ts +0 -11
  390. package/lib/types/vertexai/embeddings/embeddings-image.d.ts.map +0 -1
  391. package/lib/types/vertexai/embeddings/embeddings-text.d.ts +0 -10
  392. package/lib/types/vertexai/embeddings/embeddings-text.d.ts.map +0 -1
  393. package/lib/types/vertexai/index.d.ts.map +0 -1
  394. package/lib/types/vertexai/models/claude.d.ts.map +0 -1
  395. package/lib/types/vertexai/models/gemini.d.ts.map +0 -1
  396. package/lib/types/vertexai/models/imagen.d.ts.map +0 -1
  397. package/lib/types/vertexai/models/llama.d.ts.map +0 -1
  398. package/lib/types/vertexai/models.d.ts +0 -20
  399. package/lib/types/vertexai/models.d.ts.map +0 -1
  400. package/lib/types/watsonx/index.d.ts.map +0 -1
  401. package/lib/types/watsonx/interfaces.d.ts.map +0 -1
  402. package/lib/types/xai/index.d.ts.map +0 -1
  403. package/src/vertexai/embeddings/embeddings-image.ts +0 -52
  404. package/src/vertexai/embeddings/embeddings-text.ts +0 -54
  405. /package/lib/{esm/bedrock → bedrock}/payloads.js +0 -0
  406. /package/lib/{esm/mistral → mistral}/types.js +0 -0
  407. /package/lib/{esm/togetherai → togetherai}/interfaces.js +0 -0
  408. /package/lib/{types/watsonx → watsonx}/interfaces.d.ts +0 -0
  409. /package/lib/{esm/watsonx → watsonx}/interfaces.js +0 -0
@@ -1,46 +1,41 @@
1
- import { ExecutionOptions, NovaCanvasOptions } from "@llumiverse/core";
2
- import { NovaMessage, NovaMessagesPrompt } from "@llumiverse/core/formatters";
1
+ import type { ExecutionOptions, NovaCanvasOptions } from '@llumiverse/core';
2
+ import type { NovaMessage, NovaMessagesPrompt } from '@llumiverse/core/formatters';
3
3
 
4
4
  function getFirstImageFromPrompt(prompt: NovaMessage[]) {
5
-
6
- const msgImage = prompt.find(m => m.content.find(c => c.image));
5
+ const msgImage = prompt.find((m) => m.content.find((c) => c.image));
7
6
  if (!msgImage) {
8
7
  return undefined;
9
8
  }
10
9
 
11
- return msgImage.content.find(c => c.image)?.image;
10
+ return msgImage.content.find((c) => c.image)?.image;
12
11
  }
13
12
 
14
- //@ts-ignore
15
- function getAllImagesFromPrompt(prompt: NovaMessage[]) {
16
-
17
- const contentMsg = prompt.filter(m => m.content).map(m => m.content).flat();
18
- const imgParts = contentMsg.filter(c => c.image);
19
- if (!imgParts?.length) {
20
- return undefined;
21
- }
22
-
23
- const images = imgParts.map(i => i.image).filter(i => i?.source?.bytes).map(i => i!.source.bytes);
24
- return images;
13
+ function getAllImagesFromPrompt(prompt: NovaMessage[]): string[] | undefined {
14
+ const contentMsg = prompt.filter((m) => m.content).flatMap((m) => m.content);
15
+ const images = contentMsg.map((c) => c.image?.source?.bytes).filter((b): b is string => b !== undefined);
16
+ return images.length > 0 ? images : undefined;
25
17
  }
26
18
 
27
- async function textToImagePayload(prompt: NovaMessagesPrompt, options: ExecutionOptions): Promise<NovaTextToImagePayload> {
19
+ async function textToImagePayload(
20
+ prompt: NovaMessagesPrompt,
21
+ options: ExecutionOptions,
22
+ ): Promise<NovaTextToImagePayload> {
28
23
  const modelOptions = options.model_options as NovaCanvasOptions;
29
24
 
30
- const textMessages = prompt.messages.map(m => m.content.map(c => c.text)).flat();
31
- let text = textMessages.join("\n\n");
32
- text += prompt.system ? "\n\n\nIMPORTANT: " + prompt.system?.map(m => m.text).join("\n\n") : '';
25
+ const textMessages = prompt.messages.flatMap((m) => m.content.map((c) => c.text));
26
+ let text = textMessages.join('\n\n');
27
+ text += prompt.system ? `\n\n\nIMPORTANT: ${prompt.system?.map((m) => m.text).join('\n\n')}` : '';
33
28
 
34
29
  const conditionImage = (conditionImage: boolean) => {
35
30
  const img = getFirstImageFromPrompt(prompt.messages);
36
31
  if (img && conditionImage) {
37
- return img
32
+ return img;
38
33
  }
39
34
  return undefined;
40
- }
35
+ };
41
36
 
42
37
  const payload: NovaTextToImagePayload = {
43
- taskType: NovaImageGenerationTaskType.TEXT_IMAGE, // Always TEXT_IMAGE, as TEXT_IMAGE_WITH_IMAGE_CONDITIONING is only an internal marker.
38
+ taskType: NovaImageGenerationTaskType.TEXT_IMAGE, // Always TEXT_IMAGE, as TEXT_IMAGE_WITH_IMAGE_CONDITIONING is only an internal marker.
44
39
  imageGenerationConfig: {
45
40
  quality: modelOptions?.quality,
46
41
  width: modelOptions.width,
@@ -51,20 +46,23 @@ async function textToImagePayload(prompt: NovaMessagesPrompt, options: Execution
51
46
  },
52
47
  textToImageParams: {
53
48
  text: text,
54
- conditionImage: conditionImage(modelOptions?.controlMode ? true : false)?.source.bytes,
49
+ conditionImage: conditionImage(!!modelOptions?.controlMode)?.source.bytes,
55
50
  controlMode: modelOptions?.controlMode,
56
51
  controlStrength: modelOptions?.controlStrength,
57
- negativeText: prompt.negative
58
- }
59
- }
52
+ negativeText: prompt.negative,
53
+ },
54
+ };
60
55
 
61
56
  return payload;
62
57
  }
63
58
 
64
- async function imageVariationPayload(prompt: NovaMessagesPrompt, options: ExecutionOptions): Promise<NovaImageVariationPayload> {
59
+ async function imageVariationPayload(
60
+ prompt: NovaMessagesPrompt,
61
+ options: ExecutionOptions,
62
+ ): Promise<NovaImageVariationPayload> {
65
63
  const modelOptions = options.model_options as NovaCanvasOptions;
66
64
 
67
- const text = prompt.messages.map(m => m.content).join("\n\n");
65
+ const text = prompt.messages.map((m) => m.content).join('\n\n');
68
66
  const images = getAllImagesFromPrompt(prompt.messages);
69
67
 
70
68
  const payload: NovaImageVariationPayload = {
@@ -82,26 +80,29 @@ async function imageVariationPayload(prompt: NovaMessagesPrompt, options: Execut
82
80
  text: text,
83
81
  negativeText: prompt.negative,
84
82
  similarityStrength: modelOptions?.similarityStrength,
85
- }
86
- }
83
+ },
84
+ };
87
85
 
88
86
  return payload;
89
87
  }
90
88
 
91
- async function colorGuidedGenerationPayload(prompt: NovaMessagesPrompt, options: ExecutionOptions): Promise<NovaColorGuidedGenerationPayload> {
89
+ async function colorGuidedGenerationPayload(
90
+ prompt: NovaMessagesPrompt,
91
+ options: ExecutionOptions,
92
+ ): Promise<NovaColorGuidedGenerationPayload> {
92
93
  const modelOptions = options.model_options as NovaCanvasOptions;
93
94
 
94
- const textMessages = prompt.messages.map(m => m.content.map(c => c.text)).flat();
95
- let text = textMessages.join("\n\n");
96
- text += prompt.system ? "\n\n\nIMPORTANT: " + prompt.system?.map(m => m.text).join("\n\n") : '';
95
+ const textMessages = prompt.messages.flatMap((m) => m.content.map((c) => c.text));
96
+ let text = textMessages.join('\n\n');
97
+ text += prompt.system ? `\n\n\nIMPORTANT: ${prompt.system?.map((m) => m.text).join('\n\n')}` : '';
97
98
 
98
99
  const conditionImage = (conditionImage: boolean) => {
99
100
  const img = getFirstImageFromPrompt(prompt.messages);
100
101
  if (img && conditionImage) {
101
- return img
102
+ return img;
102
103
  }
103
104
  return undefined;
104
- }
105
+ };
105
106
 
106
107
  const payload: NovaColorGuidedGenerationPayload = {
107
108
  taskType: NovaImageGenerationTaskType.COLOR_GUIDED_GENERATION,
@@ -116,38 +117,40 @@ async function colorGuidedGenerationPayload(prompt: NovaMessagesPrompt, options:
116
117
  colorGuidedGenerationParams: {
117
118
  colors: modelOptions.colors ?? [],
118
119
  text: text,
119
- referenceImage: conditionImage(modelOptions?.controlMode ? true : false)?.source.bytes,
120
- negativeText: prompt.negative
121
- }
122
- }
120
+ referenceImage: conditionImage(!!modelOptions?.controlMode)?.source.bytes,
121
+ negativeText: prompt.negative,
122
+ },
123
+ };
123
124
 
124
125
  return payload;
125
126
  }
126
127
 
127
128
  async function backgroundRemovalPayload(prompt: NovaMessagesPrompt): Promise<NovaBackgroundRemovalPayload> {
128
-
129
129
  const image = getFirstImageFromPrompt(prompt.messages);
130
130
  if (!image?.source.bytes) {
131
- throw new Error("No image found in prompt");
131
+ throw new Error('No image found in prompt');
132
132
  }
133
133
 
134
134
  const payload: NovaBackgroundRemovalPayload = {
135
135
  taskType: NovaImageGenerationTaskType.BACKGROUND_REMOVAL,
136
136
  backgroundRemovalParams: {
137
- image: image.source.bytes
138
- }
139
- }
140
- console.log(payload)
137
+ image: image.source.bytes,
138
+ },
139
+ };
140
+ console.log(payload);
141
141
 
142
142
  return payload;
143
143
  }
144
144
 
145
- async function inpaintingPayload(prompt: NovaMessagesPrompt, options: ExecutionOptions): Promise<NovaInpaintingPayload> {
145
+ async function inpaintingPayload(
146
+ prompt: NovaMessagesPrompt,
147
+ options: ExecutionOptions,
148
+ ): Promise<NovaInpaintingPayload> {
146
149
  const modelOptions = options.model_options as NovaCanvasOptions;
147
150
 
148
151
  const images = getAllImagesFromPrompt(prompt.messages);
149
152
  if (!images?.length || images.length < 2) {
150
- throw new Error("2 images are required for inpainting");
153
+ throw new Error('2 images are required for inpainting');
151
154
  }
152
155
  const sourceImage = images[0];
153
156
  const maskImage = images[1];
@@ -165,20 +168,23 @@ async function inpaintingPayload(prompt: NovaMessagesPrompt, options: ExecutionO
165
168
  inPaintingParams: {
166
169
  image: sourceImage,
167
170
  maskImage: maskImage,
168
- text: prompt.messages.map(m => m.content.map(c => c.text)).flat().join("\n\n"),
169
- negativeText: prompt.negative
170
- }
171
- }
171
+ text: prompt.messages.flatMap((m) => m.content.map((c) => c.text)).join('\n\n'),
172
+ negativeText: prompt.negative,
173
+ },
174
+ };
172
175
 
173
176
  return payload;
174
177
  }
175
178
 
176
- async function outpaintingPayload(prompt: NovaMessagesPrompt, options: ExecutionOptions): Promise<NovaOutpaintingPayload> {
179
+ async function outpaintingPayload(
180
+ prompt: NovaMessagesPrompt,
181
+ options: ExecutionOptions,
182
+ ): Promise<NovaOutpaintingPayload> {
177
183
  const modelOptions = options.model_options as NovaCanvasOptions;
178
184
 
179
185
  const images = getAllImagesFromPrompt(prompt.messages);
180
186
  if (!images?.length || images.length < 2) {
181
- throw new Error("2 images are required for outpainting");
187
+ throw new Error('2 images are required for outpainting');
182
188
  }
183
189
  const sourceImage = images[0];
184
190
  const maskImage = images[1];
@@ -196,17 +202,20 @@ async function outpaintingPayload(prompt: NovaMessagesPrompt, options: Execution
196
202
  outPaintingParams: {
197
203
  image: sourceImage,
198
204
  maskImage: maskImage,
199
- text: prompt.messages.map(m => m.content.map(c => c.text)).flat().join("\n\n"),
205
+ text: prompt.messages.flatMap((m) => m.content.map((c) => c.text)).join('\n\n'),
200
206
  negativeText: prompt.negative,
201
- outPaintingMode: modelOptions?.outPaintingMode ?? "DEFAULT"
202
- }
203
- }
207
+ outPaintingMode: modelOptions?.outPaintingMode ?? 'DEFAULT',
208
+ },
209
+ };
204
210
 
205
211
  return payload;
206
212
  }
207
213
 
208
- export function formatNovaImageGenerationPayload(taskType: string, prompt: NovaMessagesPrompt, options: ExecutionOptions) {
209
-
214
+ export function formatNovaImageGenerationPayload(
215
+ taskType: string,
216
+ prompt: NovaMessagesPrompt,
217
+ options: ExecutionOptions,
218
+ ) {
210
219
  switch (taskType) {
211
220
  case NovaImageGenerationTaskType.TEXT_IMAGE:
212
221
  return textToImagePayload(prompt, options);
@@ -223,9 +232,8 @@ export function formatNovaImageGenerationPayload(taskType: string, prompt: NovaM
223
232
  case NovaImageGenerationTaskType.BACKGROUND_REMOVAL:
224
233
  return backgroundRemovalPayload(prompt);
225
234
  default:
226
- throw new Error("Task type not supported");
235
+ throw new Error('Task type not supported');
227
236
  }
228
-
229
237
  }
230
238
 
231
239
  export interface InvokeModelPayloadBase {
@@ -233,7 +241,7 @@ export interface InvokeModelPayloadBase {
233
241
  imageGenerationConfig: {
234
242
  width?: number;
235
243
  height?: number;
236
- quality?: "standard" | "premium";
244
+ quality?: 'standard' | 'premium';
237
245
  cfgScale?: number;
238
246
  seed?: number;
239
247
  numberOfImages?: number;
@@ -243,21 +251,20 @@ export interface InvokeModelPayloadBase {
243
251
  export interface NovaTextToImagePayload extends InvokeModelPayloadBase {
244
252
  textToImageParams: {
245
253
  conditionImage?: string;
246
- controlMode?: "CANNY_EDGE" | "SEGMENTATION";
254
+ controlMode?: 'CANNY_EDGE' | 'SEGMENTATION';
247
255
  controlStrength?: number;
248
256
  text: string;
249
257
  negativeText?: string;
250
258
  };
251
259
  }
252
260
 
253
-
254
261
  export interface NovaImageVariationPayload extends InvokeModelPayloadBase {
255
262
  imageVariationParams: {
256
- images: string[] //(list of Base64 encoded images),
257
- similarityStrength?: number,
258
- text?: string,
259
- negativeText?: string
260
- }
263
+ images: string[]; //(list of Base64 encoded images),
264
+ similarityStrength?: number;
265
+ text?: string;
266
+ negativeText?: string;
267
+ };
261
268
  }
262
269
 
263
270
  export interface NovaColorGuidedGenerationPayload extends InvokeModelPayloadBase {
@@ -266,43 +273,43 @@ export interface NovaColorGuidedGenerationPayload extends InvokeModelPayloadBase
266
273
  text: string;
267
274
  referenceImage?: string;
268
275
  negativeText?: string;
269
- }
276
+ };
270
277
  }
271
278
 
272
279
  export interface NovaInpaintingPayload extends InvokeModelPayloadBase {
273
280
  inPaintingParams: {
274
281
  image: string; //(Base64 encoded image),
275
282
  maskImage?: string; //(Base64 encoded image),
276
- maskPrompt?: string,
277
- negativeText?: string,
278
- text?: string,
279
- }
283
+ maskPrompt?: string;
284
+ negativeText?: string;
285
+ text?: string;
286
+ };
280
287
  }
281
288
 
282
289
  export interface NovaOutpaintingPayload extends InvokeModelPayloadBase {
283
290
  outPaintingParams: {
284
291
  image: string; //(Base64 encoded image),
285
292
  maskImage?: string; //(Base64 encoded image),
286
- maskPrompt?: string,
287
- negativeText?: string,
288
- text?: string,
289
- outPaintingMode: "DEFAULT" | "PRECISE";
290
- }
293
+ maskPrompt?: string;
294
+ negativeText?: string;
295
+ text?: string;
296
+ outPaintingMode: 'DEFAULT' | 'PRECISE';
297
+ };
291
298
  }
292
299
 
293
300
  export interface NovaBackgroundRemovalPayload {
294
301
  taskType: NovaImageGenerationTaskType.BACKGROUND_REMOVAL;
295
302
  backgroundRemovalParams: {
296
- image: string //(Base64 encoded image),
297
- }
303
+ image: string; //(Base64 encoded image),
304
+ };
298
305
  }
299
306
 
300
307
  export enum NovaImageGenerationTaskType {
301
- TEXT_IMAGE = "TEXT_IMAGE",
302
- TEXT_IMAGE_WITH_IMAGE_CONDITIONING = "TEXT_IMAGE_WITH_IMAGE_CONDITIONING",
303
- COLOR_GUIDED_GENERATION = "COLOR_GUIDED_GENERATION",
304
- IMAGE_VARIATION = "IMAGE_VARIATION",
305
- INPAINTING = "INPAINTING",
306
- OUTPAINTING = "OUTPAINTING",
307
- BACKGROUND_REMOVAL = "BACKGROUND_REMOVAL",
308
- }
308
+ TEXT_IMAGE = 'TEXT_IMAGE',
309
+ TEXT_IMAGE_WITH_IMAGE_CONDITIONING = 'TEXT_IMAGE_WITH_IMAGE_CONDITIONING',
310
+ COLOR_GUIDED_GENERATION = 'COLOR_GUIDED_GENERATION',
311
+ IMAGE_VARIATION = 'IMAGE_VARIATION',
312
+ INPAINTING = 'INPAINTING',
313
+ OUTPAINTING = 'OUTPAINTING',
314
+ BACKGROUND_REMOVAL = 'BACKGROUND_REMOVAL',
315
+ }
@@ -1,13 +1,13 @@
1
- import { NovaMessagesPrompt } from "@llumiverse/core/formatters";
1
+ import type { NovaMessagesPrompt } from '@llumiverse/core/formatters';
2
2
 
3
3
  //Docs at: https://docs.aws.amazon.com/nova/latest/userguide/complete-request-schema.html
4
4
  export interface NovaPayload extends NovaMessagesPrompt {
5
- schemaVersion: string,
5
+ schemaVersion: string;
6
6
  inferenceConfig?: {
7
- max_new_tokens?: number,
8
- temperature?: number,
9
- top_p?: number,
10
- top_k?: number,
11
- stopSequences?: [string]
12
- }
13
- }
7
+ max_new_tokens?: number;
8
+ temperature?: number;
9
+ top_p?: number;
10
+ top_k?: number;
11
+ stopSequences?: [string];
12
+ };
13
+ }
@@ -0,0 +1,39 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { isAmazonS3Hostname, parseS3UrlToUri } from './s3.js';
3
+
4
+ describe('isAmazonS3Hostname', () => {
5
+ it('accepts supported Amazon S3 hostnames', () => {
6
+ expect(isAmazonS3Hostname('s3.amazonaws.com')).toBe(true);
7
+ expect(isAmazonS3Hostname('s3.us-east-1.amazonaws.com')).toBe(true);
8
+ expect(isAmazonS3Hostname('s3.dualstack.us-east-1.amazonaws.com')).toBe(true);
9
+ expect(isAmazonS3Hostname('my-bucket.s3.amazonaws.com')).toBe(true);
10
+ expect(isAmazonS3Hostname('my-bucket.s3.us-east-1.amazonaws.com')).toBe(true);
11
+ expect(isAmazonS3Hostname('my-bucket.s3.dualstack.us-east-1.amazonaws.com')).toBe(true);
12
+ });
13
+
14
+ it('rejects hostnames that only contain amazonaws.com as a substring', () => {
15
+ expect(isAmazonS3Hostname('s3.amazonaws.com.example.com')).toBe(false);
16
+ expect(isAmazonS3Hostname('example-s3.amazonaws.com')).toBe(false);
17
+ expect(isAmazonS3Hostname('bucket.s3.amazonaws.com.evil.test')).toBe(false);
18
+ });
19
+ });
20
+
21
+ describe('parseS3UrlToUri', () => {
22
+ it('converts virtual-hosted style S3 URLs', () => {
23
+ expect(parseS3UrlToUri(new URL('https://my-bucket.s3.us-east-1.amazonaws.com/folder/video.mp4'))).toBe(
24
+ 's3://my-bucket/folder/video.mp4',
25
+ );
26
+ });
27
+
28
+ it('converts path-style S3 URLs', () => {
29
+ expect(parseS3UrlToUri(new URL('https://s3.us-east-1.amazonaws.com/my-bucket/folder/video.mp4'))).toBe(
30
+ 's3://my-bucket/folder/video.mp4',
31
+ );
32
+ });
33
+
34
+ it('rejects spoofed S3-looking URLs', () => {
35
+ expect(() => parseS3UrlToUri(new URL('https://bucket.s3.amazonaws.com.evil.test/video.mp4'))).toThrow(
36
+ 'Unable to determine bucket name from URL',
37
+ );
38
+ });
39
+ });
package/src/bedrock/s3.ts CHANGED
@@ -1,12 +1,18 @@
1
- import { CreateBucketCommand, HeadBucketCommand, S3Client } from "@aws-sdk/client-s3";
2
- import { Progress, Upload } from "@aws-sdk/lib-storage";
1
+ import { CreateBucketCommand, HeadBucketCommand, type S3Client } from '@aws-sdk/client-s3';
2
+ import { type Progress, Upload } from '@aws-sdk/lib-storage';
3
+
4
+ const S3_AMAZONAWS_HOSTNAME_RE = /^(?:s3(?:\.[a-z0-9-]+)*|.+\.s3(?:\.[a-z0-9-]+)*)\.amazonaws\.com$/;
5
+
6
+ export function isAmazonS3Hostname(hostname: string): boolean {
7
+ return S3_AMAZONAWS_HOSTNAME_RE.test(hostname.toLowerCase());
8
+ }
3
9
 
4
10
  export async function doesBucketExist(s3: S3Client, bucketName: string): Promise<boolean> {
5
11
  try {
6
12
  await s3.send(new HeadBucketCommand({ Bucket: bucketName }));
7
13
  return true;
8
- } catch (err: any) {
9
- if (err.name === 'NotFound') {
14
+ } catch (err: unknown) {
15
+ if (err && typeof err === 'object' && (err as { name?: unknown }).name === 'NotFound') {
10
16
  return false;
11
17
  }
12
18
  throw err;
@@ -14,12 +20,13 @@ export async function doesBucketExist(s3: S3Client, bucketName: string): Promise
14
20
  }
15
21
 
16
22
  export function createBucket(s3: S3Client, bucketName: string) {
17
- return s3.send(new CreateBucketCommand({
18
- Bucket: bucketName
19
- }));
23
+ return s3.send(
24
+ new CreateBucketCommand({
25
+ Bucket: bucketName,
26
+ }),
27
+ );
20
28
  }
21
29
 
22
-
23
30
  export async function tryCreateBucket(s3: S3Client, bucketName: string) {
24
31
  const exists = await doesBucketExist(s3, bucketName);
25
32
  if (!exists) {
@@ -27,19 +34,23 @@ export async function tryCreateBucket(s3: S3Client, bucketName: string) {
27
34
  }
28
35
  }
29
36
 
30
-
31
- export async function uploadFile(s3: S3Client, source: ReadableStream, bucketName: string, file: string, onProgress?: (progress: Progress) => void) {
32
-
37
+ export async function uploadFile(
38
+ s3: S3Client,
39
+ source: ReadableStream,
40
+ bucketName: string,
41
+ file: string,
42
+ onProgress?: (progress: Progress) => void,
43
+ ) {
33
44
  const upload = new Upload({
34
45
  client: s3,
35
46
  params: {
36
47
  Bucket: bucketName,
37
48
  Key: file,
38
49
  Body: source,
39
- }
50
+ },
40
51
  });
41
52
 
42
- onProgress && upload.on("httpUploadProgress", onProgress);
53
+ if (onProgress) upload.on('httpUploadProgress', onProgress);
43
54
 
44
55
  const result = await upload.done();
45
56
  return result;
@@ -47,20 +58,25 @@ export async function uploadFile(s3: S3Client, source: ReadableStream, bucketNam
47
58
 
48
59
  /**
49
60
  * Create the bucket if not already exists and then upload the file.
50
- * @param s3
51
- * @param source
52
- * @param bucketName
53
- * @param file
54
- * @param onProgress
55
- * @returns
61
+ * @param s3
62
+ * @param source
63
+ * @param bucketName
64
+ * @param file
65
+ * @param onProgress
66
+ * @returns
56
67
  */
57
- export async function forceUploadFile(s3: S3Client, source: ReadableStream, bucketName: string, file: string, onProgress?: (progress: Progress) => void) {
68
+ export async function forceUploadFile(
69
+ s3: S3Client,
70
+ source: ReadableStream,
71
+ bucketName: string,
72
+ file: string,
73
+ onProgress?: (progress: Progress) => void,
74
+ ) {
58
75
  // make sure the bucket exists
59
76
  await tryCreateBucket(s3, bucketName);
60
77
  return uploadFile(s3, source, bucketName, file, onProgress);
61
78
  }
62
79
 
63
-
64
80
  /**
65
81
  * Parse an S3 HTTPS URL into an S3 URI format
66
82
  * s3Url - The S3 HTTPS URL (e.g., https://bucket.s3.region.amazonaws.com/key)
@@ -71,25 +87,28 @@ export function parseS3UrlToUri(s3Url: URL) {
71
87
  const url = new URL(s3Url);
72
88
 
73
89
  // Extract the hostname which contains the bucket and S3 endpoint
74
- const hostname = url.hostname;
90
+ const hostname = url.hostname.toLowerCase();
91
+
92
+ if (!isAmazonS3Hostname(hostname)) {
93
+ throw new Error('Unable to determine bucket name from URL');
94
+ }
75
95
 
76
96
  // Parse the hostname to extract the bucket name
77
- let bucketName;
78
- if (hostname.endsWith('.amazonaws.com')) {
79
- if (hostname.includes('.s3.')) {
80
- // Format: bucket-name.s3.region.amazonaws.com
81
- bucketName = hostname.split('.s3.')[0];
82
- } else if (hostname.startsWith('s3.')) {
83
- // Format: s3.region.amazonaws.com/bucket-name
84
- // In this case, the bucket is actually in the first segment of the pathname
85
- bucketName = url.pathname.split('/')[1];
86
- // Adjust the pathname to remove the bucket name
87
- const pathParts = url.pathname.split('/').slice(2);
88
- url.pathname = '/' + pathParts.join('/');
89
- } else {
90
- throw new Error('Unable to determine bucket name from URL');
91
- }
97
+ let bucketName: string | undefined;
98
+ const virtualHostedMatch = hostname.match(/^(.+)\.s3(?:\.[a-z0-9-]+)*\.amazonaws\.com$/);
99
+ if (virtualHostedMatch) {
100
+ // Format: bucket-name.s3.region.amazonaws.com
101
+ bucketName = virtualHostedMatch[1];
92
102
  } else {
103
+ // Format: s3.region.amazonaws.com/bucket-name
104
+ // In this case, the bucket is actually in the first segment of the pathname
105
+ bucketName = url.pathname.split('/')[1];
106
+ // Adjust the pathname to remove the bucket name
107
+ const pathParts = url.pathname.split('/').slice(2);
108
+ url.pathname = `/${pathParts.join('/')}`;
109
+ }
110
+
111
+ if (!bucketName) {
93
112
  throw new Error('Unable to determine bucket name from URL');
94
113
  }
95
114
 
@@ -106,4 +125,4 @@ export function parseS3UrlToUri(s3Url: URL) {
106
125
  console.error('Error parsing S3 URL:', error);
107
126
  throw error;
108
127
  }
109
- }
128
+ }