@fragno-dev/upload 0.1.1 → 0.1.3

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 (301) hide show
  1. package/README.md +148 -12
  2. package/dist/browser/client/clients.js +17 -9
  3. package/dist/browser/client/clients.js.map +1 -1
  4. package/dist/browser/client/helpers.d.ts +15 -6
  5. package/dist/browser/client/helpers.d.ts.map +1 -1
  6. package/dist/browser/client/helpers.js +176 -30
  7. package/dist/browser/client/helpers.js.map +1 -1
  8. package/dist/browser/client/node_modules/.pnpm/{@nanostores_query@0.3.4_nanostores@1.1.0 → @nanostores_query@0.3.4_nanostores@1.2.0}/node_modules/@nanostores/query/dist/nanoquery.js +6 -6
  9. package/dist/browser/client/node_modules/.pnpm/{@nanostores_query@0.3.4_nanostores@1.1.0 → @nanostores_query@0.3.4_nanostores@1.2.0}/node_modules/@nanostores/query/dist/nanoquery.js.map +1 -1
  10. package/dist/browser/client/node_modules/.pnpm/{@nanostores_solid@1.1.1_nanostores@1.1.0_solid-js@1.9.10 → @nanostores_solid@1.1.1_nanostores@1.2.0_solid-js@1.9.10}/node_modules/@nanostores/solid/dist/index.js +2 -2
  11. package/dist/browser/client/node_modules/.pnpm/{@nanostores_solid@1.1.1_nanostores@1.1.0_solid-js@1.9.10 → @nanostores_solid@1.1.1_nanostores@1.2.0_solid-js@1.9.10}/node_modules/@nanostores/solid/dist/index.js.map +1 -1
  12. package/dist/browser/client/node_modules/.pnpm/{nanostores@1.1.0 → nanostores@1.2.0}/node_modules/nanostores/atom/index.js +2 -1
  13. package/dist/browser/client/node_modules/.pnpm/nanostores@1.2.0/node_modules/nanostores/atom/index.js.map +1 -0
  14. package/dist/browser/client/node_modules/.pnpm/nanostores@1.2.0/node_modules/nanostores/clean-stores/index.js +6 -0
  15. package/dist/browser/client/node_modules/.pnpm/{nanostores@1.1.0 → nanostores@1.2.0}/node_modules/nanostores/clean-stores/index.js.map +1 -1
  16. package/dist/browser/client/node_modules/.pnpm/{nanostores@1.1.0 → nanostores@1.2.0}/node_modules/nanostores/computed/index.js +8 -5
  17. package/dist/browser/client/node_modules/.pnpm/nanostores@1.2.0/node_modules/nanostores/computed/index.js.map +1 -0
  18. package/dist/browser/client/node_modules/.pnpm/{nanostores@1.1.0 → nanostores@1.2.0}/node_modules/nanostores/lifecycle/index.js +1 -1
  19. package/dist/browser/client/node_modules/.pnpm/{nanostores@1.1.0 → nanostores@1.2.0}/node_modules/nanostores/lifecycle/index.js.map +1 -1
  20. package/dist/browser/client/node_modules/.pnpm/{nanostores@1.1.0 → nanostores@1.2.0}/node_modules/nanostores/listen-keys/index.js +1 -1
  21. package/dist/browser/client/node_modules/.pnpm/{nanostores@1.1.0 → nanostores@1.2.0}/node_modules/nanostores/listen-keys/index.js.map +1 -1
  22. package/dist/browser/client/node_modules/.pnpm/{nanostores@1.1.0 → nanostores@1.2.0}/node_modules/nanostores/map/index.js +1 -1
  23. package/dist/browser/client/node_modules/.pnpm/{nanostores@1.1.0 → nanostores@1.2.0}/node_modules/nanostores/map/index.js.map +1 -1
  24. package/dist/browser/client/node_modules/.pnpm/{nanostores@1.1.0 → nanostores@1.2.0}/node_modules/nanostores/task/index.js +1 -1
  25. package/dist/browser/client/node_modules/.pnpm/{nanostores@1.1.0 → nanostores@1.2.0}/node_modules/nanostores/task/index.js.map +1 -1
  26. package/dist/browser/client/node_modules/.pnpm/nanostores@1.2.0/node_modules/nanostores/warn/index.js +16 -0
  27. package/dist/browser/client/node_modules/.pnpm/nanostores@1.2.0/node_modules/nanostores/warn/index.js.map +1 -0
  28. package/dist/browser/client/packages/fragment-upload/src/definition.js +1 -42
  29. package/dist/browser/client/packages/fragment-upload/src/definition.js.map +1 -1
  30. package/dist/browser/client/packages/fragment-upload/src/routes/files.js +12 -5
  31. package/dist/browser/client/packages/fragment-upload/src/routes/files.js.map +1 -1
  32. package/dist/browser/client/packages/fragment-upload/src/routes/shared.js +3 -4
  33. package/dist/browser/client/packages/fragment-upload/src/routes/shared.js.map +1 -1
  34. package/dist/browser/client/packages/fragment-upload/src/routes/uploads.js +32 -21
  35. package/dist/browser/client/packages/fragment-upload/src/routes/uploads.js.map +1 -1
  36. package/dist/browser/client/packages/fragment-upload/src/schema.js +33 -3
  37. package/dist/browser/client/packages/fragment-upload/src/schema.js.map +1 -1
  38. package/dist/browser/client/packages/fragment-upload/src/types.d.ts +1 -2
  39. package/dist/browser/client/packages/fragment-upload/src/types.d.ts.map +1 -1
  40. package/dist/browser/client/packages/fragno/dist/client/client.js +28 -12
  41. package/dist/browser/client/packages/fragno/dist/client/client.js.map +1 -1
  42. package/dist/browser/client/packages/fragno/dist/client/client.svelte.js +11 -3
  43. package/dist/browser/client/packages/fragno/dist/client/client.svelte.js.map +1 -1
  44. package/dist/browser/client/packages/fragno/dist/client/react.js +104 -12
  45. package/dist/browser/client/packages/fragno/dist/client/react.js.map +1 -1
  46. package/dist/browser/client/packages/fragno/dist/client/solid.js +25 -11
  47. package/dist/browser/client/packages/fragno/dist/client/solid.js.map +1 -1
  48. package/dist/browser/client/packages/fragno/dist/client/vanilla.js +21 -1
  49. package/dist/browser/client/packages/fragno/dist/client/vanilla.js.map +1 -1
  50. package/dist/browser/client/packages/fragno/dist/client/vue.js +19 -11
  51. package/dist/browser/client/packages/fragno/dist/client/vue.js.map +1 -1
  52. package/dist/browser/client/react.d.ts +215 -192
  53. package/dist/browser/client/react.d.ts.map +1 -1
  54. package/dist/browser/client/react.js.map +1 -1
  55. package/dist/browser/client/solid.d.ts +218 -196
  56. package/dist/browser/client/solid.d.ts.map +1 -1
  57. package/dist/browser/client/solid.js.map +1 -1
  58. package/dist/browser/client/svelte.d.ts +216 -193
  59. package/dist/browser/client/svelte.d.ts.map +1 -1
  60. package/dist/browser/client/svelte.js.map +1 -1
  61. package/dist/browser/client/vanilla.d.ts +217 -195
  62. package/dist/browser/client/vanilla.d.ts.map +1 -1
  63. package/dist/browser/client/vanilla.js.map +1 -1
  64. package/dist/browser/client/vue.d.ts +217 -194
  65. package/dist/browser/client/vue.d.ts.map +1 -1
  66. package/dist/browser/client/vue.js.map +1 -1
  67. package/dist/cli/commands/files/delete.d.ts +4 -4
  68. package/dist/cli/commands/files/delete.d.ts.map +1 -1
  69. package/dist/cli/commands/files/delete.js +8 -10
  70. package/dist/cli/commands/files/delete.js.map +1 -1
  71. package/dist/cli/commands/files/download-url.d.ts +4 -4
  72. package/dist/cli/commands/files/download-url.d.ts.map +1 -1
  73. package/dist/cli/commands/files/download-url.js +8 -10
  74. package/dist/cli/commands/files/download-url.js.map +1 -1
  75. package/dist/cli/commands/files/download.d.ts +4 -4
  76. package/dist/cli/commands/files/download.d.ts.map +1 -1
  77. package/dist/cli/commands/files/download.js +10 -12
  78. package/dist/cli/commands/files/download.js.map +1 -1
  79. package/dist/cli/commands/files/get.d.ts +4 -4
  80. package/dist/cli/commands/files/get.d.ts.map +1 -1
  81. package/dist/cli/commands/files/get.js +8 -10
  82. package/dist/cli/commands/files/get.js.map +1 -1
  83. package/dist/cli/commands/files/list.d.ts +4 -4
  84. package/dist/cli/commands/files/list.d.ts.map +1 -1
  85. package/dist/cli/commands/files/list.js +6 -8
  86. package/dist/cli/commands/files/list.js.map +1 -1
  87. package/dist/cli/commands/files/update.d.ts +4 -4
  88. package/dist/cli/commands/files/update.d.ts.map +1 -1
  89. package/dist/cli/commands/files/update.js +8 -10
  90. package/dist/cli/commands/files/update.js.map +1 -1
  91. package/dist/cli/commands/files/upload.d.ts +4 -4
  92. package/dist/cli/commands/files/upload.d.ts.map +1 -1
  93. package/dist/cli/commands/files/upload.js +10 -12
  94. package/dist/cli/commands/files/upload.js.map +1 -1
  95. package/dist/cli/commands/uploads/abort.d.ts +2 -2
  96. package/dist/cli/commands/uploads/abort.d.ts.map +1 -1
  97. package/dist/cli/commands/uploads/abort.js.map +1 -1
  98. package/dist/cli/commands/uploads/complete.d.ts +2 -2
  99. package/dist/cli/commands/uploads/complete.d.ts.map +1 -1
  100. package/dist/cli/commands/uploads/complete.js.map +1 -1
  101. package/dist/cli/commands/uploads/content.d.ts +2 -2
  102. package/dist/cli/commands/uploads/content.d.ts.map +1 -1
  103. package/dist/cli/commands/uploads/content.js +1 -1
  104. package/dist/cli/commands/uploads/content.js.map +1 -1
  105. package/dist/cli/commands/uploads/create.d.ts +4 -4
  106. package/dist/cli/commands/uploads/create.d.ts.map +1 -1
  107. package/dist/cli/commands/uploads/create.js +8 -11
  108. package/dist/cli/commands/uploads/create.js.map +1 -1
  109. package/dist/cli/commands/uploads/get.d.ts +2 -2
  110. package/dist/cli/commands/uploads/get.d.ts.map +1 -1
  111. package/dist/cli/commands/uploads/get.js.map +1 -1
  112. package/dist/cli/commands/uploads/parts-complete.d.ts +2 -2
  113. package/dist/cli/commands/uploads/parts-complete.d.ts.map +1 -1
  114. package/dist/cli/commands/uploads/parts-complete.js.map +1 -1
  115. package/dist/cli/commands/uploads/parts-list.d.ts +2 -2
  116. package/dist/cli/commands/uploads/parts-list.d.ts.map +1 -1
  117. package/dist/cli/commands/uploads/parts-list.js.map +1 -1
  118. package/dist/cli/commands/uploads/parts-urls.d.ts +2 -2
  119. package/dist/cli/commands/uploads/parts-urls.d.ts.map +1 -1
  120. package/dist/cli/commands/uploads/parts-urls.js.map +1 -1
  121. package/dist/cli/commands/uploads/progress.d.ts +2 -2
  122. package/dist/cli/commands/uploads/progress.d.ts.map +1 -1
  123. package/dist/cli/commands/uploads/progress.js.map +1 -1
  124. package/dist/cli/commands/uploads/transfer.d.ts +4 -4
  125. package/dist/cli/commands/uploads/transfer.d.ts.map +1 -1
  126. package/dist/cli/commands/uploads/transfer.js +9 -12
  127. package/dist/cli/commands/uploads/transfer.js.map +1 -1
  128. package/dist/cli/index.d.ts +13 -13
  129. package/dist/cli/index.d.ts.map +1 -1
  130. package/dist/cli/index.js +14 -14
  131. package/dist/cli/index.js.map +1 -1
  132. package/dist/cli/utils/client.js +22 -5
  133. package/dist/cli/utils/client.js.map +1 -1
  134. package/dist/cli/utils/options.js +7 -43
  135. package/dist/cli/utils/options.js.map +1 -1
  136. package/dist/node/cli/commands/files/delete.d.ts +4 -4
  137. package/dist/node/cli/commands/files/delete.d.ts.map +1 -1
  138. package/dist/node/cli/commands/files/delete.js +8 -10
  139. package/dist/node/cli/commands/files/delete.js.map +1 -1
  140. package/dist/node/cli/commands/files/download-url.d.ts +4 -4
  141. package/dist/node/cli/commands/files/download-url.d.ts.map +1 -1
  142. package/dist/node/cli/commands/files/download-url.js +8 -10
  143. package/dist/node/cli/commands/files/download-url.js.map +1 -1
  144. package/dist/node/cli/commands/files/download.d.ts +4 -4
  145. package/dist/node/cli/commands/files/download.d.ts.map +1 -1
  146. package/dist/node/cli/commands/files/download.js +9 -11
  147. package/dist/node/cli/commands/files/download.js.map +1 -1
  148. package/dist/node/cli/commands/files/get.d.ts +4 -4
  149. package/dist/node/cli/commands/files/get.d.ts.map +1 -1
  150. package/dist/node/cli/commands/files/get.js +8 -10
  151. package/dist/node/cli/commands/files/get.js.map +1 -1
  152. package/dist/node/cli/commands/files/list.d.ts +4 -4
  153. package/dist/node/cli/commands/files/list.d.ts.map +1 -1
  154. package/dist/node/cli/commands/files/list.js +6 -8
  155. package/dist/node/cli/commands/files/list.js.map +1 -1
  156. package/dist/node/cli/commands/files/update.d.ts +4 -4
  157. package/dist/node/cli/commands/files/update.d.ts.map +1 -1
  158. package/dist/node/cli/commands/files/update.js +8 -10
  159. package/dist/node/cli/commands/files/update.js.map +1 -1
  160. package/dist/node/cli/commands/files/upload.d.ts +4 -4
  161. package/dist/node/cli/commands/files/upload.d.ts.map +1 -1
  162. package/dist/node/cli/commands/files/upload.js +9 -11
  163. package/dist/node/cli/commands/files/upload.js.map +1 -1
  164. package/dist/node/cli/commands/uploads/abort.d.ts +2 -2
  165. package/dist/node/cli/commands/uploads/abort.d.ts.map +1 -1
  166. package/dist/node/cli/commands/uploads/abort.js.map +1 -1
  167. package/dist/node/cli/commands/uploads/complete.d.ts +2 -2
  168. package/dist/node/cli/commands/uploads/complete.d.ts.map +1 -1
  169. package/dist/node/cli/commands/uploads/complete.js.map +1 -1
  170. package/dist/node/cli/commands/uploads/content.d.ts +2 -2
  171. package/dist/node/cli/commands/uploads/content.d.ts.map +1 -1
  172. package/dist/node/cli/commands/uploads/content.js.map +1 -1
  173. package/dist/node/cli/commands/uploads/create.d.ts +4 -4
  174. package/dist/node/cli/commands/uploads/create.d.ts.map +1 -1
  175. package/dist/node/cli/commands/uploads/create.js +8 -11
  176. package/dist/node/cli/commands/uploads/create.js.map +1 -1
  177. package/dist/node/cli/commands/uploads/get.d.ts +2 -2
  178. package/dist/node/cli/commands/uploads/get.d.ts.map +1 -1
  179. package/dist/node/cli/commands/uploads/get.js.map +1 -1
  180. package/dist/node/cli/commands/uploads/parts-complete.d.ts +2 -2
  181. package/dist/node/cli/commands/uploads/parts-complete.d.ts.map +1 -1
  182. package/dist/node/cli/commands/uploads/parts-complete.js.map +1 -1
  183. package/dist/node/cli/commands/uploads/parts-list.d.ts +2 -2
  184. package/dist/node/cli/commands/uploads/parts-list.d.ts.map +1 -1
  185. package/dist/node/cli/commands/uploads/parts-list.js.map +1 -1
  186. package/dist/node/cli/commands/uploads/parts-urls.d.ts +2 -2
  187. package/dist/node/cli/commands/uploads/parts-urls.d.ts.map +1 -1
  188. package/dist/node/cli/commands/uploads/parts-urls.js.map +1 -1
  189. package/dist/node/cli/commands/uploads/progress.d.ts +2 -2
  190. package/dist/node/cli/commands/uploads/progress.d.ts.map +1 -1
  191. package/dist/node/cli/commands/uploads/progress.js.map +1 -1
  192. package/dist/node/cli/commands/uploads/transfer.d.ts +4 -4
  193. package/dist/node/cli/commands/uploads/transfer.d.ts.map +1 -1
  194. package/dist/node/cli/commands/uploads/transfer.js +8 -11
  195. package/dist/node/cli/commands/uploads/transfer.js.map +1 -1
  196. package/dist/node/cli/index.d.ts +13 -13
  197. package/dist/node/cli/index.d.ts.map +1 -1
  198. package/dist/node/cli/index.js +14 -14
  199. package/dist/node/cli/index.js.map +1 -1
  200. package/dist/node/cli/utils/client.js +22 -5
  201. package/dist/node/cli/utils/client.js.map +1 -1
  202. package/dist/node/cli/utils/options.js +7 -43
  203. package/dist/node/cli/utils/options.js.map +1 -1
  204. package/dist/node/client/clients.d.ts +217 -194
  205. package/dist/node/client/clients.d.ts.map +1 -1
  206. package/dist/node/client/clients.js +17 -9
  207. package/dist/node/client/clients.js.map +1 -1
  208. package/dist/node/client/helpers.d.ts +15 -6
  209. package/dist/node/client/helpers.d.ts.map +1 -1
  210. package/dist/node/client/helpers.js +176 -30
  211. package/dist/node/client/helpers.js.map +1 -1
  212. package/dist/node/client/react.d.ts +217 -194
  213. package/dist/node/client/react.d.ts.map +1 -1
  214. package/dist/node/client/react.js.map +1 -1
  215. package/dist/node/client/solid.d.ts +218 -196
  216. package/dist/node/client/solid.d.ts.map +1 -1
  217. package/dist/node/client/solid.js.map +1 -1
  218. package/dist/node/client/svelte.d.ts +216 -193
  219. package/dist/node/client/svelte.d.ts.map +1 -1
  220. package/dist/node/client/svelte.js.map +1 -1
  221. package/dist/node/client/vanilla.d.ts +217 -195
  222. package/dist/node/client/vanilla.d.ts.map +1 -1
  223. package/dist/node/client/vanilla.js.map +1 -1
  224. package/dist/node/client/vue.d.ts +217 -194
  225. package/dist/node/client/vue.d.ts.map +1 -1
  226. package/dist/node/client/vue.js.map +1 -1
  227. package/dist/node/config.d.ts +6 -6
  228. package/dist/node/config.d.ts.map +1 -1
  229. package/dist/node/config.js.map +1 -1
  230. package/dist/node/definition.d.ts +588 -219
  231. package/dist/node/definition.d.ts.map +1 -1
  232. package/dist/node/definition.js +27 -3
  233. package/dist/node/definition.js.map +1 -1
  234. package/dist/node/file-key.d.ts +19 -0
  235. package/dist/node/file-key.d.ts.map +1 -0
  236. package/dist/node/file-key.js +47 -0
  237. package/dist/node/file-key.js.map +1 -0
  238. package/dist/node/index.d.ts +582 -175
  239. package/dist/node/index.d.ts.map +1 -1
  240. package/dist/node/index.js +3 -2
  241. package/dist/node/index.js.map +1 -1
  242. package/dist/node/routes/files.js +99 -64
  243. package/dist/node/routes/files.js.map +1 -1
  244. package/dist/node/routes/index.d.ts +1497 -721
  245. package/dist/node/routes/index.d.ts.map +1 -1
  246. package/dist/node/routes/shared.js +5 -9
  247. package/dist/node/routes/shared.js.map +1 -1
  248. package/dist/node/routes/uploads.js +105 -47
  249. package/dist/node/routes/uploads.js.map +1 -1
  250. package/dist/node/schema.d.ts +6 -6
  251. package/dist/node/schema.d.ts.map +1 -1
  252. package/dist/node/schema.js +12 -3
  253. package/dist/node/schema.js.map +1 -1
  254. package/dist/node/services/files.d.ts +6 -2
  255. package/dist/node/services/files.d.ts.map +1 -1
  256. package/dist/node/services/files.js +22 -20
  257. package/dist/node/services/files.js.map +1 -1
  258. package/dist/node/services/helpers.js +37 -15
  259. package/dist/node/services/helpers.js.map +1 -1
  260. package/dist/node/services/uploads.d.ts +10 -5
  261. package/dist/node/services/uploads.d.ts.map +1 -1
  262. package/dist/node/services/uploads.js +340 -63
  263. package/dist/node/services/uploads.js.map +1 -1
  264. package/dist/node/storage/fs.d.ts.map +1 -1
  265. package/dist/node/storage/fs.js +16 -10
  266. package/dist/node/storage/fs.js.map +1 -1
  267. package/dist/node/storage/object-key.js +36 -0
  268. package/dist/node/storage/object-key.js.map +1 -0
  269. package/dist/node/storage/r2-binding.d.ts +59 -0
  270. package/dist/node/storage/r2-binding.d.ts.map +1 -0
  271. package/dist/node/storage/r2-binding.js +245 -0
  272. package/dist/node/storage/r2-binding.js.map +1 -0
  273. package/dist/node/storage/r2.d.ts +6 -5
  274. package/dist/node/storage/r2.d.ts.map +1 -1
  275. package/dist/node/storage/s3.d.ts.map +1 -1
  276. package/dist/node/storage/s3.js +16 -10
  277. package/dist/node/storage/s3.js.map +1 -1
  278. package/dist/node/storage/types.d.ts +6 -5
  279. package/dist/node/storage/types.d.ts.map +1 -1
  280. package/dist/node/types.d.ts +1 -2
  281. package/dist/node/types.d.ts.map +1 -1
  282. package/package.json +26 -46
  283. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/atom/index.js.map +0 -1
  284. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/clean-stores/index.js +0 -6
  285. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/computed/index.js.map +0 -1
  286. package/dist/browser/client/packages/fragment-upload/src/keys.d.ts +0 -7
  287. package/dist/browser/client/packages/fragment-upload/src/keys.d.ts.map +0 -1
  288. package/dist/browser/client/packages/fragment-upload/src/keys.js +0 -28
  289. package/dist/browser/client/packages/fragment-upload/src/keys.js.map +0 -1
  290. package/dist/browser/index-BdjKPO4J.d.ts +0 -177
  291. package/dist/browser/index-BdjKPO4J.d.ts.map +0 -1
  292. package/dist/browser/index.js +0 -3
  293. package/dist/browser/src-vdNJUbjT.js +0 -1982
  294. package/dist/browser/src-vdNJUbjT.js.map +0 -1
  295. package/dist/cli/keys.js +0 -32
  296. package/dist/cli/keys.js.map +0 -1
  297. package/dist/node/keys.d.ts +0 -12
  298. package/dist/node/keys.d.ts.map +0 -1
  299. package/dist/node/keys.js +0 -63
  300. package/dist/node/keys.js.map +0 -1
  301. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;iBA0CgB,oBAAA,SACN,+BACC,mDAA8B,uDAAA,2CAAA;mEAAA,IAAA,CAAA,SAAA;;;;;;;;;IAFzB,CAAA,CAAA;IAAoB,KAAA,gBAAA;yBAC1B,CAAA,CAAA,CAAA;MACC,kBAAA,cAAA,gBAAA,CAAA;YAA8B,kBAAA,aAAA,CAAA;;;;;;;;YAAA,IAAA,CAAA;;;;;;;;;;;;;;;;;;;;;aAAA,kBAAA,gBAAA;IAAA,aAAA,kBAAA,eAAA,gCAAA,CAAA;;;;;;;;;;;;sEAAA,sBAAA,CAAA;;;;;;;;;;;;;;;;;;;iCAAA,gBAAA;WAAA,cAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAH;;;;;;;;sBAW/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAX+B,QAAA,EAAA,MAAA;;IAW/B,WAAA,EAAA,MAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;iBAmDgB,oBAAA,SACN,+BACC,mDAA8B,uDAAA,2CAAA;6BAAA,IAAA,CAAA,SAAA;;;;;;;;MAFzB,MAAA,EAAA,QAAoB;MAAA,GAAA,EAAA,KAAA;IAC1B,CAAA,CAAA;IACC,KAAA,gBAAA;yBAA8B,CAAA,CAAA,CAAA;;;;;;;;;;YAAA,IAAA,CAAA;;;;;;;;;;;;;;;;;;;;;yBAAA;UAAA,gBAAA;;;;;;;;;;;;;;;;;;sEAAA,sBAAA,CAAA;;;;;;;;;;;;;;;;;;;;iCAAA;IAAA,eAAA,kBAAA,gBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBANxB;;;;;;;;;sBAajB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAbiB;;;;;;;;;sBAajB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAbiB;;;;;;;;;sBAajB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAbiB,EAAA;;IAajB,QAAA,wCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAbiB,QAAA,EAAA,MAAA;;IAajB,eAAA,EAAA,MAAA,GAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAbiB,aAAA,EAAA,OAAA;;IAajB,aAAA,EAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAPyC;MAAA,eAAA,EAAA,MAAA,GAAA,IAAA"}
