@fragno-dev/upload 0.1.1

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 (355) hide show
  1. package/LICENSE.md +16 -0
  2. package/README.md +43 -0
  3. package/bin/run.js +5 -0
  4. package/dist/browser/client/clients.js +49 -0
  5. package/dist/browser/client/clients.js.map +1 -0
  6. package/dist/browser/client/helpers.d.ts +51 -0
  7. package/dist/browser/client/helpers.d.ts.map +1 -0
  8. package/dist/browser/client/helpers.js +242 -0
  9. package/dist/browser/client/helpers.js.map +1 -0
  10. package/dist/browser/client/node_modules/.pnpm/@nanostores_query@0.3.4_nanostores@1.1.0/node_modules/@nanostores/query/dist/nanoquery.js +354 -0
  11. package/dist/browser/client/node_modules/.pnpm/@nanostores_query@0.3.4_nanostores@1.1.0/node_modules/@nanostores/query/dist/nanoquery.js.map +1 -0
  12. package/dist/browser/client/node_modules/.pnpm/@nanostores_solid@1.1.1_nanostores@1.1.0_solid-js@1.9.10/node_modules/@nanostores/solid/dist/index.js +14 -0
  13. package/dist/browser/client/node_modules/.pnpm/@nanostores_solid@1.1.1_nanostores@1.1.0_solid-js@1.9.10/node_modules/@nanostores/solid/dist/index.js.map +1 -0
  14. package/dist/browser/client/node_modules/.pnpm/nanoevents@9.1.0/node_modules/nanoevents/index.js +17 -0
  15. package/dist/browser/client/node_modules/.pnpm/nanoevents@9.1.0/node_modules/nanoevents/index.js.map +1 -0
  16. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/atom/index.js +62 -0
  17. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/atom/index.js.map +1 -0
  18. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/clean-stores/index.js +6 -0
  19. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/clean-stores/index.js.map +1 -0
  20. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/computed/index.js +50 -0
  21. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/computed/index.js.map +1 -0
  22. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/lifecycle/index.js +99 -0
  23. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/lifecycle/index.js.map +1 -0
  24. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/listen-keys/index.js +11 -0
  25. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/listen-keys/index.js.map +1 -0
  26. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/map/index.js +25 -0
  27. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/map/index.js.map +1 -0
  28. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/task/index.js +24 -0
  29. package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/task/index.js.map +1 -0
  30. package/dist/browser/client/packages/fragment-upload/src/definition.js +49 -0
  31. package/dist/browser/client/packages/fragment-upload/src/definition.js.map +1 -0
  32. package/dist/browser/client/packages/fragment-upload/src/keys.d.ts +7 -0
  33. package/dist/browser/client/packages/fragment-upload/src/keys.d.ts.map +1 -0
  34. package/dist/browser/client/packages/fragment-upload/src/keys.js +28 -0
  35. package/dist/browser/client/packages/fragment-upload/src/keys.js.map +1 -0
  36. package/dist/browser/client/packages/fragment-upload/src/routes/files.js +98 -0
  37. package/dist/browser/client/packages/fragment-upload/src/routes/files.js.map +1 -0
  38. package/dist/browser/client/packages/fragment-upload/src/routes/index.js +9 -0
  39. package/dist/browser/client/packages/fragment-upload/src/routes/index.js.map +1 -0
  40. package/dist/browser/client/packages/fragment-upload/src/routes/shared.js +41 -0
  41. package/dist/browser/client/packages/fragment-upload/src/routes/shared.js.map +1 -0
  42. package/dist/browser/client/packages/fragment-upload/src/routes/uploads.js +186 -0
  43. package/dist/browser/client/packages/fragment-upload/src/routes/uploads.js.map +1 -0
  44. package/dist/browser/client/packages/fragment-upload/src/schema.js +8 -0
  45. package/dist/browser/client/packages/fragment-upload/src/schema.js.map +1 -0
  46. package/dist/browser/client/packages/fragment-upload/src/storage/types.d.ts +9 -0
  47. package/dist/browser/client/packages/fragment-upload/src/storage/types.d.ts.map +1 -0
  48. package/dist/browser/client/packages/fragment-upload/src/types.d.ts +31 -0
  49. package/dist/browser/client/packages/fragment-upload/src/types.d.ts.map +1 -0
  50. package/dist/browser/client/packages/fragno/dist/api/error.js +48 -0
  51. package/dist/browser/client/packages/fragno/dist/api/error.js.map +1 -0
  52. package/dist/browser/client/packages/fragno/dist/api/internal/path.js +76 -0
  53. package/dist/browser/client/packages/fragno/dist/api/internal/path.js.map +1 -0
  54. package/dist/browser/client/packages/fragno/dist/api/internal/response-stream.js +81 -0
  55. package/dist/browser/client/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
  56. package/dist/browser/client/packages/fragno/dist/api/internal/route.js +10 -0
  57. package/dist/browser/client/packages/fragno/dist/api/internal/route.js.map +1 -0
  58. package/dist/browser/client/packages/fragno/dist/api/request-input-context.js +185 -0
  59. package/dist/browser/client/packages/fragno/dist/api/request-input-context.js.map +1 -0
  60. package/dist/browser/client/packages/fragno/dist/api/request-output-context.js +119 -0
  61. package/dist/browser/client/packages/fragno/dist/api/request-output-context.js.map +1 -0
  62. package/dist/browser/client/packages/fragno/dist/api/route.js +17 -0
  63. package/dist/browser/client/packages/fragno/dist/api/route.js.map +1 -0
  64. package/dist/browser/client/packages/fragno/dist/client/client-error.js +92 -0
  65. package/dist/browser/client/packages/fragno/dist/client/client-error.js.map +1 -0
  66. package/dist/browser/client/packages/fragno/dist/client/client.js +495 -0
  67. package/dist/browser/client/packages/fragno/dist/client/client.js.map +1 -0
  68. package/dist/browser/client/packages/fragno/dist/client/client.svelte.js +120 -0
  69. package/dist/browser/client/packages/fragno/dist/client/client.svelte.js.map +1 -0
  70. package/dist/browser/client/packages/fragno/dist/client/internal/fetcher-merge.js +36 -0
  71. package/dist/browser/client/packages/fragno/dist/client/internal/fetcher-merge.js.map +1 -0
  72. package/dist/browser/client/packages/fragno/dist/client/internal/ndjson-streaming.js +139 -0
  73. package/dist/browser/client/packages/fragno/dist/client/internal/ndjson-streaming.js.map +1 -0
  74. package/dist/browser/client/packages/fragno/dist/client/react.js +70 -0
  75. package/dist/browser/client/packages/fragno/dist/client/react.js.map +1 -0
  76. package/dist/browser/client/packages/fragno/dist/client/solid.js +108 -0
  77. package/dist/browser/client/packages/fragno/dist/client/solid.js.map +1 -0
  78. package/dist/browser/client/packages/fragno/dist/client/vanilla.js +96 -0
  79. package/dist/browser/client/packages/fragno/dist/client/vanilla.js.map +1 -0
  80. package/dist/browser/client/packages/fragno/dist/client/vue.js +120 -0
  81. package/dist/browser/client/packages/fragno/dist/client/vue.js.map +1 -0
  82. package/dist/browser/client/packages/fragno/dist/util/async.js +40 -0
  83. package/dist/browser/client/packages/fragno/dist/util/async.js.map +1 -0
  84. package/dist/browser/client/packages/fragno/dist/util/content-type.js +49 -0
  85. package/dist/browser/client/packages/fragno/dist/util/content-type.js.map +1 -0
  86. package/dist/browser/client/packages/fragno/dist/util/nanostores.js +31 -0
  87. package/dist/browser/client/packages/fragno/dist/util/nanostores.js.map +1 -0
  88. package/dist/browser/client/packages/fragno/dist/util/ssr.js +18 -0
  89. package/dist/browser/client/packages/fragno/dist/util/ssr.js.map +1 -0
  90. package/dist/browser/client/react.d.ts +295 -0
  91. package/dist/browser/client/react.d.ts.map +1 -0
  92. package/dist/browser/client/react.js +11 -0
  93. package/dist/browser/client/react.js.map +1 -0
  94. package/dist/browser/client/solid.d.ts +303 -0
  95. package/dist/browser/client/solid.d.ts.map +1 -0
  96. package/dist/browser/client/solid.js +11 -0
  97. package/dist/browser/client/solid.js.map +1 -0
  98. package/dist/browser/client/svelte.d.ts +295 -0
  99. package/dist/browser/client/svelte.d.ts.map +1 -0
  100. package/dist/browser/client/svelte.js +11 -0
  101. package/dist/browser/client/svelte.js.map +1 -0
  102. package/dist/browser/client/vanilla.d.ts +296 -0
  103. package/dist/browser/client/vanilla.d.ts.map +1 -0
  104. package/dist/browser/client/vanilla.js +11 -0
  105. package/dist/browser/client/vanilla.js.map +1 -0
  106. package/dist/browser/client/vue.d.ts +295 -0
  107. package/dist/browser/client/vue.d.ts.map +1 -0
  108. package/dist/browser/client/vue.js +11 -0
  109. package/dist/browser/client/vue.js.map +1 -0
  110. package/dist/browser/index-BdjKPO4J.d.ts +177 -0
  111. package/dist/browser/index-BdjKPO4J.d.ts.map +1 -0
  112. package/dist/browser/index.js +3 -0
  113. package/dist/browser/src-vdNJUbjT.js +1982 -0
  114. package/dist/browser/src-vdNJUbjT.js.map +1 -0
  115. package/dist/cli/commands/files/delete.d.ts +40 -0
  116. package/dist/cli/commands/files/delete.d.ts.map +1 -0
  117. package/dist/cli/commands/files/delete.js +31 -0
  118. package/dist/cli/commands/files/delete.js.map +1 -0
  119. package/dist/cli/commands/files/download-url.d.ts +40 -0
  120. package/dist/cli/commands/files/download-url.d.ts.map +1 -0
  121. package/dist/cli/commands/files/download-url.js +31 -0
  122. package/dist/cli/commands/files/download-url.js.map +1 -0
  123. package/dist/cli/commands/files/download.d.ts +49 -0
  124. package/dist/cli/commands/files/download.d.ts.map +1 -0
  125. package/dist/cli/commands/files/download.js +65 -0
  126. package/dist/cli/commands/files/download.js.map +1 -0
  127. package/dist/cli/commands/files/get.d.ts +40 -0
  128. package/dist/cli/commands/files/get.d.ts.map +1 -0
  129. package/dist/cli/commands/files/get.js +31 -0
  130. package/dist/cli/commands/files/get.js.map +1 -0
  131. package/dist/cli/commands/files/list.d.ts +56 -0
  132. package/dist/cli/commands/files/list.d.ts.map +1 -0
  133. package/dist/cli/commands/files/list.js +53 -0
  134. package/dist/cli/commands/files/list.js.map +1 -0
  135. package/dist/cli/commands/files/update.d.ts +56 -0
  136. package/dist/cli/commands/files/update.d.ts.map +1 -0
  137. package/dist/cli/commands/files/update.js +53 -0
  138. package/dist/cli/commands/files/update.js.map +1 -0
  139. package/dist/cli/commands/files/upload.d.ts +73 -0
  140. package/dist/cli/commands/files/upload.d.ts.map +1 -0
  141. package/dist/cli/commands/files/upload.js +87 -0
  142. package/dist/cli/commands/files/upload.js.map +1 -0
  143. package/dist/cli/commands/uploads/abort.d.ts +37 -0
  144. package/dist/cli/commands/uploads/abort.d.ts.map +1 -0
  145. package/dist/cli/commands/uploads/abort.js +26 -0
  146. package/dist/cli/commands/uploads/abort.js.map +1 -0
  147. package/dist/cli/commands/uploads/complete.d.ts +41 -0
  148. package/dist/cli/commands/uploads/complete.d.ts.map +1 -0
  149. package/dist/cli/commands/uploads/complete.js +45 -0
  150. package/dist/cli/commands/uploads/complete.js.map +1 -0
  151. package/dist/cli/commands/uploads/content.d.ts +46 -0
  152. package/dist/cli/commands/uploads/content.d.ts.map +1 -0
  153. package/dist/cli/commands/uploads/content.js +43 -0
  154. package/dist/cli/commands/uploads/content.js.map +1 -0
  155. package/dist/cli/commands/uploads/create.d.ts +72 -0
  156. package/dist/cli/commands/uploads/create.d.ts.map +1 -0
  157. package/dist/cli/commands/uploads/create.js +84 -0
  158. package/dist/cli/commands/uploads/create.js.map +1 -0
  159. package/dist/cli/commands/uploads/get.d.ts +37 -0
  160. package/dist/cli/commands/uploads/get.d.ts.map +1 -0
  161. package/dist/cli/commands/uploads/get.js +26 -0
  162. package/dist/cli/commands/uploads/get.js.map +1 -0
  163. package/dist/cli/commands/uploads/parts-complete.d.ts +41 -0
  164. package/dist/cli/commands/uploads/parts-complete.d.ts.map +1 -0
  165. package/dist/cli/commands/uploads/parts-complete.js +44 -0
  166. package/dist/cli/commands/uploads/parts-complete.js.map +1 -0
  167. package/dist/cli/commands/uploads/parts-list.d.ts +37 -0
  168. package/dist/cli/commands/uploads/parts-list.d.ts.map +1 -0
  169. package/dist/cli/commands/uploads/parts-list.js +26 -0
  170. package/dist/cli/commands/uploads/parts-list.js.map +1 -0
  171. package/dist/cli/commands/uploads/parts-urls.d.ts +46 -0
  172. package/dist/cli/commands/uploads/parts-urls.d.ts.map +1 -0
  173. package/dist/cli/commands/uploads/parts-urls.js +57 -0
  174. package/dist/cli/commands/uploads/parts-urls.js.map +1 -0
  175. package/dist/cli/commands/uploads/progress.d.ts +45 -0
  176. package/dist/cli/commands/uploads/progress.d.ts.map +1 -0
  177. package/dist/cli/commands/uploads/progress.js +40 -0
  178. package/dist/cli/commands/uploads/progress.js.map +1 -0
  179. package/dist/cli/commands/uploads/transfer.d.ts +73 -0
  180. package/dist/cli/commands/uploads/transfer.d.ts.map +1 -0
  181. package/dist/cli/commands/uploads/transfer.js +170 -0
  182. package/dist/cli/commands/uploads/transfer.js.map +1 -0
  183. package/dist/cli/index.d.ts +27 -0
  184. package/dist/cli/index.d.ts.map +1 -0
  185. package/dist/cli/index.js +198 -0
  186. package/dist/cli/index.js.map +1 -0
  187. package/dist/cli/keys.js +32 -0
  188. package/dist/cli/keys.js.map +1 -0
  189. package/dist/cli/utils/client.js +174 -0
  190. package/dist/cli/utils/client.js.map +1 -0
  191. package/dist/cli/utils/options.js +135 -0
  192. package/dist/cli/utils/options.js.map +1 -0
  193. package/dist/node/cli/commands/files/delete.d.ts +40 -0
  194. package/dist/node/cli/commands/files/delete.d.ts.map +1 -0
  195. package/dist/node/cli/commands/files/delete.js +31 -0
  196. package/dist/node/cli/commands/files/delete.js.map +1 -0
  197. package/dist/node/cli/commands/files/download-url.d.ts +40 -0
  198. package/dist/node/cli/commands/files/download-url.d.ts.map +1 -0
  199. package/dist/node/cli/commands/files/download-url.js +31 -0
  200. package/dist/node/cli/commands/files/download-url.js.map +1 -0
  201. package/dist/node/cli/commands/files/download.d.ts +49 -0
  202. package/dist/node/cli/commands/files/download.d.ts.map +1 -0
  203. package/dist/node/cli/commands/files/download.js +65 -0
  204. package/dist/node/cli/commands/files/download.js.map +1 -0
  205. package/dist/node/cli/commands/files/get.d.ts +40 -0
  206. package/dist/node/cli/commands/files/get.d.ts.map +1 -0
  207. package/dist/node/cli/commands/files/get.js +31 -0
  208. package/dist/node/cli/commands/files/get.js.map +1 -0
  209. package/dist/node/cli/commands/files/list.d.ts +56 -0
  210. package/dist/node/cli/commands/files/list.d.ts.map +1 -0
  211. package/dist/node/cli/commands/files/list.js +53 -0
  212. package/dist/node/cli/commands/files/list.js.map +1 -0
  213. package/dist/node/cli/commands/files/update.d.ts +56 -0
  214. package/dist/node/cli/commands/files/update.d.ts.map +1 -0
  215. package/dist/node/cli/commands/files/update.js +53 -0
  216. package/dist/node/cli/commands/files/update.js.map +1 -0
  217. package/dist/node/cli/commands/files/upload.d.ts +73 -0
  218. package/dist/node/cli/commands/files/upload.d.ts.map +1 -0
  219. package/dist/node/cli/commands/files/upload.js +87 -0
  220. package/dist/node/cli/commands/files/upload.js.map +1 -0
  221. package/dist/node/cli/commands/uploads/abort.d.ts +37 -0
  222. package/dist/node/cli/commands/uploads/abort.d.ts.map +1 -0
  223. package/dist/node/cli/commands/uploads/abort.js +26 -0
  224. package/dist/node/cli/commands/uploads/abort.js.map +1 -0
  225. package/dist/node/cli/commands/uploads/complete.d.ts +41 -0
  226. package/dist/node/cli/commands/uploads/complete.d.ts.map +1 -0
  227. package/dist/node/cli/commands/uploads/complete.js +45 -0
  228. package/dist/node/cli/commands/uploads/complete.js.map +1 -0
  229. package/dist/node/cli/commands/uploads/content.d.ts +46 -0
  230. package/dist/node/cli/commands/uploads/content.d.ts.map +1 -0
  231. package/dist/node/cli/commands/uploads/content.js +43 -0
  232. package/dist/node/cli/commands/uploads/content.js.map +1 -0
  233. package/dist/node/cli/commands/uploads/create.d.ts +72 -0
  234. package/dist/node/cli/commands/uploads/create.d.ts.map +1 -0
  235. package/dist/node/cli/commands/uploads/create.js +84 -0
  236. package/dist/node/cli/commands/uploads/create.js.map +1 -0
  237. package/dist/node/cli/commands/uploads/get.d.ts +37 -0
  238. package/dist/node/cli/commands/uploads/get.d.ts.map +1 -0
  239. package/dist/node/cli/commands/uploads/get.js +26 -0
  240. package/dist/node/cli/commands/uploads/get.js.map +1 -0
  241. package/dist/node/cli/commands/uploads/parts-complete.d.ts +41 -0
  242. package/dist/node/cli/commands/uploads/parts-complete.d.ts.map +1 -0
  243. package/dist/node/cli/commands/uploads/parts-complete.js +44 -0
  244. package/dist/node/cli/commands/uploads/parts-complete.js.map +1 -0
  245. package/dist/node/cli/commands/uploads/parts-list.d.ts +37 -0
  246. package/dist/node/cli/commands/uploads/parts-list.d.ts.map +1 -0
  247. package/dist/node/cli/commands/uploads/parts-list.js +26 -0
  248. package/dist/node/cli/commands/uploads/parts-list.js.map +1 -0
  249. package/dist/node/cli/commands/uploads/parts-urls.d.ts +46 -0
  250. package/dist/node/cli/commands/uploads/parts-urls.d.ts.map +1 -0
  251. package/dist/node/cli/commands/uploads/parts-urls.js +57 -0
  252. package/dist/node/cli/commands/uploads/parts-urls.js.map +1 -0
  253. package/dist/node/cli/commands/uploads/progress.d.ts +45 -0
  254. package/dist/node/cli/commands/uploads/progress.d.ts.map +1 -0
  255. package/dist/node/cli/commands/uploads/progress.js +40 -0
  256. package/dist/node/cli/commands/uploads/progress.js.map +1 -0
  257. package/dist/node/cli/commands/uploads/transfer.d.ts +73 -0
  258. package/dist/node/cli/commands/uploads/transfer.d.ts.map +1 -0
  259. package/dist/node/cli/commands/uploads/transfer.js +170 -0
  260. package/dist/node/cli/commands/uploads/transfer.js.map +1 -0
  261. package/dist/node/cli/index.d.ts +27 -0
  262. package/dist/node/cli/index.d.ts.map +1 -0
  263. package/dist/node/cli/index.js +198 -0
  264. package/dist/node/cli/index.js.map +1 -0
  265. package/dist/node/cli/utils/client.js +174 -0
  266. package/dist/node/cli/utils/client.js.map +1 -0
  267. package/dist/node/cli/utils/options.js +135 -0
  268. package/dist/node/cli/utils/options.js.map +1 -0
  269. package/dist/node/client/clients.d.ts +295 -0
  270. package/dist/node/client/clients.d.ts.map +1 -0
  271. package/dist/node/client/clients.js +49 -0
  272. package/dist/node/client/clients.js.map +1 -0
  273. package/dist/node/client/helpers.d.ts +51 -0
  274. package/dist/node/client/helpers.d.ts.map +1 -0
  275. package/dist/node/client/helpers.js +242 -0
  276. package/dist/node/client/helpers.js.map +1 -0
  277. package/dist/node/client/react.d.ts +295 -0
  278. package/dist/node/client/react.d.ts.map +1 -0
  279. package/dist/node/client/react.js +11 -0
  280. package/dist/node/client/react.js.map +1 -0
  281. package/dist/node/client/solid.d.ts +303 -0
  282. package/dist/node/client/solid.d.ts.map +1 -0
  283. package/dist/node/client/solid.js +11 -0
  284. package/dist/node/client/solid.js.map +1 -0
  285. package/dist/node/client/svelte.d.ts +295 -0
  286. package/dist/node/client/svelte.d.ts.map +1 -0
  287. package/dist/node/client/svelte.js +11 -0
  288. package/dist/node/client/svelte.js.map +1 -0
  289. package/dist/node/client/vanilla.d.ts +296 -0
  290. package/dist/node/client/vanilla.d.ts.map +1 -0
  291. package/dist/node/client/vanilla.js +11 -0
  292. package/dist/node/client/vanilla.js.map +1 -0
  293. package/dist/node/client/vue.d.ts +295 -0
  294. package/dist/node/client/vue.d.ts.map +1 -0
  295. package/dist/node/client/vue.js +11 -0
  296. package/dist/node/client/vue.js.map +1 -0
  297. package/dist/node/config.d.ts +41 -0
  298. package/dist/node/config.d.ts.map +1 -0
  299. package/dist/node/config.js +26 -0
  300. package/dist/node/config.js.map +1 -0
  301. package/dist/node/definition.d.ts +829 -0
  302. package/dist/node/definition.d.ts.map +1 -0
  303. package/dist/node/definition.js +59 -0
  304. package/dist/node/definition.js.map +1 -0
  305. package/dist/node/index.d.ts +1246 -0
  306. package/dist/node/index.d.ts.map +1 -0
  307. package/dist/node/index.js +19 -0
  308. package/dist/node/index.js.map +1 -0
  309. package/dist/node/keys.d.ts +12 -0
  310. package/dist/node/keys.d.ts.map +1 -0
  311. package/dist/node/keys.js +63 -0
  312. package/dist/node/keys.js.map +1 -0
  313. package/dist/node/routes/files.js +450 -0
  314. package/dist/node/routes/files.js.map +1 -0
  315. package/dist/node/routes/index.d.ts +2023 -0
  316. package/dist/node/routes/index.d.ts.map +1 -0
  317. package/dist/node/routes/index.js +9 -0
  318. package/dist/node/routes/index.js.map +1 -0
  319. package/dist/node/routes/shared.js +66 -0
  320. package/dist/node/routes/shared.js.map +1 -0
  321. package/dist/node/routes/uploads.js +454 -0
  322. package/dist/node/routes/uploads.js.map +1 -0
  323. package/dist/node/schema.d.ts +14 -0
  324. package/dist/node/schema.d.ts.map +1 -0
  325. package/dist/node/schema.js +30 -0
  326. package/dist/node/schema.js.map +1 -0
  327. package/dist/node/services/files.d.ts +20 -0
  328. package/dist/node/services/files.d.ts.map +1 -0
  329. package/dist/node/services/files.js +93 -0
  330. package/dist/node/services/files.js.map +1 -0
  331. package/dist/node/services/helpers.js +36 -0
  332. package/dist/node/services/helpers.js.map +1 -0
  333. package/dist/node/services/index.js +4 -0
  334. package/dist/node/services/uploads.d.ts +50 -0
  335. package/dist/node/services/uploads.d.ts.map +1 -0
  336. package/dist/node/services/uploads.js +358 -0
  337. package/dist/node/services/uploads.js.map +1 -0
  338. package/dist/node/storage/fs.d.ts +16 -0
  339. package/dist/node/storage/fs.d.ts.map +1 -0
  340. package/dist/node/storage/fs.js +94 -0
  341. package/dist/node/storage/fs.js.map +1 -0
  342. package/dist/node/storage/r2.d.ts +103 -0
  343. package/dist/node/storage/r2.d.ts.map +1 -0
  344. package/dist/node/storage/r2.js +23 -0
  345. package/dist/node/storage/r2.js.map +1 -0
  346. package/dist/node/storage/s3.d.ts +44 -0
  347. package/dist/node/storage/s3.d.ts.map +1 -0
  348. package/dist/node/storage/s3.js +398 -0
  349. package/dist/node/storage/s3.js.map +1 -0
  350. package/dist/node/storage/types.d.ts +118 -0
  351. package/dist/node/storage/types.d.ts.map +1 -0
  352. package/dist/node/types.d.ts +32 -0
  353. package/dist/node/types.d.ts.map +1 -0
  354. package/dist/tsconfig.tsbuildinfo +1 -0
  355. package/package.json +105 -0