@@ -1,12 +1,13 @@
1
1
  import { resolveUploadFragmentConfig } from "./config.js";
2
2
  import { uploadSchema } from "./schema.js";
3
- import { decodeFileKey, encodeFileKey, encodeFileKeyPrefix } from "./keys.js";
3
+ import { assertFileKey, splitFileKey, validateFileKey } from "./file-key.js";
4
4
  import { uploadFragmentDefinition } from "./definition.js";
5
5
  import { uploadRoutes } from "./routes/index.js";
6
6
  import { createUploadFragmentClients } from "./client/clients.js";
7
7
  import { createFilesystemStorageAdapter } from "./storage/fs.js";
8
8
  import { createS3CompatibleStorageAdapter } from "./storage/s3.js";
9
9
  import { createR2StorageAdapter } from "./storage/r2.js";
10
+ import { createR2BindingStorageAdapter, resolveR2BindingBucket } from "./storage/r2-binding.js";
10
11
  import { instantiate } from "@fragno-dev/core";
11
12
 
12
13
  //#region src/index.ts
@@ -15,5 +16,5 @@ function createUploadFragment(config, options) {
15
16
  }
16
17
 
17
18
  //#endregion
18
- export { createFilesystemStorageAdapter, createR2StorageAdapter, createS3CompatibleStorageAdapter, createUploadFragment, createUploadFragmentClients, decodeFileKey, encodeFileKey, encodeFileKeyPrefix, resolveUploadFragmentConfig, uploadFragmentDefinition, uploadRoutes, uploadSchema };
19
+ export { assertFileKey, createFilesystemStorageAdapter, createR2BindingStorageAdapter, createR2StorageAdapter, createS3CompatibleStorageAdapter, createUploadFragment, createUploadFragmentClients, resolveR2BindingBucket, resolveUploadFragmentConfig, splitFileKey, uploadFragmentDefinition, uploadRoutes, uploadSchema, validateFileKey };
19
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import type { FragnoPublicConfigWithDatabase } from \"@fragno-dev/db\";\nimport { instantiate } from \"@fragno-dev/core\";\nimport { uploadFragmentDefinition } from \"./definition\";\nimport type { UploadFragmentConfig } from \"./config\";\nimport { uploadRoutes } from \"./routes\";\nimport { createUploadFragmentClients } from \"./client/clients\";\n\nexport type {\n FileHookPayload,\n UploadFragmentConfig,\n UploadFragmentResolvedConfig,\n UploadTimeoutPayload,\n} from \"./config\";\nexport { resolveUploadFragmentConfig } from \"./config\";\nexport { uploadSchema } from \"./schema\";\nexport type { FileKeyEncoded, FileKeyPart, FileKeyParts } from \"./keys\";\nexport { decodeFileKey, encodeFileKey, encodeFileKeyPrefix } from \"./keys\";\nexport type {\n StorageAdapter,\n StorageAdapterCapabilities,\n StorageAdapterLimits,\n StorageAdapterRecommendations,\n UploadChecksum,\n UploadMode,\n UploadTransport,\n} from \"./storage/types\";\nexport { createFilesystemStorageAdapter, type FilesystemStorageAdapterOptions } from \"./storage/fs\";\nexport {\n createS3CompatibleStorageAdapter,\n type S3CompatibleStorageAdapterOptions,\n type S3Signer,\n type S3SignerInput,\n} from \"./storage/s3\";\nexport { createR2StorageAdapter, type R2StorageAdapterOptions } from \"./storage/r2\";\nexport type {\n CreateUploadAndTransferOptions,\n UploadHelpers,\n UploadProgress,\n} from \"./client/helpers\";\n\nexport { uploadRoutes };\n\nexport function createUploadFragment(\n config: UploadFragmentConfig,\n options: FragnoPublicConfigWithDatabase,\n) {\n return instantiate(uploadFragmentDefinition)\n .withConfig(config)\n .withRoutes(uploadRoutes)\n .withOptions(options)\n .build();\n}\nexport { createUploadFragmentClients };\n\nexport { uploadFragmentDefinition } from \"./definition\";\n"],"mappings":";;;;;;;;;;;;AA0CA,SAAgB,qBACd,QACA,SACA;AACA,QAAO,YAAY,yBAAyB,CACzC,WAAW,OAAO,CAClB,WAAW,aAAa,CACxB,YAAY,QAAQ,CACpB,OAAO"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import { instantiate } from \"@fragno-dev/core\";\nimport type { FragnoPublicConfigWithDatabase } from \"@fragno-dev/db\";\n\nimport { createUploadFragmentClients } from \"./client/clients\";\nimport type { UploadFragmentConfig } from \"./config\";\nimport { uploadFragmentDefinition } from \"./definition\";\nimport { uploadRoutes } from \"./routes\";\n\nexport type {\n FileHookPayload,\n UploadFragmentConfig,\n UploadFragmentResolvedConfig,\n UploadTimeoutPayload,\n} from \"./config\";\nexport { resolveUploadFragmentConfig } from \"./config\";\nexport { uploadSchema } from \"./schema\";\nexport type { FileKey, FileKeyValidationResult, ValidateFileKeyOptions } from \"./file-key\";\nexport { assertFileKey, splitFileKey, validateFileKey } from \"./file-key\";\nexport type {\n StorageAdapter,\n StorageAdapterCapabilities,\n StorageAdapterLimits,\n StorageAdapterRecommendations,\n UploadChecksum,\n UploadMode,\n UploadTransport,\n} from \"./storage/types\";\nexport { createFilesystemStorageAdapter, type FilesystemStorageAdapterOptions } from \"./storage/fs\";\nexport {\n createS3CompatibleStorageAdapter,\n type S3CompatibleStorageAdapterOptions,\n type S3Signer,\n type S3SignerInput,\n} from \"./storage/s3\";\nexport { createR2StorageAdapter, type R2StorageAdapterOptions } from \"./storage/r2\";\nexport {\n createR2BindingStorageAdapter,\n resolveR2BindingBucket,\n type R2BindingBucket,\n type R2BindingStorageAdapterOptions,\n} from \"./storage/r2-binding\";\nexport type {\n CreateUploadAndTransferOptions,\n DownloadFileOptions,\n DownloadMethod,\n UploadHelpers,\n UploadProgress,\n} from \"./client/helpers\";\n\nexport { uploadRoutes };\n\nexport function createUploadFragment(\n config: UploadFragmentConfig,\n options: FragnoPublicConfigWithDatabase,\n) {\n return instantiate(uploadFragmentDefinition)\n .withConfig(config)\n .withRoutes(uploadRoutes)\n .withOptions(options)\n .build();\n}\nexport { createUploadFragmentClients };\n\nexport { uploadFragmentDefinition } from \"./definition\";\n"],"mappings":";;;;;;;;;;;;;AAmDA,SAAgB,qBACd,QACA,SACA;AACA,QAAO,YAAY,yBAAyB,CACzC,WAAW,OAAO,CAClB,WAAW,aAAa,CACxB,YAAY,QAAQ,CACpB,OAAO"}
@@ -1,18 +1,25 @@
1
1
  import { resolveUploadFragmentConfig } from "../config.js";
2
2
  import { resolveFileKeyInput } from "../services/helpers.js";
3
3
  import { uploadFragmentDefinition } from "../definition.js";
4
- import { checksumSchema, fileKeyPartsSchema, fileMetadataSchema, toFileMetadata, visibilitySchema } from "./shared.js";
4
+ import { buildStorageObjectVersionSegment } from "../storage/object-key.js";
5
+ import { checksumSchema, fileMetadataSchema, providerNamespaceSchema, toFileMetadata, visibilitySchema } from "./shared.js";
5
6
  import { defineRoutes } from "@fragno-dev/core";
6
7
  import { z } from "zod";
7
8
 
8
9
  //#region src/routes/files.ts
10
+ const legacyFileKeyPartsSchema = z.array(z.union([z.string(), z.number().int()]));
9
11
  const listQuerySchema = z.object({
12
+ provider: providerNamespaceSchema.optional(),
10
13
  prefix: z.string().optional(),
11
14
  cursor: z.string().optional(),
12
15
  pageSize: z.coerce.number().min(1).max(100).catch(25),
13
16
  status: z.enum(["ready", "deleted"]).optional(),
14
17
  uploaderId: z.string().optional()
15
18
  });
19
+ const byKeyQuerySchema = z.object({
20
+ provider: providerNamespaceSchema,
21
+ key: z.string().min(1)
22
+ });
16
23
  const updateFileSchema = z.object({
17
24
  filename: z.string().min(1).optional(),
18
25
  visibility: visibilitySchema.optional(),
@@ -24,6 +31,7 @@ const errorCodes = [
24
31
  "UPLOAD_ALREADY_ACTIVE",
25
32
  "FILE_ALREADY_EXISTS",
26
33
  "FILE_NOT_FOUND",
34
+ "FILE_DELETED",
27
35
  "UPLOAD_EXPIRED",
28
36
  "UPLOAD_INVALID_STATE",
29
37
  "SIGNED_URL_UNSUPPORTED",
@@ -39,6 +47,10 @@ const handleServiceError = (err, error) => {
39
47
  message: "File not found",
40
48
  code: "FILE_NOT_FOUND"
41
49
  }, 404);
50
+ case "FILE_DELETED": return error({
51
+ message: "File deleted",
52
+ code: "FILE_DELETED"
53
+ }, 410);
42
54
  case "UPLOAD_NOT_FOUND": return error({
43
55
  message: "Upload not found",
44
56
  code: "UPLOAD_NOT_FOUND"
@@ -71,6 +83,10 @@ const handleServiceError = (err, error) => {
71
83
  message: "Invalid request",
72
84
  code: "INVALID_REQUEST"
73
85
  }, 400);
86
+ case "STORAGE_ERROR": return error({
87
+ message: "Storage error",
88
+ code: "STORAGE_ERROR"
89
+ }, 502);
74
90
  default: throw err;
75
91
  }
76
92
  };
@@ -93,10 +109,15 @@ const parseMetadata = (value) => {
93
109
  const parsed = parseJson(value);
94
110
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
95
111
  };
112
+ const assertFileAvailable = (file) => {
113
+ if (file.status === "deleted") throw new Error("FILE_DELETED");
114
+ return file;
115
+ };
96
116
  const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ services, defineRoute, config }) => {
97
117
  const getResolvedConfig = () => resolveUploadFragmentConfig(config);
98
118
  const parseListQuery = (query) => {
99
119
  const result = listQuerySchema.safeParse({
120
+ provider: query.has("provider") ? query.get("provider") : void 0,
100
121
  prefix: query.get("prefix") || void 0,
101
122
  cursor: query.get("cursor") || void 0,
102
123
  pageSize: query.get("pageSize"),
@@ -104,9 +125,23 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
104
125
  uploaderId: query.get("uploaderId") || void 0
105
126
  });
106
127
  if (!result.success) throw new Error("INVALID_REQUEST");
107
- const params = result.data;
108
- if (params.prefix && !params.prefix.endsWith(".")) throw new Error("INVALID_FILE_KEY");
109
- return params;
128
+ return result.data;
129
+ };
130
+ const parseByKeyQuery = (query) => {
131
+ const result = byKeyQuerySchema.safeParse({
132
+ provider: query.get("provider"),
133
+ key: query.get("key")
134
+ });
135
+ if (!result.success) throw new Error("INVALID_REQUEST");
136
+ try {
137
+ const resolvedKey = resolveFileKeyInput({ fileKey: result.data.key });
138
+ return {
139
+ provider: result.data.provider,
140
+ fileKey: resolvedKey.fileKey
141
+ };
142
+ } catch {
143
+ throw new Error("INVALID_FILE_KEY");
144
+ }
110
145
  };
111
146
  return [
112
147
  defineRoute({
@@ -123,10 +158,17 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
123
158
  message: "File is required",
124
159
  code: "INVALID_REQUEST"
125
160
  }, 400);
161
+ const providerValue = form.get("provider");
162
+ const providerResult = providerNamespaceSchema.safeParse(providerValue);
163
+ if (!providerResult.success) return error({
164
+ message: "Invalid request",
165
+ code: "INVALID_REQUEST"
166
+ }, 400);
167
+ const provider = providerResult.data;
126
168
  let keyParts;
127
169
  if (form.has("keyParts")) {
128
170
  const parsed = parseJson(form.get("keyParts"));
129
- const result = fileKeyPartsSchema.safeParse(parsed);
171
+ const result = legacyFileKeyPartsSchema.safeParse(parsed);
130
172
  if (!result.success) return error({
131
173
  message: "Invalid file key",
132
174
  code: "INVALID_FILE_KEY"
@@ -168,7 +210,9 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
168
210
  const filenameValue = form.get("filename");
169
211
  const filename = typeof filenameValue === "string" && filenameValue ? filenameValue : file instanceof File && file.name ? file.name : "upload";
170
212
  const contentType = file.type || "application/octet-stream";
213
+ const objectKeyVersionSegment = buildStorageObjectVersionSegment();
171
214
  const createInput = {
215
+ provider,
172
216
  fileKey: resolvedKey.fileKey,
173
217
  keyParts: resolvedKey.fileKeyParts,
174
218
  filename,
@@ -180,19 +224,15 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
180
224
  uploaderId,
181
225
  metadata
182
226
  };
183
- try {
184
- await this.handlerTx().withServiceCalls(() => [services.checkUploadAvailability(createInput, { allowIdempotentReuse: false })]).execute();
185
- } catch (err) {
186
- return handleServiceError(err, error);
187
- }
188
227
  try {
189
228
  storageInit = await resolvedConfig.storage.initUpload({
229
+ provider,
190
230
  fileKey: resolvedKey.fileKey,
191
- fileKeyParts: resolvedKey.fileKeyParts,
192
231
  sizeBytes: BigInt(file.size),
193
232
  contentType,
194
233
  checksum: checksumForStorage,
195
- metadata: metadata ?? null
234
+ metadata: metadata ?? null,
235
+ objectKeyVersionSegment
196
236
  });
197
237
  } catch {
198
238
  return error({
@@ -212,19 +252,8 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
212
252
  code: "UPLOAD_INVALID_STATE"
213
253
  }, 409);
214
254
  }
215
- let created;
216
- try {
217
- created = await this.handlerTx().withServiceCalls(() => [services.createUploadRecord({
218
- ...createInput,
219
- storageInit,
220
- allowIdempotentReuse: false
221
- })]).transform(({ serviceResult: [result] }) => result).execute();
222
- } catch (err) {
223
- return handleServiceError(err, error);
224
- }
225
- const createdUpload = created.result;
226
255
  try {
227
- if (createdUpload.strategy === "proxy") {
256
+ if (storageInit.strategy === "proxy") {
228
257
  if (!resolvedConfig.storage.writeStream) throw new Error("STORAGE_ERROR");
229
258
  await resolvedConfig.storage.writeStream({
230
259
  storageKey: storageInit.storageKey,
@@ -232,7 +261,7 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
232
261
  contentType,
233
262
  sizeBytes: BigInt(file.size)
234
263
  });
235
- } else if (createdUpload.strategy === "direct-single") {
264
+ } else if (storageInit.strategy === "direct-single") {
236
265
  if (!storageInit.uploadUrl) throw new Error("STORAGE_ERROR");
237
266
  if (!(await fetch(storageInit.uploadUrl, {
238
267
  method: "PUT",
@@ -249,14 +278,23 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
249
278
  checksum: checksumResult.data ?? null
250
279
  });
251
280
  } catch {
252
- await this.handlerTx().withServiceCalls(() => [services.markUploadFailed(createdUpload.uploadId, "STORAGE_ERROR", "Storage upload failed")]).execute();
281
+ await this.handlerTx().withServiceCalls(() => [services.createFailedUpload({
282
+ ...createInput,
283
+ storageInit,
284
+ errorCode: "STORAGE_ERROR",
285
+ errorMessage: "Storage upload failed"
286
+ })]).execute();
253
287
  return error({
254
288
  message: "Storage error",
255
289
  code: "STORAGE_ERROR"
256
290
  }, 502);
257
291
  }
258
292
  try {
259
- return json(toFileMetadata((await this.handlerTx().withServiceCalls(() => [services.markUploadComplete(createdUpload.uploadId, createdUpload.fileKey, { sizeBytes: BigInt(file.size) })]).transform(({ serviceResult: [result] }) => result).execute()).file));
293
+ return json(toFileMetadata((await this.handlerTx().withServiceCalls(() => [services.createCompletedUpload({
294
+ ...createInput,
295
+ storageInit,
296
+ completedSizeBytes: BigInt(file.size)
297
+ })]).transform(({ serviceResult: [result] }) => result).execute()).file));
260
298
  } catch (err) {
261
299
  return handleServiceError(err, error);
262
300
  }
@@ -266,6 +304,7 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
266
304
  method: "GET",
267
305
  path: "/files",
268
306
  queryParameters: [
307
+ "provider",
269
308
  "prefix",
270
309
  "cursor",
271
310
  "pageSize",
@@ -286,6 +325,7 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
286
325
  return handleServiceError(err, error);
287
326
  }
288
327
  const result = await this.handlerTx().withServiceCalls(() => [services.listFiles({
328
+ provider: params.provider,
289
329
  prefix: params.prefix,
290
330
  pageSize: params.pageSize,
291
331
  cursor: params.cursor,
@@ -301,18 +341,19 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
301
341
  }),
302
342
  defineRoute({
303
343
  method: "GET",
304
- path: "/files/:fileKey",
344
+ path: "/files/by-key",
345
+ queryParameters: ["provider", "key"],
305
346
  outputSchema: fileMetadataSchema,
306
347
  errorCodes,
307
- handler: async function({ pathParams }, { json, error }) {
308
- let resolvedKey;
348
+ handler: async function({ query }, { json, error }) {
349
+ let byKey;
309
350
  try {
310
- resolvedKey = resolveFileKeyInput({ fileKey: pathParams.fileKey });
351
+ byKey = parseByKeyQuery(query);
311
352
  } catch (err) {
312
353
  return handleServiceError(err, error);
313
354
  }
314
355
  try {
315
- return json(toFileMetadata(await this.handlerTx().withServiceCalls(() => [services.getFileByKey(resolvedKey.fileKey)]).transform(({ serviceResult: [result] }) => result).execute()));
356
+ return json(toFileMetadata(await this.handlerTx().withServiceCalls(() => [services.getFileByKey(byKey)]).transform(({ serviceResult: [result] }) => result).execute()));
316
357
  } catch (err) {
317
358
  return handleServiceError(err, error);
318
359
  }
@@ -320,20 +361,21 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
320
361
  }),
321
362
  defineRoute({
322
363
  method: "PATCH",
323
- path: "/files/:fileKey",
364
+ path: "/files/by-key",
365
+ queryParameters: ["provider", "key"],
324
366
  inputSchema: updateFileSchema,
325
367
  outputSchema: fileMetadataSchema,
326
368
  errorCodes,
327
- handler: async function({ pathParams, input }, { json, error }) {
369
+ handler: async function({ query, input }, { json, error }) {
328
370
  const payload = await input.valid();
329
- let resolvedKey;
371
+ let byKey;
330
372
  try {
331
- resolvedKey = resolveFileKeyInput({ fileKey: pathParams.fileKey });
373
+ byKey = parseByKeyQuery(query);
332
374
  } catch (err) {
333
375
  return handleServiceError(err, error);
334
376
  }
335
377
  try {
336
- return json(toFileMetadata(await this.handlerTx().withServiceCalls(() => [services.updateFile(resolvedKey.fileKey, payload)]).transform(({ serviceResult: [result] }) => result).execute()));
378
+ return json(toFileMetadata(await this.handlerTx().withServiceCalls(() => [services.updateFile(byKey, payload)]).transform(({ serviceResult: [result] }) => result).execute()));
337
379
  } catch (err) {
338
380
  return handleServiceError(err, error);
339
381
  }
@@ -341,28 +383,19 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
341
383
  }),
342
384
  defineRoute({
343
385
  method: "DELETE",
344
- path: "/files/:fileKey",
386
+ path: "/files/by-key",
387
+ queryParameters: ["provider", "key"],
345
388
  outputSchema: z.object({ ok: z.literal(true) }),
346
389
  errorCodes,
347
- handler: async function({ pathParams }, { json, error }) {
348
- const resolvedConfig = getResolvedConfig();
349
- let resolvedKey;
390
+ handler: async function({ query }, { json, error }) {
391
+ let byKey;
350
392
  try {
351
- resolvedKey = resolveFileKeyInput({ fileKey: pathParams.fileKey });
393
+ byKey = parseByKeyQuery(query);
352
394
  } catch (err) {
353
395
  return handleServiceError(err, error);
354
396
  }
355
397
  try {
356
- const file = await this.handlerTx().withServiceCalls(() => [services.getFileByKey(resolvedKey.fileKey)]).transform(({ serviceResult: [result] }) => result).execute();
357
- try {
358
- await resolvedConfig.storage.deleteObject({ storageKey: file.storageKey });
359
- } catch {
360
- return error({
361
- message: "Storage error",
362
- code: "STORAGE_ERROR"
363
- }, 502);
364
- }
365
- await this.handlerTx().withServiceCalls(() => [services.markFileDeleted(resolvedKey.fileKey, resolvedKey.fileKeyParts)]).execute();
398
+ await this.handlerTx().withServiceCalls(() => [services.markFileDeleted(byKey)]).execute();
366
399
  return json({ ok: true });
367
400
  } catch (err) {
368
401
  return handleServiceError(err, error);
@@ -371,18 +404,19 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
371
404
  }),
372
405
  defineRoute({
373
406
  method: "GET",
374
- path: "/files/:fileKey/download-url",
407
+ path: "/files/by-key/download-url",
408
+ queryParameters: ["provider", "key"],
375
409
  outputSchema: z.object({
376
410
  url: z.string(),
377
411
  headers: z.record(z.string(), z.string()).optional(),
378
412
  expiresAt: z.date()
379
413
  }),
380
414
  errorCodes,
381
- handler: async function({ pathParams }, { json, error }) {
415
+ handler: async function({ query }, { json, error }) {
382
416
  const resolvedConfig = getResolvedConfig();
383
- let resolvedKey;
417
+ let byKey;
384
418
  try {
385
- resolvedKey = resolveFileKeyInput({ fileKey: pathParams.fileKey });
419
+ byKey = parseByKeyQuery(query);
386
420
  } catch (err) {
387
421
  return handleServiceError(err, error);
388
422
  }
@@ -391,11 +425,11 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
391
425
  code: "SIGNED_URL_UNSUPPORTED"
392
426
  }, 400);
393
427
  try {
394
- const file = await this.handlerTx().withServiceCalls(() => [services.getFileByKey(resolvedKey.fileKey)]).transform(({ serviceResult: [result$1] }) => result$1).execute();
428
+ const file = assertFileAvailable(await this.handlerTx().withServiceCalls(() => [services.getFileByKey(byKey)]).transform(({ serviceResult: [result$1] }) => result$1).execute());
395
429
  let result;
396
430
  try {
397
431
  result = await resolvedConfig.storage.getDownloadUrl({
398
- storageKey: file.storageKey,
432
+ storageKey: file.objectKey,
399
433
  expiresInSeconds: resolvedConfig.signedUrlExpiresInSeconds,
400
434
  contentType: file.contentType ?? void 0
401
435
  });
@@ -413,13 +447,14 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
413
447
  }),
414
448
  defineRoute({
415
449
  method: "GET",
416
- path: "/files/:fileKey/content",
450
+ path: "/files/by-key/content",
451
+ queryParameters: ["provider", "key"],
417
452
  errorCodes,
418
- handler: async function({ pathParams }, { error }) {
453
+ handler: async function({ query }, { error }) {
419
454
  const resolvedConfig = getResolvedConfig();
420
- let resolvedKey;
455
+ let byKey;
421
456
  try {
422
- resolvedKey = resolveFileKeyInput({ fileKey: pathParams.fileKey });
457
+ byKey = parseByKeyQuery(query);
423
458
  } catch (err) {
424
459
  return handleServiceError(err, error);
425
460
  }
@@ -428,9 +463,9 @@ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ servi
428
463
  code: "SIGNED_URL_UNSUPPORTED"
429
464
  }, 400);
430
465
  try {
431
- const file = await this.handlerTx().withServiceCalls(() => [services.getFileByKey(resolvedKey.fileKey)]).transform(({ serviceResult: [result] }) => result).execute();
466
+ const file = assertFileAvailable(await this.handlerTx().withServiceCalls(() => [services.getFileByKey(byKey)]).transform(({ serviceResult: [result] }) => result).execute());
432
467
  try {
433
- return await resolvedConfig.storage.getDownloadStream({ storageKey: file.storageKey });
468
+ return await resolvedConfig.storage.getDownloadStream({ storageKey: file.objectKey });
434
469
  } catch {
435
470
  return error({
436
471
  message: "Storage error",
@@ -1 +1 @@
1
- {"version":3,"file":"files.js","names":["keyParts: z.infer<typeof fileKeyPartsSchema> | undefined","result"],"sources":["../../../src/routes/files.ts"],"sourcesContent":["import { defineRoutes } from \"@fragno-dev/core\";\nimport type { FragnoRouteConfig } from \"@fragno-dev/core\";\nimport { z } from \"zod\";\nimport { uploadFragmentDefinition } from \"../definition\";\nimport { resolveUploadFragmentConfig } from \"../config\";\nimport { resolveFileKeyInput } from \"../services/helpers\";\nimport {\n checksumSchema,\n fileKeyPartsSchema,\n fileMetadataSchema,\n toFileMetadata,\n visibilitySchema,\n} from \"./shared\";\n\nconst listQuerySchema = z.object({\n prefix: z.string().optional(),\n cursor: z.string().optional(),\n pageSize: z.coerce.number().min(1).max(100).catch(25),\n status: z.enum([\"ready\", \"deleted\"]).optional(),\n uploaderId: z.string().optional(),\n});\n\nconst updateFileSchema = z.object({\n filename: z.string().min(1).optional(),\n visibility: visibilitySchema.optional(),\n tags: z.array(z.string()).nullable().optional(),\n metadata: z.record(z.string(), z.unknown()).nullable().optional(),\n});\n\nconst errorCodes = [\n \"UPLOAD_NOT_FOUND\",\n \"UPLOAD_ALREADY_ACTIVE\",\n \"FILE_ALREADY_EXISTS\",\n \"FILE_NOT_FOUND\",\n \"UPLOAD_EXPIRED\",\n \"UPLOAD_INVALID_STATE\",\n \"SIGNED_URL_UNSUPPORTED\",\n \"STORAGE_ERROR\",\n \"INVALID_FILE_KEY\",\n \"INVALID_CHECKSUM\",\n \"INVALID_REQUEST\",\n] as const;\n\ntype FileErrorCode = (typeof errorCodes)[number];\n\ntype ErrorFn<Code extends string> = Parameters<\n FragnoRouteConfig<\"GET\", \"/__error\", undefined, undefined, Code>[\"handler\"]\n>[1][\"error\"];\n\nconst handleServiceError = <Code extends FileErrorCode>(\n err: unknown,\n error: ErrorFn<Code>,\n): Response => {\n if (!(err instanceof Error)) {\n throw err;\n }\n\n switch (err.message) {\n case \"FILE_NOT_FOUND\":\n return error({ message: \"File not found\", code: \"FILE_NOT_FOUND\" as Code }, 404);\n case \"UPLOAD_NOT_FOUND\":\n return error({ message: \"Upload not found\", code: \"UPLOAD_NOT_FOUND\" as Code }, 404);\n case \"FILE_ALREADY_EXISTS\":\n return error({ message: \"File already exists\", code: \"FILE_ALREADY_EXISTS\" as Code }, 409);\n case \"UPLOAD_ALREADY_ACTIVE\":\n return error(\n { message: \"Upload already active\", code: \"UPLOAD_ALREADY_ACTIVE\" as Code },\n 409,\n );\n case \"UPLOAD_EXPIRED\":\n return error({ message: \"Upload expired\", code: \"UPLOAD_EXPIRED\" as Code }, 410);\n case \"UPLOAD_INVALID_STATE\":\n return error({ message: \"Upload invalid state\", code: \"UPLOAD_INVALID_STATE\" as Code }, 409);\n case \"INVALID_FILE_KEY\":\n return error({ message: \"Invalid file key\", code: \"INVALID_FILE_KEY\" as Code }, 400);\n case \"INVALID_CHECKSUM\":\n return error({ message: \"Invalid checksum\", code: \"INVALID_CHECKSUM\" as Code }, 400);\n case \"INVALID_REQUEST\":\n return error({ message: \"Invalid request\", code: \"INVALID_REQUEST\" as Code }, 400);\n default:\n throw err;\n }\n};\n\nconst parseJson = <T>(value: FormDataEntryValue | null): T | undefined => {\n if (value === null || typeof value !== \"string\" || value.length === 0) {\n return undefined;\n }\n try {\n return JSON.parse(value) as T;\n } catch {\n return undefined;\n }\n};\n\nconst parseTags = (value: FormDataEntryValue | null): string[] | undefined => {\n if (value === null) {\n return undefined;\n }\n if (typeof value !== \"string\") {\n return undefined;\n }\n const parsed = parseJson<unknown>(value);\n if (Array.isArray(parsed)) {\n return parsed.filter((tag) => typeof tag === \"string\") as string[];\n }\n if (typeof value === \"string\" && value.length > 0) {\n return [value];\n }\n return undefined;\n};\n\nconst parseMetadata = (value: FormDataEntryValue | null): Record<string, unknown> | undefined => {\n const parsed = parseJson<unknown>(value);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n return undefined;\n};\n\nexport const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(\n ({ services, defineRoute, config }) => {\n const getResolvedConfig = () => resolveUploadFragmentConfig(config);\n\n const parseListQuery = (query: URLSearchParams) => {\n const result = listQuerySchema.safeParse({\n prefix: query.get(\"prefix\") || undefined,\n cursor: query.get(\"cursor\") || undefined,\n pageSize: query.get(\"pageSize\"),\n status: query.get(\"status\") || undefined,\n uploaderId: query.get(\"uploaderId\") || undefined,\n });\n if (!result.success) {\n throw new Error(\"INVALID_REQUEST\");\n }\n const params = result.data;\n\n if (params.prefix && !params.prefix.endsWith(\".\")) {\n throw new Error(\"INVALID_FILE_KEY\");\n }\n\n return params;\n };\n\n return [\n defineRoute({\n method: \"POST\",\n path: \"/files\",\n contentType: \"multipart/form-data\",\n outputSchema: fileMetadataSchema,\n errorCodes,\n handler: async function (context, { json, error }) {\n const resolvedConfig = getResolvedConfig();\n const form = context.formData();\n const file = form.get(\"file\");\n if (!(file instanceof Blob)) {\n return error({ message: \"File is required\", code: \"INVALID_REQUEST\" }, 400);\n }\n\n let keyParts: z.infer<typeof fileKeyPartsSchema> | undefined;\n if (form.has(\"keyParts\")) {\n const parsed = parseJson<unknown>(form.get(\"keyParts\"));\n const result = fileKeyPartsSchema.safeParse(parsed);\n if (!result.success) {\n return error({ message: \"Invalid file key\", code: \"INVALID_FILE_KEY\" }, 400);\n }\n keyParts = result.data;\n }\n\n const fileKeyValue = form.get(\"fileKey\");\n const fileKey = typeof fileKeyValue === \"string\" ? fileKeyValue : undefined;\n\n const checksumValue = form.get(\"checksum\");\n const parsedChecksum = parseJson<unknown>(checksumValue);\n const checksumResult = checksumSchema.safeParse(parsedChecksum);\n if (!checksumResult.success) {\n return error({ message: \"Invalid checksum\", code: \"INVALID_CHECKSUM\" }, 400);\n }\n\n const tags = parseTags(form.get(\"tags\"));\n const metadata = parseMetadata(form.get(\"metadata\"));\n\n let resolvedKey;\n try {\n resolvedKey = resolveFileKeyInput({ keyParts, fileKey: fileKey ?? undefined });\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n const checksumForStorage = checksumResult.data ?? null;\n const checksumForRecord = checksumResult.data ?? undefined;\n\n let storageInit;\n\n const uploaderIdValue = form.get(\"uploaderId\");\n const uploaderId = typeof uploaderIdValue === \"string\" ? uploaderIdValue : undefined;\n const visibilityValue = form.get(\"visibility\");\n const parsedVisibility =\n typeof visibilityValue === \"string\" ? visibilityValue : undefined;\n const visibilityResult = visibilitySchema.optional().safeParse(parsedVisibility);\n if (!visibilityResult.success) {\n return error({ message: \"Invalid request\", code: \"INVALID_REQUEST\" }, 400);\n }\n const visibility = visibilityResult.data;\n const filenameValue = form.get(\"filename\");\n const filename =\n typeof filenameValue === \"string\" && filenameValue\n ? filenameValue\n : file instanceof File && file.name\n ? file.name\n : \"upload\";\n const contentType = file.type || \"application/octet-stream\";\n\n const createInput = {\n fileKey: resolvedKey.fileKey,\n keyParts: resolvedKey.fileKeyParts,\n filename,\n sizeBytes: file.size,\n contentType,\n checksum: checksumForRecord,\n tags,\n visibility,\n uploaderId,\n metadata,\n };\n\n try {\n await this.handlerTx()\n .withServiceCalls(() => [\n services.checkUploadAvailability(createInput, { allowIdempotentReuse: false }),\n ])\n .execute();\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n try {\n storageInit = await resolvedConfig.storage.initUpload({\n fileKey: resolvedKey.fileKey,\n fileKeyParts: resolvedKey.fileKeyParts,\n sizeBytes: BigInt(file.size),\n contentType,\n checksum: checksumForStorage,\n metadata: metadata ?? null,\n });\n } catch {\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n\n if (storageInit.strategy === \"direct-multipart\") {\n if (resolvedConfig.storage.abortMultipartUpload && storageInit.storageUploadId) {\n try {\n await resolvedConfig.storage.abortMultipartUpload({\n storageKey: storageInit.storageKey,\n storageUploadId: storageInit.storageUploadId,\n });\n } catch {\n // Ignore abort failures; the request is still invalid for this endpoint.\n }\n }\n\n return error({ message: \"Upload invalid state\", code: \"UPLOAD_INVALID_STATE\" }, 409);\n }\n\n let created;\n try {\n created = await this.handlerTx()\n .withServiceCalls(() => [\n services.createUploadRecord({\n ...createInput,\n storageInit,\n allowIdempotentReuse: false,\n }),\n ])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n const createdUpload = created.result;\n\n try {\n if (createdUpload.strategy === \"proxy\") {\n if (!resolvedConfig.storage.writeStream) {\n throw new Error(\"STORAGE_ERROR\");\n }\n await resolvedConfig.storage.writeStream({\n storageKey: storageInit.storageKey,\n body: file.stream(),\n contentType,\n sizeBytes: BigInt(file.size),\n });\n } else if (createdUpload.strategy === \"direct-single\") {\n if (!storageInit.uploadUrl) {\n throw new Error(\"STORAGE_ERROR\");\n }\n const response = await fetch(storageInit.uploadUrl, {\n method: \"PUT\",\n headers: storageInit.uploadHeaders,\n body: file,\n });\n if (!response.ok) {\n throw new Error(\"STORAGE_ERROR\");\n }\n } else {\n return error({ message: \"Upload invalid state\", code: \"UPLOAD_INVALID_STATE\" }, 409);\n }\n\n if (resolvedConfig.storage.finalizeUpload) {\n await resolvedConfig.storage.finalizeUpload({\n storageKey: storageInit.storageKey,\n expectedSizeBytes: BigInt(file.size),\n checksum: checksumResult.data ?? null,\n });\n }\n } catch {\n await this.handlerTx()\n .withServiceCalls(() => [\n services.markUploadFailed(\n createdUpload.uploadId,\n \"STORAGE_ERROR\",\n \"Storage upload failed\",\n ),\n ])\n .execute();\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n\n try {\n const completed = await this.handlerTx()\n .withServiceCalls(() => [\n services.markUploadComplete(createdUpload.uploadId, createdUpload.fileKey, {\n sizeBytes: BigInt(file.size),\n }),\n ])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n return json(toFileMetadata(completed.file));\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/files\",\n queryParameters: [\"prefix\", \"cursor\", \"pageSize\", \"status\", \"uploaderId\"],\n outputSchema: z.object({\n files: z.array(fileMetadataSchema),\n cursor: z.string().optional(),\n hasNextPage: z.boolean(),\n }),\n errorCodes,\n handler: async function ({ query }, { json, error }) {\n let params;\n try {\n params = parseListQuery(query);\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n const result = await this.handlerTx()\n .withServiceCalls(() => [\n services.listFiles({\n prefix: params.prefix,\n pageSize: params.pageSize,\n cursor: params.cursor,\n status: params.status,\n uploaderId: params.uploaderId,\n }),\n ])\n .transform(({ serviceResult: [files] }) => files)\n .execute();\n\n return json({\n files: result.items.map(toFileMetadata),\n cursor: result.cursor?.encode(),\n hasNextPage: result.hasNextPage,\n });\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/files/:fileKey\",\n outputSchema: fileMetadataSchema,\n errorCodes,\n handler: async function ({ pathParams }, { json, error }) {\n let resolvedKey;\n try {\n resolvedKey = resolveFileKeyInput({ fileKey: pathParams.fileKey });\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n try {\n const file = await this.handlerTx()\n .withServiceCalls(() => [services.getFileByKey(resolvedKey.fileKey)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n return json(toFileMetadata(file));\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"PATCH\",\n path: \"/files/:fileKey\",\n inputSchema: updateFileSchema,\n outputSchema: fileMetadataSchema,\n errorCodes,\n handler: async function ({ pathParams, input }, { json, error }) {\n const payload = await input.valid();\n let resolvedKey;\n try {\n resolvedKey = resolveFileKeyInput({ fileKey: pathParams.fileKey });\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n try {\n const file = await this.handlerTx()\n .withServiceCalls(() => [services.updateFile(resolvedKey.fileKey, payload)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n return json(toFileMetadata(file));\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"DELETE\",\n path: \"/files/:fileKey\",\n outputSchema: z.object({ ok: z.literal(true) }),\n errorCodes,\n handler: async function ({ pathParams }, { json, error }) {\n const resolvedConfig = getResolvedConfig();\n let resolvedKey;\n try {\n resolvedKey = resolveFileKeyInput({ fileKey: pathParams.fileKey });\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n try {\n const file = await this.handlerTx()\n .withServiceCalls(() => [services.getFileByKey(resolvedKey.fileKey)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n try {\n await resolvedConfig.storage.deleteObject({ storageKey: file.storageKey });\n } catch {\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n\n await this.handlerTx()\n .withServiceCalls(() => [\n services.markFileDeleted(resolvedKey.fileKey, resolvedKey.fileKeyParts),\n ])\n .execute();\n\n return json({ ok: true });\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/files/:fileKey/download-url\",\n outputSchema: z.object({\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n expiresAt: z.date(),\n }),\n errorCodes,\n handler: async function ({ pathParams }, { json, error }) {\n const resolvedConfig = getResolvedConfig();\n let resolvedKey;\n try {\n resolvedKey = resolveFileKeyInput({ fileKey: pathParams.fileKey });\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n if (!resolvedConfig.storage.getDownloadUrl) {\n return error(\n { message: \"Signed URLs are not supported\", code: \"SIGNED_URL_UNSUPPORTED\" },\n 400,\n );\n }\n\n try {\n const file = await this.handlerTx()\n .withServiceCalls(() => [services.getFileByKey(resolvedKey.fileKey)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n let result;\n try {\n result = await resolvedConfig.storage.getDownloadUrl({\n storageKey: file.storageKey,\n expiresInSeconds: resolvedConfig.signedUrlExpiresInSeconds,\n contentType: file.contentType ?? undefined,\n });\n } catch {\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n\n return json(result);\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/files/:fileKey/content\",\n errorCodes,\n handler: async function ({ pathParams }, { error }) {\n const resolvedConfig = getResolvedConfig();\n let resolvedKey;\n try {\n resolvedKey = resolveFileKeyInput({ fileKey: pathParams.fileKey });\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n if (!resolvedConfig.storage.getDownloadStream) {\n return error(\n { message: \"Download streaming unsupported\", code: \"SIGNED_URL_UNSUPPORTED\" },\n 400,\n );\n }\n\n try {\n const file = await this.handlerTx()\n .withServiceCalls(() => [services.getFileByKey(resolvedKey.fileKey)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n try {\n return await resolvedConfig.storage.getDownloadStream({\n storageKey: file.storageKey,\n });\n } catch {\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n ];\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"files.js","names":["keyParts: z.infer<typeof legacyFileKeyPartsSchema> | undefined","result"],"sources":["../../../src/routes/files.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport { defineRoutes } from \"@fragno-dev/core\";\nimport type { FragnoRouteConfig } from \"@fragno-dev/core\";\n\nimport { resolveUploadFragmentConfig } from \"../config\";\nimport { uploadFragmentDefinition } from \"../definition\";\nimport { resolveFileKeyInput } from \"../services/helpers\";\nimport { buildStorageObjectVersionSegment } from \"../storage/object-key\";\nimport {\n checksumSchema,\n fileMetadataSchema,\n providerNamespaceSchema,\n toFileMetadata,\n visibilitySchema,\n} from \"./shared\";\n\nconst legacyFileKeyPartsSchema = z.array(z.union([z.string(), z.number().int()]));\n\nconst listQuerySchema = z.object({\n provider: providerNamespaceSchema.optional(),\n prefix: z.string().optional(),\n cursor: z.string().optional(),\n pageSize: z.coerce.number().min(1).max(100).catch(25),\n status: z.enum([\"ready\", \"deleted\"]).optional(),\n uploaderId: z.string().optional(),\n});\n\nconst byKeyQuerySchema = z.object({\n provider: providerNamespaceSchema,\n key: z.string().min(1),\n});\n\nconst updateFileSchema = z.object({\n filename: z.string().min(1).optional(),\n visibility: visibilitySchema.optional(),\n tags: z.array(z.string()).nullable().optional(),\n metadata: z.record(z.string(), z.unknown()).nullable().optional(),\n});\n\nconst errorCodes = [\n \"UPLOAD_NOT_FOUND\",\n \"UPLOAD_ALREADY_ACTIVE\",\n \"FILE_ALREADY_EXISTS\",\n \"FILE_NOT_FOUND\",\n \"FILE_DELETED\",\n \"UPLOAD_EXPIRED\",\n \"UPLOAD_INVALID_STATE\",\n \"SIGNED_URL_UNSUPPORTED\",\n \"STORAGE_ERROR\",\n \"INVALID_FILE_KEY\",\n \"INVALID_CHECKSUM\",\n \"INVALID_REQUEST\",\n] as const;\n\ntype FileErrorCode = (typeof errorCodes)[number];\n\ntype ErrorFn<Code extends string> = Parameters<\n FragnoRouteConfig<\"GET\", \"/__error\", undefined, undefined, Code>[\"handler\"]\n>[1][\"error\"];\n\nconst handleServiceError = <Code extends FileErrorCode>(\n err: unknown,\n error: ErrorFn<Code>,\n): Response => {\n if (!(err instanceof Error)) {\n throw err;\n }\n\n switch (err.message) {\n case \"FILE_NOT_FOUND\":\n return error({ message: \"File not found\", code: \"FILE_NOT_FOUND\" as Code }, 404);\n case \"FILE_DELETED\":\n return error({ message: \"File deleted\", code: \"FILE_DELETED\" as Code }, 410);\n case \"UPLOAD_NOT_FOUND\":\n return error({ message: \"Upload not found\", code: \"UPLOAD_NOT_FOUND\" as Code }, 404);\n case \"FILE_ALREADY_EXISTS\":\n return error({ message: \"File already exists\", code: \"FILE_ALREADY_EXISTS\" as Code }, 409);\n case \"UPLOAD_ALREADY_ACTIVE\":\n return error(\n {\n message: \"Upload already active\",\n code: \"UPLOAD_ALREADY_ACTIVE\" as Code,\n },\n 409,\n );\n case \"UPLOAD_EXPIRED\":\n return error({ message: \"Upload expired\", code: \"UPLOAD_EXPIRED\" as Code }, 410);\n case \"UPLOAD_INVALID_STATE\":\n return error(\n {\n message: \"Upload invalid state\",\n code: \"UPLOAD_INVALID_STATE\" as Code,\n },\n 409,\n );\n case \"INVALID_FILE_KEY\":\n return error({ message: \"Invalid file key\", code: \"INVALID_FILE_KEY\" as Code }, 400);\n case \"INVALID_CHECKSUM\":\n return error({ message: \"Invalid checksum\", code: \"INVALID_CHECKSUM\" as Code }, 400);\n case \"INVALID_REQUEST\":\n return error({ message: \"Invalid request\", code: \"INVALID_REQUEST\" as Code }, 400);\n case \"STORAGE_ERROR\":\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" as Code }, 502);\n default:\n throw err;\n }\n};\n\nconst parseJson = <T>(value: FormDataEntryValue | null): T | undefined => {\n if (value === null || typeof value !== \"string\" || value.length === 0) {\n return undefined;\n }\n try {\n return JSON.parse(value) as T;\n } catch {\n return undefined;\n }\n};\n\nconst parseTags = (value: FormDataEntryValue | null): string[] | undefined => {\n if (value === null) {\n return undefined;\n }\n if (typeof value !== \"string\") {\n return undefined;\n }\n const parsed = parseJson<unknown>(value);\n if (Array.isArray(parsed)) {\n return parsed.filter((tag) => typeof tag === \"string\") as string[];\n }\n if (typeof value === \"string\" && value.length > 0) {\n return [value];\n }\n return undefined;\n};\n\nconst parseMetadata = (value: FormDataEntryValue | null): Record<string, unknown> | undefined => {\n const parsed = parseJson<unknown>(value);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n return undefined;\n};\n\nconst assertFileAvailable = <T extends { status: string }>(file: T) => {\n if (file.status === \"deleted\") {\n throw new Error(\"FILE_DELETED\");\n }\n return file;\n};\n\nexport const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(\n ({ services, defineRoute, config }) => {\n const getResolvedConfig = () => resolveUploadFragmentConfig(config);\n\n const parseListQuery = (query: URLSearchParams) => {\n const result = listQuerySchema.safeParse({\n provider: query.has(\"provider\") ? query.get(\"provider\") : undefined,\n prefix: query.get(\"prefix\") || undefined,\n cursor: query.get(\"cursor\") || undefined,\n pageSize: query.get(\"pageSize\"),\n status: query.get(\"status\") || undefined,\n uploaderId: query.get(\"uploaderId\") || undefined,\n });\n if (!result.success) {\n throw new Error(\"INVALID_REQUEST\");\n }\n return result.data;\n };\n\n const parseByKeyQuery = (query: URLSearchParams) => {\n const result = byKeyQuerySchema.safeParse({\n provider: query.get(\"provider\"),\n key: query.get(\"key\"),\n });\n if (!result.success) {\n throw new Error(\"INVALID_REQUEST\");\n }\n\n try {\n const resolvedKey = resolveFileKeyInput({ fileKey: result.data.key });\n return {\n provider: result.data.provider,\n fileKey: resolvedKey.fileKey,\n };\n } catch {\n throw new Error(\"INVALID_FILE_KEY\");\n }\n };\n\n return [\n defineRoute({\n method: \"POST\",\n path: \"/files\",\n contentType: \"multipart/form-data\",\n outputSchema: fileMetadataSchema,\n errorCodes,\n handler: async function (context, { json, error }) {\n const resolvedConfig = getResolvedConfig();\n const form = context.formData();\n const file = form.get(\"file\");\n if (!(file instanceof Blob)) {\n return error({ message: \"File is required\", code: \"INVALID_REQUEST\" }, 400);\n }\n\n const providerValue = form.get(\"provider\");\n const providerResult = providerNamespaceSchema.safeParse(providerValue);\n if (!providerResult.success) {\n return error({ message: \"Invalid request\", code: \"INVALID_REQUEST\" }, 400);\n }\n const provider = providerResult.data;\n\n let keyParts: z.infer<typeof legacyFileKeyPartsSchema> | undefined;\n if (form.has(\"keyParts\")) {\n const parsed = parseJson<unknown>(form.get(\"keyParts\"));\n const result = legacyFileKeyPartsSchema.safeParse(parsed);\n if (!result.success) {\n return error({ message: \"Invalid file key\", code: \"INVALID_FILE_KEY\" }, 400);\n }\n keyParts = result.data;\n }\n\n const fileKeyValue = form.get(\"fileKey\");\n const fileKey = typeof fileKeyValue === \"string\" ? fileKeyValue : undefined;\n\n const checksumValue = form.get(\"checksum\");\n const parsedChecksum = parseJson<unknown>(checksumValue);\n const checksumResult = checksumSchema.safeParse(parsedChecksum);\n if (!checksumResult.success) {\n return error({ message: \"Invalid checksum\", code: \"INVALID_CHECKSUM\" }, 400);\n }\n\n const tags = parseTags(form.get(\"tags\"));\n const metadata = parseMetadata(form.get(\"metadata\"));\n\n let resolvedKey;\n try {\n resolvedKey = resolveFileKeyInput({\n keyParts,\n fileKey: fileKey ?? undefined,\n });\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n const checksumForStorage = checksumResult.data ?? null;\n const checksumForRecord = checksumResult.data ?? undefined;\n\n let storageInit;\n\n const uploaderIdValue = form.get(\"uploaderId\");\n const uploaderId = typeof uploaderIdValue === \"string\" ? uploaderIdValue : undefined;\n const visibilityValue = form.get(\"visibility\");\n const parsedVisibility =\n typeof visibilityValue === \"string\" ? visibilityValue : undefined;\n const visibilityResult = visibilitySchema.optional().safeParse(parsedVisibility);\n if (!visibilityResult.success) {\n return error({ message: \"Invalid request\", code: \"INVALID_REQUEST\" }, 400);\n }\n const visibility = visibilityResult.data;\n const filenameValue = form.get(\"filename\");\n const filename =\n typeof filenameValue === \"string\" && filenameValue\n ? filenameValue\n : file instanceof File && file.name\n ? file.name\n : \"upload\";\n const contentType = file.type || \"application/octet-stream\";\n\n const objectKeyVersionSegment = buildStorageObjectVersionSegment();\n\n const createInput = {\n provider,\n fileKey: resolvedKey.fileKey,\n keyParts: resolvedKey.fileKeyParts,\n filename,\n sizeBytes: file.size,\n contentType,\n checksum: checksumForRecord,\n tags,\n visibility,\n uploaderId,\n metadata,\n };\n\n try {\n storageInit = await resolvedConfig.storage.initUpload({\n provider,\n fileKey: resolvedKey.fileKey,\n sizeBytes: BigInt(file.size),\n contentType,\n checksum: checksumForStorage,\n metadata: metadata ?? null,\n objectKeyVersionSegment,\n });\n } catch {\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n\n if (storageInit.strategy === \"direct-multipart\") {\n if (resolvedConfig.storage.abortMultipartUpload && storageInit.storageUploadId) {\n try {\n await resolvedConfig.storage.abortMultipartUpload({\n storageKey: storageInit.storageKey,\n storageUploadId: storageInit.storageUploadId,\n });\n } catch {\n // Ignore abort failures; the request is still invalid for this endpoint.\n }\n }\n\n return error({ message: \"Upload invalid state\", code: \"UPLOAD_INVALID_STATE\" }, 409);\n }\n\n try {\n if (storageInit.strategy === \"proxy\") {\n if (!resolvedConfig.storage.writeStream) {\n throw new Error(\"STORAGE_ERROR\");\n }\n await resolvedConfig.storage.writeStream({\n storageKey: storageInit.storageKey,\n body: file.stream(),\n contentType,\n sizeBytes: BigInt(file.size),\n });\n } else if (storageInit.strategy === \"direct-single\") {\n if (!storageInit.uploadUrl) {\n throw new Error(\"STORAGE_ERROR\");\n }\n const response = await fetch(storageInit.uploadUrl, {\n method: \"PUT\",\n headers: storageInit.uploadHeaders,\n body: file,\n });\n if (!response.ok) {\n throw new Error(\"STORAGE_ERROR\");\n }\n } else {\n return error(\n {\n message: \"Upload invalid state\",\n code: \"UPLOAD_INVALID_STATE\",\n },\n 409,\n );\n }\n\n if (resolvedConfig.storage.finalizeUpload) {\n await resolvedConfig.storage.finalizeUpload({\n storageKey: storageInit.storageKey,\n expectedSizeBytes: BigInt(file.size),\n checksum: checksumResult.data ?? null,\n });\n }\n } catch {\n await this.handlerTx()\n .withServiceCalls(() => [\n services.createFailedUpload({\n ...createInput,\n storageInit,\n errorCode: \"STORAGE_ERROR\",\n errorMessage: \"Storage upload failed\",\n }),\n ])\n .execute();\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n\n try {\n const completed = await this.handlerTx()\n .withServiceCalls(() => [\n services.createCompletedUpload({\n ...createInput,\n storageInit,\n completedSizeBytes: BigInt(file.size),\n }),\n ])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n return json(toFileMetadata(completed.file));\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/files\",\n queryParameters: [\"provider\", \"prefix\", \"cursor\", \"pageSize\", \"status\", \"uploaderId\"],\n outputSchema: z.object({\n files: z.array(fileMetadataSchema),\n cursor: z.string().optional(),\n hasNextPage: z.boolean(),\n }),\n errorCodes,\n handler: async function ({ query }, { json, error }) {\n let params;\n try {\n params = parseListQuery(query);\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n const result = await this.handlerTx()\n .withServiceCalls(() => [\n services.listFiles({\n provider: params.provider,\n prefix: params.prefix,\n pageSize: params.pageSize,\n cursor: params.cursor,\n status: params.status,\n uploaderId: params.uploaderId,\n }),\n ])\n .transform(({ serviceResult: [files] }) => files)\n .execute();\n\n return json({\n files: result.items.map(toFileMetadata),\n cursor: result.cursor?.encode(),\n hasNextPage: result.hasNextPage,\n });\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/files/by-key\",\n queryParameters: [\"provider\", \"key\"],\n outputSchema: fileMetadataSchema,\n errorCodes,\n handler: async function ({ query }, { json, error }) {\n let byKey;\n try {\n byKey = parseByKeyQuery(query);\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n try {\n const file = await this.handlerTx()\n .withServiceCalls(() => [services.getFileByKey(byKey)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n return json(toFileMetadata(file));\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"PATCH\",\n path: \"/files/by-key\",\n queryParameters: [\"provider\", \"key\"],\n inputSchema: updateFileSchema,\n outputSchema: fileMetadataSchema,\n errorCodes,\n handler: async function ({ query, input }, { json, error }) {\n const payload = await input.valid();\n let byKey;\n try {\n byKey = parseByKeyQuery(query);\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n try {\n const file = await this.handlerTx()\n .withServiceCalls(() => [services.updateFile(byKey, payload)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n return json(toFileMetadata(file));\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"DELETE\",\n path: \"/files/by-key\",\n queryParameters: [\"provider\", \"key\"],\n outputSchema: z.object({ ok: z.literal(true) }),\n errorCodes,\n handler: async function ({ query }, { json, error }) {\n let byKey;\n try {\n byKey = parseByKeyQuery(query);\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n try {\n await this.handlerTx()\n .withServiceCalls(() => [services.markFileDeleted(byKey)])\n .execute();\n\n return json({ ok: true });\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/files/by-key/download-url\",\n queryParameters: [\"provider\", \"key\"],\n outputSchema: z.object({\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n expiresAt: z.date(),\n }),\n errorCodes,\n handler: async function ({ query }, { json, error }) {\n const resolvedConfig = getResolvedConfig();\n let byKey;\n try {\n byKey = parseByKeyQuery(query);\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n if (!resolvedConfig.storage.getDownloadUrl) {\n return error(\n {\n message: \"Signed URLs are not supported\",\n code: \"SIGNED_URL_UNSUPPORTED\",\n },\n 400,\n );\n }\n\n try {\n const file = assertFileAvailable(\n await this.handlerTx()\n .withServiceCalls(() => [services.getFileByKey(byKey)])\n .transform(({ serviceResult: [result] }) => result)\n .execute(),\n );\n\n let result;\n try {\n result = await resolvedConfig.storage.getDownloadUrl({\n storageKey: file.objectKey,\n expiresInSeconds: resolvedConfig.signedUrlExpiresInSeconds,\n contentType: file.contentType ?? undefined,\n });\n } catch {\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n\n return json(result);\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/files/by-key/content\",\n queryParameters: [\"provider\", \"key\"],\n errorCodes,\n handler: async function ({ query }, { error }) {\n const resolvedConfig = getResolvedConfig();\n let byKey;\n try {\n byKey = parseByKeyQuery(query);\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n if (!resolvedConfig.storage.getDownloadStream) {\n return error(\n {\n message: \"Download streaming unsupported\",\n code: \"SIGNED_URL_UNSUPPORTED\",\n },\n 400,\n );\n }\n\n try {\n const file = assertFileAvailable(\n await this.handlerTx()\n .withServiceCalls(() => [services.getFileByKey(byKey)])\n .transform(({ serviceResult: [result] }) => result)\n .execute(),\n );\n\n try {\n return await resolvedConfig.storage.getDownloadStream({\n storageKey: file.objectKey,\n });\n } catch {\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n ];\n },\n);\n"],"mappings":"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"}