@@ -0,0 +1,99 @@
1
+ import { clean } from "../clean-stores/index.js";
2
+
3
+ //#region ../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/lifecycle/index.js
4
+ const START = 0;
5
+ const STOP = 1;
6
+ const MOUNT = 5;
7
+ const UNMOUNT = 6;
8
+ const REVERT_MUTATION = 10;
9
+ let on = (object, listener, eventKey, mutateStore) => {
10
+ object.events = object.events || {};
11
+ if (!object.events[eventKey + REVERT_MUTATION]) object.events[eventKey + REVERT_MUTATION] = mutateStore((eventProps) => {
12
+ object.events[eventKey].reduceRight((event, l) => (l(event), event), {
13
+ shared: {},
14
+ ...eventProps
15
+ });
16
+ });
17
+ object.events[eventKey] = object.events[eventKey] || [];
18
+ object.events[eventKey].push(listener);
19
+ return () => {
20
+ let currentListeners = object.events[eventKey];
21
+ let index = currentListeners.indexOf(listener);
22
+ currentListeners.splice(index, 1);
23
+ if (!currentListeners.length) {
24
+ delete object.events[eventKey];
25
+ object.events[eventKey + REVERT_MUTATION]();
26
+ delete object.events[eventKey + REVERT_MUTATION];
27
+ }
28
+ };
29
+ };
30
+ let onStart = ($store, listener) => on($store, listener, START, (runListeners) => {
31
+ let originListen = $store.listen;
32
+ $store.listen = (arg) => {
33
+ if (!$store.lc && !$store.starting) {
34
+ $store.starting = true;
35
+ runListeners();
36
+ delete $store.starting;
37
+ }
38
+ return originListen(arg);
39
+ };
40
+ return () => {
41
+ $store.listen = originListen;
42
+ };
43
+ });
44
+ let onStop = ($store, listener) => on($store, listener, STOP, (runListeners) => {
45
+ let originOff = $store.off;
46
+ $store.off = () => {
47
+ runListeners();
48
+ originOff();
49
+ };
50
+ return () => {
51
+ $store.off = originOff;
52
+ };
53
+ });
54
+ let STORE_UNMOUNT_DELAY = 1e3;
55
+ let onMount = ($store, initialize) => {
56
+ let listener = (payload) => {
57
+ let destroy = initialize(payload);
58
+ if (destroy) $store.events[UNMOUNT].push(destroy);
59
+ };
60
+ return on($store, listener, MOUNT, (runListeners) => {
61
+ let originListen = $store.listen;
62
+ $store.listen = (...args) => {
63
+ if (!$store.lc && !$store.active) {
64
+ $store.active = true;
65
+ runListeners();
66
+ }
67
+ return originListen(...args);
68
+ };
69
+ let originOff = $store.off;
70
+ $store.events[UNMOUNT] = [];
71
+ $store.off = () => {
72
+ originOff();
73
+ setTimeout(() => {
74
+ if ($store.active && !$store.lc) {
75
+ $store.active = false;
76
+ for (let destroy of $store.events[UNMOUNT]) destroy();
77
+ $store.events[UNMOUNT] = [];
78
+ }
79
+ }, STORE_UNMOUNT_DELAY);
80
+ };
81
+ {
82
+ let originClean = $store[clean];
83
+ $store[clean] = () => {
84
+ for (let destroy of $store.events[UNMOUNT]) destroy();
85
+ $store.events[UNMOUNT] = [];
86
+ $store.active = false;
87
+ originClean();
88
+ };
89
+ }
90
+ return () => {
91
+ $store.listen = originListen;
92
+ $store.off = originOff;
93
+ };
94
+ });
95
+ };
96
+
97
+ //#endregion
98
+ export { onMount, onStart, onStop };
99
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["clean","START","STOP","SET","NOTIFY","MOUNT","UNMOUNT","REVERT_MUTATION","on","object","listener","eventKey","mutateStore","events","eventProps","reduceRight","event","l","shared","push","currentListeners","index","indexOf","splice","length","onStart","$store","runListeners","originListen","listen","arg","lc","starting","onStop","originOff","off","onSet","originSet","set","originSetKey","setKey","changed","changedValue","isAborted","abort","newValue","value","onNotify","originNotify","notify","oldValue","STORE_UNMOUNT_DELAY","onMount","initialize","payload","destroy","args","active","setTimeout","process","env","NODE_ENV","originClean"],"sources":["../../../../../../../../../../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/lifecycle/index.js"],"sourcesContent":["import { clean } from '../clean-stores/index.js'\n\nconst START = 0\nconst STOP = 1\nconst SET = 2\nconst NOTIFY = 3\nconst MOUNT = 5\nconst UNMOUNT = 6\nconst REVERT_MUTATION = 10\n\nexport let on = (object, listener, eventKey, mutateStore) => {\n object.events = object.events || {}\n if (!object.events[eventKey + REVERT_MUTATION]) {\n object.events[eventKey + REVERT_MUTATION] = mutateStore(eventProps => {\n // eslint-disable-next-line no-sequences\n object.events[eventKey].reduceRight((event, l) => (l(event), event), {\n shared: {},\n ...eventProps\n })\n })\n }\n object.events[eventKey] = object.events[eventKey] || []\n object.events[eventKey].push(listener)\n return () => {\n let currentListeners = object.events[eventKey]\n let index = currentListeners.indexOf(listener)\n currentListeners.splice(index, 1)\n if (!currentListeners.length) {\n delete object.events[eventKey]\n object.events[eventKey + REVERT_MUTATION]()\n delete object.events[eventKey + REVERT_MUTATION]\n }\n }\n}\n\nexport let onStart = ($store, listener) =>\n on($store, listener, START, runListeners => {\n let originListen = $store.listen\n $store.listen = arg => {\n if (!$store.lc && !$store.starting) {\n $store.starting = true\n runListeners()\n delete $store.starting\n }\n return originListen(arg)\n }\n return () => {\n $store.listen = originListen\n }\n })\n\nexport let onStop = ($store, listener) =>\n on($store, listener, STOP, runListeners => {\n let originOff = $store.off\n $store.off = () => {\n runListeners()\n originOff()\n }\n return () => {\n $store.off = originOff\n }\n })\n\nexport let onSet = ($store, listener) =>\n on($store, listener, SET, runListeners => {\n let originSet = $store.set\n let originSetKey = $store.setKey\n if ($store.setKey) {\n $store.setKey = (changed, changedValue) => {\n let isAborted\n let abort = () => {\n isAborted = true\n }\n\n runListeners({\n abort,\n changed,\n newValue: { ...$store.value, [changed]: changedValue }\n })\n if (!isAborted) return originSetKey(changed, changedValue)\n }\n }\n $store.set = newValue => {\n let isAborted\n let abort = () => {\n isAborted = true\n }\n\n runListeners({ abort, newValue })\n if (!isAborted) return originSet(newValue)\n }\n return () => {\n $store.set = originSet\n $store.setKey = originSetKey\n }\n })\n\nexport let onNotify = ($store, listener) =>\n on($store, listener, NOTIFY, runListeners => {\n let originNotify = $store.notify\n $store.notify = (oldValue, changed) => {\n let isAborted\n let abort = () => {\n isAborted = true\n }\n\n runListeners({ abort, changed, oldValue })\n if (!isAborted) return originNotify(oldValue, changed)\n }\n return () => {\n $store.notify = originNotify\n }\n })\n\nexport let STORE_UNMOUNT_DELAY = 1000\n\nexport let onMount = ($store, initialize) => {\n let listener = payload => {\n let destroy = initialize(payload)\n if (destroy) $store.events[UNMOUNT].push(destroy)\n }\n return on($store, listener, MOUNT, runListeners => {\n let originListen = $store.listen\n $store.listen = (...args) => {\n if (!$store.lc && !$store.active) {\n $store.active = true\n runListeners()\n }\n return originListen(...args)\n }\n\n let originOff = $store.off\n $store.events[UNMOUNT] = []\n $store.off = () => {\n originOff()\n setTimeout(() => {\n if ($store.active && !$store.lc) {\n $store.active = false\n for (let destroy of $store.events[UNMOUNT]) destroy()\n $store.events[UNMOUNT] = []\n }\n }, STORE_UNMOUNT_DELAY)\n }\n\n if (process.env.NODE_ENV !== 'production') {\n let originClean = $store[clean]\n $store[clean] = () => {\n for (let destroy of $store.events[UNMOUNT]) destroy()\n $store.events[UNMOUNT] = []\n $store.active = false\n originClean()\n }\n }\n\n return () => {\n $store.listen = originListen\n $store.off = originOff\n }\n })\n}\n"],"x_google_ignoreList":[0],"mappings":";;;AAEA,MAAMC,QAAQ;AACd,MAAMC,OAAO;AAGb,MAAMG,QAAQ;AACd,MAAMC,UAAU;AAChB,MAAMC,kBAAkB;AAExB,IAAWC,MAAMC,QAAQC,UAAUC,UAAUC,gBAAgB;AAC3DH,QAAOI,SAASJ,OAAOI,UAAU,EAAE;AACnC,KAAI,CAACJ,OAAOI,OAAOF,WAAWJ,iBAC5BE,QAAOI,OAAOF,WAAWJ,mBAAmBK,aAAYE,eAAc;AAEpEL,SAAOI,OAAOF,UAAUI,aAAaC,OAAOC,OAAOA,EAAED,MAAM,EAAEA,QAAQ;GACnEE,QAAQ,EAAE;GACV,GAAGJ;GACJ,CAAC;GACF;AAEJL,QAAOI,OAAOF,YAAYF,OAAOI,OAAOF,aAAa,EAAE;AACvDF,QAAOI,OAAOF,UAAUQ,KAAKT,SAAS;AACtC,cAAa;EACX,IAAIU,mBAAmBX,OAAOI,OAAOF;EACrC,IAAIU,QAAQD,iBAAiBE,QAAQZ,SAAS;AAC9CU,mBAAiBG,OAAOF,OAAO,EAAE;AACjC,MAAI,CAACD,iBAAiBI,QAAQ;AAC5B,UAAOf,OAAOI,OAAOF;AACrBF,UAAOI,OAAOF,WAAWJ,kBAAkB;AAC3C,UAAOE,OAAOI,OAAOF,WAAWJ;;;;AAKtC,IAAWkB,WAAWC,QAAQhB,aAC5BF,GAAGkB,QAAQhB,UAAUT,QAAO0B,iBAAgB;CAC1C,IAAIC,eAAeF,OAAOG;AAC1BH,QAAOG,UAASC,QAAO;AACrB,MAAI,CAACJ,OAAOK,MAAM,CAACL,OAAOM,UAAU;AAClCN,UAAOM,WAAW;AAClBL,iBAAc;AACd,UAAOD,OAAOM;;AAEhB,SAAOJ,aAAaE,IAAI;;AAE1B,cAAa;AACXJ,SAAOG,SAASD;;EAElB;AAEJ,IAAWK,UAAUP,QAAQhB,aAC3BF,GAAGkB,QAAQhB,UAAUR,OAAMyB,iBAAgB;CACzC,IAAIO,YAAYR,OAAOS;AACvBT,QAAOS,YAAY;AACjBR,gBAAc;AACdO,aAAW;;AAEb,cAAa;AACXR,SAAOS,MAAMD;;EAEf;AAqDJ,IAAWiB,sBAAsB;AAEjC,IAAWC,WAAW1B,QAAQ2B,eAAe;CAC3C,IAAI3C,YAAW4C,YAAW;EACxB,IAAIC,UAAUF,WAAWC,QAAQ;AACjC,MAAIC,QAAS7B,QAAOb,OAAOP,SAASa,KAAKoC,QAAQ;;AAEnD,QAAO/C,GAAGkB,QAAQhB,UAAUL,QAAOsB,iBAAgB;EACjD,IAAIC,eAAeF,OAAOG;AAC1BH,SAAOG,UAAU,GAAG2B,SAAS;AAC3B,OAAI,CAAC9B,OAAOK,MAAM,CAACL,OAAO+B,QAAQ;AAChC/B,WAAO+B,SAAS;AAChB9B,kBAAc;;AAEhB,UAAOC,aAAa,GAAG4B,KAAK;;EAG9B,IAAItB,YAAYR,OAAOS;AACvBT,SAAOb,OAAOP,WAAW,EAAE;AAC3BoB,SAAOS,YAAY;AACjBD,cAAW;AACXwB,oBAAiB;AACf,QAAIhC,OAAO+B,UAAU,CAAC/B,OAAOK,IAAI;AAC/BL,YAAO+B,SAAS;AAChB,UAAK,IAAIF,WAAW7B,OAAOb,OAAOP,SAAUiD,UAAS;AACrD7B,YAAOb,OAAOP,WAAW,EAAE;;MAE5B6C,oBAAoB;;EAGkB;GACzC,IAAIW,cAAcpC,OAAO1B;AACzB0B,UAAO1B,eAAe;AACpB,SAAK,IAAIuD,WAAW7B,OAAOb,OAAOP,SAAUiD,UAAS;AACrD7B,WAAOb,OAAOP,WAAW,EAAE;AAC3BoB,WAAO+B,SAAS;AAChBK,iBAAa;;;AAIjB,eAAa;AACXpC,UAAOG,SAASD;AAChBF,UAAOS,MAAMD;;GAEf"}
@@ -0,0 +1,11 @@
1
+ //#region ../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/listen-keys/index.js
2
+ function listenKeys($store, keys, listener) {
3
+ let keysSet = new Set(keys).add(void 0);
4
+ return $store.listen((value, oldValue, changed) => {
5
+ if (keysSet.has(changed)) listener(value, oldValue, changed);
6
+ });
7
+ }
8
+
9
+ //#endregion
10
+ export { listenKeys };
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["listenKeys","$store","keys","listener","keysSet","Set","add","undefined","listen","value","oldValue","changed","has","subscribeKeys","unbind"],"sources":["../../../../../../../../../../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/listen-keys/index.js"],"sourcesContent":["export function listenKeys($store, keys, listener) {\n let keysSet = new Set(keys).add(undefined)\n return $store.listen((value, oldValue, changed) => {\n if (keysSet.has(changed)) {\n listener(value, oldValue, changed)\n }\n })\n}\n\nexport function subscribeKeys($store, keys, listener) {\n let unbind = listenKeys($store, keys, listener)\n listener($store.value)\n return unbind\n}\n"],"x_google_ignoreList":[0],"mappings":";AAAA,SAAgBA,WAAWC,QAAQC,MAAMC,UAAU;CACjD,IAAIC,UAAU,IAAIC,IAAIH,KAAK,CAACI,IAAIC,OAAU;AAC1C,QAAON,OAAOO,QAAQC,OAAOC,UAAUC,YAAY;AACjD,MAAIP,QAAQQ,IAAID,QAAQ,CACtBR,UAASM,OAAOC,UAAUC,QAAQ;GAEpC"}
@@ -0,0 +1,25 @@
1
+ import { atom } from "../atom/index.js";
2
+
3
+ //#region ../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/map/index.js
4
+ const map = /* @__NO_SIDE_EFFECTS__ */ (initial = {}) => {
5
+ let $map = /* @__PURE__ */ atom(initial);
6
+ $map.setKey = function(key, value) {
7
+ let oldMap = $map.value;
8
+ if (typeof value === "undefined" && key in $map.value) {
9
+ $map.value = { ...$map.value };
10
+ delete $map.value[key];
11
+ $map.notify(oldMap, key);
12
+ } else if ($map.value[key] !== value) {
13
+ $map.value = {
14
+ ...$map.value,
15
+ [key]: value
16
+ };
17
+ $map.notify(oldMap, key);
18
+ }
19
+ };
20
+ return $map;
21
+ };
22
+
23
+ //#endregion
24
+ export { map };
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["atom","map","initial","$map","setKey","key","value","oldMap","notify"],"sources":["../../../../../../../../../../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/map/index.js"],"sourcesContent":["import { atom } from '../atom/index.js'\n\n/* @__NO_SIDE_EFFECTS__ */\nexport const map = (initial = {}) => {\n let $map = atom(initial)\n\n $map.setKey = function (key, value) {\n let oldMap = $map.value\n if (typeof value === 'undefined' && key in $map.value) {\n $map.value = { ...$map.value }\n delete $map.value[key]\n $map.notify(oldMap, key)\n } else if ($map.value[key] !== value) {\n $map.value = {\n ...$map.value,\n [key]: value\n }\n $map.notify(oldMap, key)\n }\n }\n\n return $map\n}\n"],"x_google_ignoreList":[0],"mappings":";;;AAGA,MAAaC,kCAAOC,UAAU,EAAE,KAAK;CACnC,IAAIC,OAAOH,qBAAKE,QAAQ;AAExBC,MAAKC,SAAS,SAAUC,KAAKC,OAAO;EAClC,IAAIC,SAASJ,KAAKG;AAClB,MAAI,OAAOA,UAAU,eAAeD,OAAOF,KAAKG,OAAO;AACrDH,QAAKG,QAAQ,EAAE,GAAGH,KAAKG,OAAO;AAC9B,UAAOH,KAAKG,MAAMD;AAClBF,QAAKK,OAAOD,QAAQF,IAAI;aACfF,KAAKG,MAAMD,SAASC,OAAO;AACpCH,QAAKG,QAAQ;IACX,GAAGH,KAAKG;KACPD,MAAMC;IACR;AACDH,QAAKK,OAAOD,QAAQF,IAAI;;;AAI5B,QAAOF"}
@@ -0,0 +1,24 @@
1
+ //#region ../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/task/index.js
2
+ let tasks = 0;
3
+ let resolves = [];
4
+ function startTask() {
5
+ tasks += 1;
6
+ return () => {
7
+ tasks -= 1;
8
+ if (tasks === 0) {
9
+ let prevResolves = resolves;
10
+ resolves = [];
11
+ for (let i of prevResolves) i();
12
+ }
13
+ };
14
+ }
15
+ function task(cb) {
16
+ let endTask = startTask();
17
+ let promise = cb().finally(endTask);
18
+ promise.t = true;
19
+ return promise;
20
+ }
21
+
22
+ //#endregion
23
+ export { startTask, task };
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["tasks","resolves","startTask","prevResolves","i","task","cb","endTask","promise","finally","t","allTasks","Promise","resolve","push","cleanTasks"],"sources":["../../../../../../../../../../../node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/task/index.js"],"sourcesContent":["let tasks = 0\nlet resolves = []\n\nexport function startTask() {\n tasks += 1\n return () => {\n tasks -= 1\n if (tasks === 0) {\n let prevResolves = resolves\n resolves = []\n for (let i of prevResolves) i()\n }\n }\n}\n\nexport function task(cb) {\n let endTask = startTask()\n let promise = cb().finally(endTask)\n promise.t = true\n return promise\n}\n\nexport function allTasks() {\n if (tasks === 0) {\n return Promise.resolve()\n } else {\n return new Promise(resolve => {\n resolves.push(resolve)\n })\n }\n}\n\nexport function cleanTasks() {\n tasks = 0\n}\n"],"x_google_ignoreList":[0],"mappings":";AAAA,IAAIA,QAAQ;AACZ,IAAIC,WAAW,EAAE;AAEjB,SAAgBC,YAAY;AAC1BF,UAAS;AACT,cAAa;AACXA,WAAS;AACT,MAAIA,UAAU,GAAG;GACf,IAAIG,eAAeF;AACnBA,cAAW,EAAE;AACb,QAAK,IAAIG,KAAKD,aAAcC,IAAG;;;;AAKrC,SAAgBC,KAAKC,IAAI;CACvB,IAAIC,UAAUL,WAAW;CACzB,IAAIM,UAAUF,IAAI,CAACG,QAAQF,QAAQ;AACnCC,SAAQE,IAAI;AACZ,QAAOF"}
@@ -0,0 +1,49 @@
1
+ import { uploadSchema } from "./schema.js";
2
+ import { defineFragment } from "@fragno-dev/core";
3
+
4
+ //#region src/definition.ts
5
+ const uploadFragmentDefinition = defineFragment("upload").extend((x) => x).withDependencies(() => {}).provideHooks(({ defineHook, config }) => {
6
+ return {
7
+ onFileReady: defineHook(async function(payload) {
8
+ await config.onFileReady?.(payload, this.idempotencyKey);
9
+ }),
10
+ onUploadFailed: defineHook(async function(payload) {
11
+ await config.onUploadFailed?.(payload, this.idempotencyKey);
12
+ }),
13
+ onFileDeleted: defineHook(async function(payload) {
14
+ await config.onFileDeleted?.(payload, this.idempotencyKey);
15
+ }),
16
+ onUploadTimeout: defineHook(async function(payload) {
17
+ const now = /* @__PURE__ */ new Date();
18
+ if (!payload.uploadId) return;
19
+ const result = await this.handlerTx().retrieve(({ forSchema }) => forSchema(uploadSchema).findFirst("upload", (b) => b.whereIndex("primary", (eb) => eb("id", "=", payload.uploadId)))).mutate(({ forSchema, retrieveResult: [upload] }) => {
20
+ if (!upload) return { shouldNotify: false };
21
+ const status = upload.status;
22
+ if (status === "completed" || status === "aborted" || status === "failed" || status === "expired") return { shouldNotify: false };
23
+ if (upload.expiresAt.getTime() > now.getTime()) return { shouldNotify: false };
24
+ forSchema(uploadSchema).update("upload", upload.id, (b) => b.set({
25
+ status: "expired",
26
+ updatedAt: now,
27
+ errorCode: "UPLOAD_EXPIRED",
28
+ errorMessage: "Upload expired"
29
+ }));
30
+ return {
31
+ shouldNotify: true,
32
+ payload: {
33
+ fileKey: upload.fileKey,
34
+ fileKeyParts: payload.fileKeyParts,
35
+ uploadId: payload.uploadId,
36
+ uploaderId: upload.uploaderId,
37
+ sizeBytes: Number(upload.expectedSizeBytes),
38
+ contentType: upload.contentType
39
+ }
40
+ };
41
+ }).transform(({ mutateResult }) => mutateResult).execute();
42
+ if (result.shouldNotify) await config.onUploadFailed?.(result.payload, this.idempotencyKey);
43
+ })
44
+ };
45
+ }).providesBaseService(() => {}).build();
46
+
47
+ //#endregion
48
+ export { uploadFragmentDefinition };
49
+ //# sourceMappingURL=definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.js","names":["defineFragment","UploadFragmentConfig","uploadSchema","UploadStatus","uploadFragmentDefinition","extend","x","withDependencies","provideHooks","defineHook","config","onFileReady","payload","idempotencyKey","onUploadFailed","onFileDeleted","onUploadTimeout","now","Date","uploadId","result","handlerTx","retrieve","forSchema","findFirst","b","whereIndex","eb","mutate","retrieveResult","upload","shouldNotify","const","status","expiresAt","getTime","uow","update","id","set","updatedAt","errorCode","errorMessage","fileKey","fileKeyParts","uploaderId","sizeBytes","Number","expectedSizeBytes","contentType","transform","mutateResult","execute","providesBaseService","build"],"sources":["../../../../../../src/definition.ts"],"sourcesContent":["import { defineFragment } from \"@fragno-dev/core\";\nimport { withDatabase } from \"@fragno-dev/db\";\nimport type { UploadFragmentConfig } from \"./config\";\nimport { resolveUploadFragmentConfig } from \"./config\";\nimport { uploadSchema } from \"./schema\";\nimport { createFileServices, createUploadServices } from \"./services\";\nimport type { UploadStatus } from \"./types\";\n\nexport const uploadFragmentDefinition = defineFragment<UploadFragmentConfig>(\"upload\")\n .extend(withDatabase(uploadSchema))\n .withDependencies(({ config }) => ({\n resolvedConfig: resolveUploadFragmentConfig(config),\n }))\n .provideHooks(({ defineHook, config }) => {\n return {\n onFileReady: defineHook(async function (payload) {\n await config.onFileReady?.(payload, this.idempotencyKey);\n }),\n onUploadFailed: defineHook(async function (payload) {\n await config.onUploadFailed?.(payload, this.idempotencyKey);\n }),\n onFileDeleted: defineHook(async function (payload) {\n await config.onFileDeleted?.(payload, this.idempotencyKey);\n }),\n onUploadTimeout: defineHook(async function (payload) {\n const now = new Date();\n\n if (!payload.uploadId) {\n return;\n }\n\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(uploadSchema).findFirst(\"upload\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", payload.uploadId)),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [upload] }) => {\n if (!upload) {\n return { shouldNotify: false as const };\n }\n\n const status = upload.status as UploadStatus;\n if (\n status === \"completed\" ||\n status === \"aborted\" ||\n status === \"failed\" ||\n status === \"expired\"\n ) {\n return { shouldNotify: false as const };\n }\n\n if (upload.expiresAt.getTime() > now.getTime()) {\n return { shouldNotify: false as const };\n }\n\n const uow = forSchema(uploadSchema);\n uow.update(\"upload\", upload.id, (b) =>\n b.set({\n status: \"expired\",\n updatedAt: now,\n errorCode: \"UPLOAD_EXPIRED\",\n errorMessage: \"Upload expired\",\n }),\n );\n\n return {\n shouldNotify: true as const,\n payload: {\n fileKey: upload.fileKey,\n fileKeyParts: payload.fileKeyParts,\n uploadId: payload.uploadId,\n uploaderId: upload.uploaderId,\n sizeBytes: Number(upload.expectedSizeBytes),\n contentType: upload.contentType,\n },\n };\n })\n .transform(({ mutateResult }) => mutateResult)\n .execute();\n\n if (result.shouldNotify) {\n await config.onUploadFailed?.(result.payload, this.idempotencyKey);\n }\n }),\n };\n })\n .providesBaseService(({ defineService, deps }) => {\n return defineService({\n ...createUploadServices(deps.resolvedConfig),\n ...createFileServices(deps.resolvedConfig),\n });\n })\n .build();\n"],"mappings":";;;;AAQA,MAAaI,2BAA2BJ,eAAqC,SAAS,CACnFK,QAAMC,MAAAA,EAA4B,CAClCC,uBAAgB,GAEd,CACFC,cAAc,EAAEC,YAAYC,aAAa;AACxC,QAAO;EACLC,aAAaF,WAAW,eAAgBG,SAAS;AAC/C,SAAMF,OAAOC,cAAcC,SAAS,KAAKC,eAAe;IACxD;EACFC,gBAAgBL,WAAW,eAAgBG,SAAS;AAClD,SAAMF,OAAOI,iBAAiBF,SAAS,KAAKC,eAAe;IAC3D;EACFE,eAAeN,WAAW,eAAgBG,SAAS;AACjD,SAAMF,OAAOK,gBAAgBH,SAAS,KAAKC,eAAe;IAC1D;EACFG,iBAAiBP,WAAW,eAAgBG,SAAS;GACnD,MAAMK,sBAAM,IAAIC,MAAM;AAEtB,OAAI,CAACN,QAAQO,SACX;GAGF,MAAMC,SAAS,MAAM,KAAKC,WAAW,CAClCC,UAAU,EAAEC,gBACXA,UAAUrB,aAAa,CAACsB,UAAU,WAAWC,MAC3CA,EAAEC,WAAW,YAAYC,OAAOA,GAAG,MAAM,KAAKf,QAAQO,SAAS,CACjE,CACF,CAAC,CACAS,QAAQ,EAAEL,WAAWM,gBAAgB,CAACC,cAAc;AACnD,QAAI,CAACA,OACH,QAAO,EAAEC,cAAc,OAAgB;IAGzC,MAAME,SAASH,OAAOG;AACtB,QACEA,WAAW,eACXA,WAAW,aACXA,WAAW,YACXA,WAAW,UAEX,QAAO,EAAEF,cAAc,OAAgB;AAGzC,QAAID,OAAOI,UAAUC,SAAS,GAAGlB,IAAIkB,SAAS,CAC5C,QAAO,EAAEJ,cAAc,OAAgB;AAIzCK,IADYb,UAAUrB,aAAa,CAC/BmC,OAAO,UAAUP,OAAOQ,KAAKb,MAC/BA,EAAEc,IAAI;KACJN,QAAQ;KACRO,WAAWvB;KACXwB,WAAW;KACXC,cAAc;KACf,CACH,CAAC;AAED,WAAO;KACLX,cAAc;KACdnB,SAAS;MACP+B,SAASb,OAAOa;MAChBC,cAAchC,QAAQgC;MACtBzB,UAAUP,QAAQO;MAClB0B,YAAYf,OAAOe;MACnBC,WAAWC,OAAOjB,OAAOkB,kBAAkB;MAC3CC,aAAanB,OAAOmB;MACtB;KACD;KACD,CACDC,WAAW,EAAEC,mBAAmBA,aAAa,CAC7CC,SAAS;AAEZ,OAAIhC,OAAOW,aACT,OAAMrB,OAAOI,iBAAiBM,OAAOR,SAAS,KAAKC,eAAe;IAErE;EACF;EACD,CACDwC,0BAAmB,GAKlB,CACDC,OAAO"}
@@ -0,0 +1,7 @@
1
+ //#region src/keys.d.ts
2
+ type FileKeyPart = string | number;
3
+ type FileKeyParts = readonly FileKeyPart[];
4
+ type FileKeyEncoded = string;
5
+ //#endregion
6
+ export { FileKeyEncoded, FileKeyParts };
7
+ //# sourceMappingURL=keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.ts","names":[],"sources":["../../../../../../src/keys.ts"],"sourcesContent":[],"mappings":";KAAY,WAAA;AAAA,KACA,YAAA,GADW,SACa,WADb,EAAA;AACX,KACA,cAAA,GADY,MAAY"}
@@ -0,0 +1,28 @@
1
+ //#region src/keys.ts
2
+ function base64UrlEncode(value) {
3
+ const bytes = new TextEncoder().encode(value);
4
+ if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
5
+ const encoder = globalThis.btoa;
6
+ if (!encoder) throw new Error("Base64 encoding is not available");
7
+ let binary = "";
8
+ for (const byte of bytes) binary += String.fromCharCode(byte);
9
+ return encoder(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
10
+ }
11
+ function encodePart(part) {
12
+ if (typeof part === "string") return `s~${base64UrlEncode(part)}`;
13
+ if (typeof part === "number") {
14
+ if (!Number.isFinite(part)) throw new Error("File key number parts must be finite");
15
+ const serialized = String(part);
16
+ if (serialized.includes(".") || serialized.includes("e") || serialized.includes("E")) throw new Error("File key number parts must be integers");
17
+ return `n~${serialized}`;
18
+ }
19
+ throw new Error("File key parts must be strings or numbers");
20
+ }
21
+ function encodeFileKey(parts) {
22
+ if (parts.length === 0) return "";
23
+ return parts.map((part) => encodePart(part)).join(".");
24
+ }
25
+
26
+ //#endregion
27
+ export { encodeFileKey };
28
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","names":["FileKeyPart","FileKeyParts","FileKeyEncoded","base64UrlPattern","base64UrlEncode","value","bytes","TextEncoder","encode","Buffer","from","toString","replace","encoder","globalThis","btoa","Error","binary","byte","String","fromCharCode","base64UrlDecode","test","base64","padded","repeat","length","TextDecoder","decode","decoder","atob","Uint8Array","i","charCodeAt","encodePart","part","Number","isFinite","serialized","includes","decodeNumberPart","raw","encodeFileKey","parts","map","join","decodeFileKey","key","segments","split","segment","prefix","slice","payload","encodeFileKeyPrefix"],"sources":["../../../../../../src/keys.ts"],"sourcesContent":["export type FileKeyPart = string | number;\nexport type FileKeyParts = readonly FileKeyPart[];\nexport type FileKeyEncoded = string;\n\nconst base64UrlPattern = /^[A-Za-z0-9_-]*$/;\n\nfunction base64UrlEncode(value: string): string {\n const bytes = new TextEncoder().encode(value);\n\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(bytes)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\");\n }\n\n const encoder = (globalThis as { btoa?: (value: string) => string }).btoa;\n if (!encoder) {\n throw new Error(\"Base64 encoding is not available\");\n }\n\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n\n return encoder(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/g, \"\");\n}\n\nfunction base64UrlDecode(value: string): string {\n if (!base64UrlPattern.test(value)) {\n throw new Error(\"Invalid base64url value\");\n }\n\n const base64 = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded = base64 + \"=\".repeat((4 - (base64.length % 4)) % 4);\n\n if (typeof Buffer !== \"undefined\") {\n return new TextDecoder().decode(Buffer.from(padded, \"base64\"));\n }\n\n const decoder = (globalThis as { atob?: (value: string) => string }).atob;\n if (!decoder) {\n throw new Error(\"Base64 decoding is not available\");\n }\n\n const binary = decoder(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) {\n bytes[i] = binary.charCodeAt(i);\n }\n\n return new TextDecoder().decode(bytes);\n}\n\nfunction encodePart(part: FileKeyPart): string {\n if (typeof part === \"string\") {\n return `s~${base64UrlEncode(part)}`;\n }\n\n if (typeof part === \"number\") {\n if (!Number.isFinite(part)) {\n throw new Error(\"File key number parts must be finite\");\n }\n\n const serialized = String(part);\n if (serialized.includes(\".\") || serialized.includes(\"e\") || serialized.includes(\"E\")) {\n throw new Error(\"File key number parts must be integers\");\n }\n\n return `n~${serialized}`;\n }\n\n throw new Error(\"File key parts must be strings or numbers\");\n}\n\nfunction decodeNumberPart(raw: string): number {\n if (raw.length === 0) {\n throw new Error(\"Invalid number part\");\n }\n\n if (raw.includes(\".\") || raw.includes(\"e\") || raw.includes(\"E\")) {\n throw new Error(\"Invalid number part\");\n }\n\n const value = Number(raw);\n if (!Number.isFinite(value)) {\n throw new Error(\"Invalid number part\");\n }\n\n if (String(value) !== raw) {\n throw new Error(\"Invalid number part\");\n }\n\n return value;\n}\n\nexport function encodeFileKey(parts: FileKeyParts): FileKeyEncoded {\n if (parts.length === 0) {\n return \"\";\n }\n\n return parts.map((part) => encodePart(part)).join(\".\");\n}\n\nexport function decodeFileKey(key: FileKeyEncoded): FileKeyParts {\n if (key.length === 0) {\n return [];\n }\n\n const segments = key.split(\".\");\n\n return segments.map((segment) => {\n const prefix = segment.slice(0, 2);\n const payload = segment.slice(2);\n\n if (prefix === \"s~\") {\n return base64UrlDecode(payload);\n }\n\n if (prefix === \"n~\") {\n return decodeNumberPart(payload);\n }\n\n throw new Error(\"Invalid file key segment\");\n });\n}\n\nexport function encodeFileKeyPrefix(parts: FileKeyParts): string {\n if (parts.length === 0) {\n return \"\";\n }\n\n return `${encodeFileKey(parts)}.`;\n}\n"],"mappings":";AAMA,SAASI,gBAAgBC,OAAuB;CAC9C,MAAMC,QAAQ,IAAIC,aAAa,CAACC,OAAOH,MAAM;AAE7C,KAAI,OAAOI,WAAW,YACpB,QAAOA,OAAOC,KAAKJ,MAAM,CACtBK,SAAS,SAAS,CAClBC,QAAQ,OAAO,IAAI,CACnBA,QAAQ,OAAO,IAAI,CACnBA,QAAQ,QAAQ,GAAG;CAGxB,MAAMC,UAAWC,WAAoDC;AACrE,KAAI,CAACF,QACH,OAAM,IAAIG,MAAM,mCAAmC;CAGrD,IAAIC,SAAS;AACb,MAAK,MAAMC,QAAQZ,MACjBW,WAAUE,OAAOC,aAAaF,KAAK;AAGrC,QAAOL,QAAQI,OAAO,CAACL,QAAQ,OAAO,IAAI,CAACA,QAAQ,OAAO,IAAI,CAACA,QAAQ,QAAQ,GAAG;;AA6BpF,SAASsB,WAAWC,MAA2B;AAC7C,KAAI,OAAOA,SAAS,SAClB,QAAO,KAAK/B,gBAAgB+B,KAAK;AAGnC,KAAI,OAAOA,SAAS,UAAU;AAC5B,MAAI,CAACC,OAAOC,SAASF,KAAK,CACxB,OAAM,IAAInB,MAAM,uCAAuC;EAGzD,MAAMsB,aAAanB,OAAOgB,KAAK;AAC/B,MAAIG,WAAWC,SAAS,IAAI,IAAID,WAAWC,SAAS,IAAI,IAAID,WAAWC,SAAS,IAAI,CAClF,OAAM,IAAIvB,MAAM,yCAAyC;AAG3D,SAAO,KAAKsB;;AAGd,OAAM,IAAItB,MAAM,4CAA4C;;AAwB9D,SAAgB0B,cAAcC,OAAqC;AACjE,KAAIA,MAAMjB,WAAW,EACnB,QAAO;AAGT,QAAOiB,MAAMC,KAAKT,SAASD,WAAWC,KAAK,CAAC,CAACU,KAAK,IAAI"}
@@ -0,0 +1,98 @@
1
+ import { uploadFragmentDefinition } from "../definition.js";
2
+ import { fileMetadataSchema, visibilitySchema } from "./shared.js";
3
+ import { defineRoutes } from "@fragno-dev/core";
4
+ import { z } from "zod";
5
+
6
+ //#region src/routes/files.ts
7
+ const updateFileSchema = z.object({
8
+ filename: z.string().min(1).optional(),
9
+ visibility: visibilitySchema.optional(),
10
+ tags: z.array(z.string()).nullable().optional(),
11
+ metadata: z.record(z.string(), z.unknown()).nullable().optional()
12
+ });
13
+ const errorCodes = [
14
+ "UPLOAD_NOT_FOUND",
15
+ "UPLOAD_ALREADY_ACTIVE",
16
+ "FILE_ALREADY_EXISTS",
17
+ "FILE_NOT_FOUND",
18
+ "UPLOAD_EXPIRED",
19
+ "UPLOAD_INVALID_STATE",
20
+ "SIGNED_URL_UNSUPPORTED",
21
+ "STORAGE_ERROR",
22
+ "INVALID_FILE_KEY",
23
+ "INVALID_CHECKSUM",
24
+ "INVALID_REQUEST"
25
+ ];
26
+ const fileRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ services, defineRoute, config }) => {
27
+ return [
28
+ defineRoute({
29
+ method: "POST",
30
+ path: "/files",
31
+ contentType: "multipart/form-data",
32
+ outputSchema: fileMetadataSchema,
33
+ errorCodes,
34
+ handler: () => {}
35
+ }),
36
+ defineRoute({
37
+ method: "GET",
38
+ path: "/files",
39
+ queryParameters: [
40
+ "prefix",
41
+ "cursor",
42
+ "pageSize",
43
+ "status",
44
+ "uploaderId"
45
+ ],
46
+ outputSchema: z.object({
47
+ files: z.array(fileMetadataSchema),
48
+ cursor: z.string().optional(),
49
+ hasNextPage: z.boolean()
50
+ }),
51
+ errorCodes,
52
+ handler: () => {}
53
+ }),
54
+ defineRoute({
55
+ method: "GET",
56
+ path: "/files/:fileKey",
57
+ outputSchema: fileMetadataSchema,
58
+ errorCodes,
59
+ handler: () => {}
60
+ }),
61
+ defineRoute({
62
+ method: "PATCH",
63
+ path: "/files/:fileKey",
64
+ inputSchema: updateFileSchema,
65
+ outputSchema: fileMetadataSchema,
66
+ errorCodes,
67
+ handler: () => {}
68
+ }),
69
+ defineRoute({
70
+ method: "DELETE",
71
+ path: "/files/:fileKey",
72
+ outputSchema: z.object({ ok: z.literal(true) }),
73
+ errorCodes,
74
+ handler: () => {}
75
+ }),
76
+ defineRoute({
77
+ method: "GET",
78
+ path: "/files/:fileKey/download-url",
79
+ outputSchema: z.object({
80
+ url: z.string(),
81
+ headers: z.record(z.string(), z.string()).optional(),
82
+ expiresAt: z.date()
83
+ }),
84
+ errorCodes,
85
+ handler: () => {}
86
+ }),
87
+ defineRoute({
88
+ method: "GET",
89
+ path: "/files/:fileKey/content",
90
+ errorCodes,
91
+ handler: () => {}
92
+ })
93
+ ];
94
+ });
95
+
96
+ //#endregion
97
+ export { fileRoutesFactory };
98
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","names":["defineRoutes","FragnoRouteConfig","z","uploadFragmentDefinition","fileMetadataSchema","visibilitySchema","updateFileSchema","object","filename","string","min","optional","visibility","tags","array","nullable","metadata","record","unknown","errorCodes","const","FileErrorCode","ErrorFn","Parameters","Code","fileRoutesFactory","create","services","defineRoute","config","method","path","contentType","outputSchema","handler","queryParameters","files","cursor","hasNextPage","boolean","inputSchema","ok","literal","url","headers","expiresAt","date"],"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":";;;;;;AAsBA,MAAMM,mBAAmBJ,EAAEK,OAAO;CAChCC,UAAUN,EAAEO,QAAQ,CAACC,IAAI,EAAE,CAACC,UAAU;CACtCC,YAAYP,iBAAiBM,UAAU;CACvCE,MAAMX,EAAEY,MAAMZ,EAAEO,QAAQ,CAAC,CAACM,UAAU,CAACJ,UAAU;CAC/CK,UAAUd,EAAEe,OAAOf,EAAEO,QAAQ,EAAEP,EAAEgB,SAAS,CAAC,CAACH,UAAU,CAACJ,UAAS;CACjE,CAAC;AAEF,MAAMQ,aAAa;CACjB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AA+ED,MAAaM,oBAAoBzB,aAAaG,yBAAyB,CAACuB,QACrE,EAAEC,UAAUC,aAAaC,aAAa;AAuBrC,QAAO;EACLD,YAAY;GACVE,QAAQ;GACRC,MAAM;GACNC,aAAa;GACbC,cAAc7B;GACde;GACAe,eAAO;GAiMR,CAAC;EAEFN,YAAY;GACVE,QAAQ;GACRC,MAAM;GACNI,iBAAiB;IAAC;IAAU;IAAU;IAAY;IAAU;IAAa;GACzEF,cAAc/B,EAAEK,OAAO;IACrB6B,OAAOlC,EAAEY,MAAMV,mBAAmB;IAClCiC,QAAQnC,EAAEO,QAAQ,CAACE,UAAU;IAC7B2B,aAAapC,EAAEqC,SAAQ;IACxB,CAAC;GACFpB;GACAe,eAAO;GA2BR,CAAC;EAEFN,YAAY;GACVE,QAAQ;GACRC,MAAM;GACNE,cAAc7B;GACde;GACAe,eAAO;GAmBR,CAAC;EAEFN,YAAY;GACVE,QAAQ;GACRC,MAAM;GACNS,aAAalC;GACb2B,cAAc7B;GACde;GACAe,eAAO;GAoBR,CAAC;EAEFN,YAAY;GACVE,QAAQ;GACRC,MAAM;GACNE,cAAc/B,EAAEK,OAAO,EAAEkC,IAAIvC,EAAEwC,QAAQ,KAAI,EAAG,CAAC;GAC/CvB;GACAe,eAAO;GAgCR,CAAC;EAEFN,YAAY;GACVE,QAAQ;GACRC,MAAM;GACNE,cAAc/B,EAAEK,OAAO;IACrBoC,KAAKzC,EAAEO,QAAQ;IACfmC,SAAS1C,EAAEe,OAAOf,EAAEO,QAAQ,EAAEP,EAAEO,QAAQ,CAAC,CAACE,UAAU;IACpDkC,WAAW3C,EAAE4C,MAAK;IACnB,CAAC;GACF3B;GACAe,eAAO;GAsCR,CAAC;EAEFN,YAAY;GACVE,QAAQ;GACRC,MAAM;GACNZ;GACAe,eAAO;GAiCR,CAAC;EACH;EAEJ"}
@@ -0,0 +1,9 @@
1
+ import { fileRoutesFactory } from "./files.js";
2
+ import { uploadRoutesFactory } from "./uploads.js";
3
+
4
+ //#region src/routes/index.ts
5
+ const uploadRoutes = [uploadRoutesFactory, fileRoutesFactory];
6
+
7
+ //#endregion
8
+ export { uploadRoutes };
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["fileRoutesFactory","uploadRoutesFactory","uploadRoutes","const"],"sources":["../../../../../../../src/routes/index.ts"],"sourcesContent":["import { fileRoutesFactory } from \"./files\";\nimport { uploadRoutesFactory } from \"./uploads\";\n\nexport const uploadRoutes = [uploadRoutesFactory, fileRoutesFactory] as const;\n\nexport { fileRoutesFactory, uploadRoutesFactory };\n"],"mappings":";;;;AAGA,MAAaE,eAAe,CAACD,qBAAqBD,kBAAkB"}
@@ -0,0 +1,41 @@
1
+ import "../schema.js";
2
+ import { z } from "zod";
3
+
4
+ //#region src/routes/shared.ts
5
+ const fileKeyPartsSchema = z.array(z.union([z.string(), z.number().int()]));
6
+ const checksumSchema = z.object({
7
+ algo: z.enum(["sha256", "md5"]),
8
+ value: z.string()
9
+ }).nullable().optional();
10
+ const visibilitySchema = z.enum([
11
+ "private",
12
+ "public",
13
+ "unlisted"
14
+ ]);
15
+ const fileMetadataSchema = z.object({
16
+ fileKey: z.string(),
17
+ fileKeyParts: fileKeyPartsSchema,
18
+ uploaderId: z.string().nullable(),
19
+ filename: z.string(),
20
+ sizeBytes: z.number(),
21
+ contentType: z.string(),
22
+ checksum: z.object({
23
+ algo: z.enum(["sha256", "md5"]),
24
+ value: z.string()
25
+ }).nullable(),
26
+ visibility: visibilitySchema,
27
+ tags: z.array(z.string()).nullable(),
28
+ metadata: z.record(z.string(), z.unknown()).nullable(),
29
+ status: z.enum(["ready", "deleted"]),
30
+ storageProvider: z.string(),
31
+ createdAt: z.string(),
32
+ updatedAt: z.string(),
33
+ completedAt: z.string().nullable(),
34
+ deletedAt: z.string().nullable(),
35
+ errorCode: z.string().nullable(),
36
+ errorMessage: z.string().nullable()
37
+ });
38
+
39
+ //#endregion
40
+ export { checksumSchema, fileKeyPartsSchema, fileMetadataSchema, visibilitySchema };
41
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","names":["z","TableToColumnValues","decodeFileKey","uploadSchema","FileMetadata","FileRow","tables","file","fileKeyPartsSchema","array","union","string","number","int","checksumSchema","object","algo","enum","value","nullable","optional","visibilitySchema","fileMetadataSchema","fileKey","fileKeyParts","uploaderId","filename","sizeBytes","contentType","checksum","visibility","tags","metadata","record","unknown","status","storageProvider","createdAt","updatedAt","completedAt","deletedAt","errorCode","errorMessage","toFileMetadata","Array","from","toIsoString","Date","toISOString","Number"],"sources":["../../../../../../../src/routes/shared.ts"],"sourcesContent":["import { z } from \"zod\";\nimport type { TableToColumnValues } from \"@fragno-dev/db/query\";\nimport { decodeFileKey } from \"../keys\";\nimport { uploadSchema } from \"../schema\";\nimport type { FileMetadata } from \"../types\";\n\ntype FileRow = TableToColumnValues<typeof uploadSchema.tables.file>;\n\nexport const fileKeyPartsSchema = z.array(z.union([z.string(), z.number().int()]));\n\nexport const checksumSchema = z\n .object({\n algo: z.enum([\"sha256\", \"md5\"]),\n value: z.string(),\n })\n .nullable()\n .optional();\n\nexport const visibilitySchema = z.enum([\"private\", \"public\", \"unlisted\"]);\n\nexport const fileMetadataSchema = z.object({\n fileKey: z.string(),\n fileKeyParts: fileKeyPartsSchema,\n uploaderId: z.string().nullable(),\n filename: z.string(),\n sizeBytes: z.number(),\n contentType: z.string(),\n checksum: z\n .object({\n algo: z.enum([\"sha256\", \"md5\"]),\n value: z.string(),\n })\n .nullable(),\n visibility: visibilitySchema,\n tags: z.array(z.string()).nullable(),\n metadata: z.record(z.string(), z.unknown()).nullable(),\n status: z.enum([\"ready\", \"deleted\"]),\n storageProvider: z.string(),\n createdAt: z.string(),\n updatedAt: z.string(),\n completedAt: z.string().nullable(),\n deletedAt: z.string().nullable(),\n errorCode: z.string().nullable(),\n errorMessage: z.string().nullable(),\n});\n\nexport const toFileMetadata = (file: FileRow): FileMetadata => {\n const fileKeyParts = Array.from(decodeFileKey(file.fileKey));\n\n const toIsoString = (value: Date | null | undefined) => (value ? value.toISOString() : null);\n\n return {\n fileKey: file.fileKey,\n fileKeyParts,\n uploaderId: file.uploaderId,\n filename: file.filename,\n sizeBytes: Number(file.sizeBytes),\n contentType: file.contentType,\n checksum: file.checksum as FileMetadata[\"checksum\"],\n visibility: file.visibility as FileMetadata[\"visibility\"],\n tags: file.tags as FileMetadata[\"tags\"],\n metadata: file.metadata as FileMetadata[\"metadata\"],\n status: file.status as FileMetadata[\"status\"],\n storageProvider: file.storageProvider,\n createdAt: file.createdAt.toISOString(),\n updatedAt: file.updatedAt.toISOString(),\n completedAt: toIsoString(file.completedAt),\n deletedAt: toIsoString(file.deletedAt),\n errorCode: file.errorCode,\n errorMessage: file.errorMessage,\n };\n};\n"],"mappings":";;;;AAQA,MAAaQ,qBAAqBR,EAAES,MAAMT,EAAEU,MAAM,CAACV,EAAEW,QAAQ,EAAEX,EAAEY,QAAQ,CAACC,KAAK,CAAC,CAAC,CAAC;AAElF,MAAaC,iBAAiBd,EAC3Be,OAAO;CACNC,MAAMhB,EAAEiB,KAAK,CAAC,UAAU,MAAM,CAAC;CAC/BC,OAAOlB,EAAEW,QAAO;CACjB,CAAC,CACDQ,UAAU,CACVC,UAAU;AAEb,MAAaC,mBAAmBrB,EAAEiB,KAAK;CAAC;CAAW;CAAU;CAAW,CAAC;AAEzE,MAAaK,qBAAqBtB,EAAEe,OAAO;CACzCQ,SAASvB,EAAEW,QAAQ;CACnBa,cAAchB;CACdiB,YAAYzB,EAAEW,QAAQ,CAACQ,UAAU;CACjCO,UAAU1B,EAAEW,QAAQ;CACpBgB,WAAW3B,EAAEY,QAAQ;CACrBgB,aAAa5B,EAAEW,QAAQ;CACvBkB,UAAU7B,EACPe,OAAO;EACNC,MAAMhB,EAAEiB,KAAK,CAAC,UAAU,MAAM,CAAC;EAC/BC,OAAOlB,EAAEW,QAAO;EACjB,CAAC,CACDQ,UAAU;CACbW,YAAYT;CACZU,MAAM/B,EAAES,MAAMT,EAAEW,QAAQ,CAAC,CAACQ,UAAU;CACpCa,UAAUhC,EAAEiC,OAAOjC,EAAEW,QAAQ,EAAEX,EAAEkC,SAAS,CAAC,CAACf,UAAU;CACtDgB,QAAQnC,EAAEiB,KAAK,CAAC,SAAS,UAAU,CAAC;CACpCmB,iBAAiBpC,EAAEW,QAAQ;CAC3B0B,WAAWrC,EAAEW,QAAQ;CACrB2B,WAAWtC,EAAEW,QAAQ;CACrB4B,aAAavC,EAAEW,QAAQ,CAACQ,UAAU;CAClCqB,WAAWxC,EAAEW,QAAQ,CAACQ,UAAU;CAChCsB,WAAWzC,EAAEW,QAAQ,CAACQ,UAAU;CAChCuB,cAAc1C,EAAEW,QAAQ,CAACQ,UAAS;CACnC,CAAC"}