@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.
- package/LICENSE.md +16 -0
- package/README.md +43 -0
- package/bin/run.js +5 -0
- package/dist/browser/client/clients.js +49 -0
- package/dist/browser/client/clients.js.map +1 -0
- package/dist/browser/client/helpers.d.ts +51 -0
- package/dist/browser/client/helpers.d.ts.map +1 -0
- package/dist/browser/client/helpers.js +242 -0
- package/dist/browser/client/helpers.js.map +1 -0
- 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
- 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
- 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
- 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
- package/dist/browser/client/node_modules/.pnpm/nanoevents@9.1.0/node_modules/nanoevents/index.js +17 -0
- package/dist/browser/client/node_modules/.pnpm/nanoevents@9.1.0/node_modules/nanoevents/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/atom/index.js +62 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/atom/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/clean-stores/index.js +6 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/clean-stores/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/computed/index.js +50 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/computed/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/lifecycle/index.js +99 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/lifecycle/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/listen-keys/index.js +11 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/listen-keys/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/map/index.js +25 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/map/index.js.map +1 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/task/index.js +24 -0
- package/dist/browser/client/node_modules/.pnpm/nanostores@1.1.0/node_modules/nanostores/task/index.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/definition.js +49 -0
- package/dist/browser/client/packages/fragment-upload/src/definition.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/keys.d.ts +7 -0
- package/dist/browser/client/packages/fragment-upload/src/keys.d.ts.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/keys.js +28 -0
- package/dist/browser/client/packages/fragment-upload/src/keys.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/files.js +98 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/files.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/index.js +9 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/index.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/shared.js +41 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/shared.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/uploads.js +186 -0
- package/dist/browser/client/packages/fragment-upload/src/routes/uploads.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/schema.js +8 -0
- package/dist/browser/client/packages/fragment-upload/src/schema.js.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/storage/types.d.ts +9 -0
- package/dist/browser/client/packages/fragment-upload/src/storage/types.d.ts.map +1 -0
- package/dist/browser/client/packages/fragment-upload/src/types.d.ts +31 -0
- package/dist/browser/client/packages/fragment-upload/src/types.d.ts.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/error.js +48 -0
- package/dist/browser/client/packages/fragno/dist/api/error.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/internal/path.js +76 -0
- package/dist/browser/client/packages/fragno/dist/api/internal/path.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/internal/response-stream.js +81 -0
- package/dist/browser/client/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/internal/route.js +10 -0
- package/dist/browser/client/packages/fragno/dist/api/internal/route.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/request-input-context.js +185 -0
- package/dist/browser/client/packages/fragno/dist/api/request-input-context.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/request-output-context.js +119 -0
- package/dist/browser/client/packages/fragno/dist/api/request-output-context.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/api/route.js +17 -0
- package/dist/browser/client/packages/fragno/dist/api/route.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/client-error.js +92 -0
- package/dist/browser/client/packages/fragno/dist/client/client-error.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/client.js +495 -0
- package/dist/browser/client/packages/fragno/dist/client/client.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/client.svelte.js +120 -0
- package/dist/browser/client/packages/fragno/dist/client/client.svelte.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/internal/fetcher-merge.js +36 -0
- package/dist/browser/client/packages/fragno/dist/client/internal/fetcher-merge.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/internal/ndjson-streaming.js +139 -0
- package/dist/browser/client/packages/fragno/dist/client/internal/ndjson-streaming.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/react.js +70 -0
- package/dist/browser/client/packages/fragno/dist/client/react.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/solid.js +108 -0
- package/dist/browser/client/packages/fragno/dist/client/solid.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/vanilla.js +96 -0
- package/dist/browser/client/packages/fragno/dist/client/vanilla.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/client/vue.js +120 -0
- package/dist/browser/client/packages/fragno/dist/client/vue.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/util/async.js +40 -0
- package/dist/browser/client/packages/fragno/dist/util/async.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/util/content-type.js +49 -0
- package/dist/browser/client/packages/fragno/dist/util/content-type.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/util/nanostores.js +31 -0
- package/dist/browser/client/packages/fragno/dist/util/nanostores.js.map +1 -0
- package/dist/browser/client/packages/fragno/dist/util/ssr.js +18 -0
- package/dist/browser/client/packages/fragno/dist/util/ssr.js.map +1 -0
- package/dist/browser/client/react.d.ts +295 -0
- package/dist/browser/client/react.d.ts.map +1 -0
- package/dist/browser/client/react.js +11 -0
- package/dist/browser/client/react.js.map +1 -0
- package/dist/browser/client/solid.d.ts +303 -0
- package/dist/browser/client/solid.d.ts.map +1 -0
- package/dist/browser/client/solid.js +11 -0
- package/dist/browser/client/solid.js.map +1 -0
- package/dist/browser/client/svelte.d.ts +295 -0
- package/dist/browser/client/svelte.d.ts.map +1 -0
- package/dist/browser/client/svelte.js +11 -0
- package/dist/browser/client/svelte.js.map +1 -0
- package/dist/browser/client/vanilla.d.ts +296 -0
- package/dist/browser/client/vanilla.d.ts.map +1 -0
- package/dist/browser/client/vanilla.js +11 -0
- package/dist/browser/client/vanilla.js.map +1 -0
- package/dist/browser/client/vue.d.ts +295 -0
- package/dist/browser/client/vue.d.ts.map +1 -0
- package/dist/browser/client/vue.js +11 -0
- package/dist/browser/client/vue.js.map +1 -0
- package/dist/browser/index-BdjKPO4J.d.ts +177 -0
- package/dist/browser/index-BdjKPO4J.d.ts.map +1 -0
- package/dist/browser/index.js +3 -0
- package/dist/browser/src-vdNJUbjT.js +1982 -0
- package/dist/browser/src-vdNJUbjT.js.map +1 -0
- package/dist/cli/commands/files/delete.d.ts +40 -0
- package/dist/cli/commands/files/delete.d.ts.map +1 -0
- package/dist/cli/commands/files/delete.js +31 -0
- package/dist/cli/commands/files/delete.js.map +1 -0
- package/dist/cli/commands/files/download-url.d.ts +40 -0
- package/dist/cli/commands/files/download-url.d.ts.map +1 -0
- package/dist/cli/commands/files/download-url.js +31 -0
- package/dist/cli/commands/files/download-url.js.map +1 -0
- package/dist/cli/commands/files/download.d.ts +49 -0
- package/dist/cli/commands/files/download.d.ts.map +1 -0
- package/dist/cli/commands/files/download.js +65 -0
- package/dist/cli/commands/files/download.js.map +1 -0
- package/dist/cli/commands/files/get.d.ts +40 -0
- package/dist/cli/commands/files/get.d.ts.map +1 -0
- package/dist/cli/commands/files/get.js +31 -0
- package/dist/cli/commands/files/get.js.map +1 -0
- package/dist/cli/commands/files/list.d.ts +56 -0
- package/dist/cli/commands/files/list.d.ts.map +1 -0
- package/dist/cli/commands/files/list.js +53 -0
- package/dist/cli/commands/files/list.js.map +1 -0
- package/dist/cli/commands/files/update.d.ts +56 -0
- package/dist/cli/commands/files/update.d.ts.map +1 -0
- package/dist/cli/commands/files/update.js +53 -0
- package/dist/cli/commands/files/update.js.map +1 -0
- package/dist/cli/commands/files/upload.d.ts +73 -0
- package/dist/cli/commands/files/upload.d.ts.map +1 -0
- package/dist/cli/commands/files/upload.js +87 -0
- package/dist/cli/commands/files/upload.js.map +1 -0
- package/dist/cli/commands/uploads/abort.d.ts +37 -0
- package/dist/cli/commands/uploads/abort.d.ts.map +1 -0
- package/dist/cli/commands/uploads/abort.js +26 -0
- package/dist/cli/commands/uploads/abort.js.map +1 -0
- package/dist/cli/commands/uploads/complete.d.ts +41 -0
- package/dist/cli/commands/uploads/complete.d.ts.map +1 -0
- package/dist/cli/commands/uploads/complete.js +45 -0
- package/dist/cli/commands/uploads/complete.js.map +1 -0
- package/dist/cli/commands/uploads/content.d.ts +46 -0
- package/dist/cli/commands/uploads/content.d.ts.map +1 -0
- package/dist/cli/commands/uploads/content.js +43 -0
- package/dist/cli/commands/uploads/content.js.map +1 -0
- package/dist/cli/commands/uploads/create.d.ts +72 -0
- package/dist/cli/commands/uploads/create.d.ts.map +1 -0
- package/dist/cli/commands/uploads/create.js +84 -0
- package/dist/cli/commands/uploads/create.js.map +1 -0
- package/dist/cli/commands/uploads/get.d.ts +37 -0
- package/dist/cli/commands/uploads/get.d.ts.map +1 -0
- package/dist/cli/commands/uploads/get.js +26 -0
- package/dist/cli/commands/uploads/get.js.map +1 -0
- package/dist/cli/commands/uploads/parts-complete.d.ts +41 -0
- package/dist/cli/commands/uploads/parts-complete.d.ts.map +1 -0
- package/dist/cli/commands/uploads/parts-complete.js +44 -0
- package/dist/cli/commands/uploads/parts-complete.js.map +1 -0
- package/dist/cli/commands/uploads/parts-list.d.ts +37 -0
- package/dist/cli/commands/uploads/parts-list.d.ts.map +1 -0
- package/dist/cli/commands/uploads/parts-list.js +26 -0
- package/dist/cli/commands/uploads/parts-list.js.map +1 -0
- package/dist/cli/commands/uploads/parts-urls.d.ts +46 -0
- package/dist/cli/commands/uploads/parts-urls.d.ts.map +1 -0
- package/dist/cli/commands/uploads/parts-urls.js +57 -0
- package/dist/cli/commands/uploads/parts-urls.js.map +1 -0
- package/dist/cli/commands/uploads/progress.d.ts +45 -0
- package/dist/cli/commands/uploads/progress.d.ts.map +1 -0
- package/dist/cli/commands/uploads/progress.js +40 -0
- package/dist/cli/commands/uploads/progress.js.map +1 -0
- package/dist/cli/commands/uploads/transfer.d.ts +73 -0
- package/dist/cli/commands/uploads/transfer.d.ts.map +1 -0
- package/dist/cli/commands/uploads/transfer.js +170 -0
- package/dist/cli/commands/uploads/transfer.js.map +1 -0
- package/dist/cli/index.d.ts +27 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +198 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/keys.js +32 -0
- package/dist/cli/keys.js.map +1 -0
- package/dist/cli/utils/client.js +174 -0
- package/dist/cli/utils/client.js.map +1 -0
- package/dist/cli/utils/options.js +135 -0
- package/dist/cli/utils/options.js.map +1 -0
- package/dist/node/cli/commands/files/delete.d.ts +40 -0
- package/dist/node/cli/commands/files/delete.d.ts.map +1 -0
- package/dist/node/cli/commands/files/delete.js +31 -0
- package/dist/node/cli/commands/files/delete.js.map +1 -0
- package/dist/node/cli/commands/files/download-url.d.ts +40 -0
- package/dist/node/cli/commands/files/download-url.d.ts.map +1 -0
- package/dist/node/cli/commands/files/download-url.js +31 -0
- package/dist/node/cli/commands/files/download-url.js.map +1 -0
- package/dist/node/cli/commands/files/download.d.ts +49 -0
- package/dist/node/cli/commands/files/download.d.ts.map +1 -0
- package/dist/node/cli/commands/files/download.js +65 -0
- package/dist/node/cli/commands/files/download.js.map +1 -0
- package/dist/node/cli/commands/files/get.d.ts +40 -0
- package/dist/node/cli/commands/files/get.d.ts.map +1 -0
- package/dist/node/cli/commands/files/get.js +31 -0
- package/dist/node/cli/commands/files/get.js.map +1 -0
- package/dist/node/cli/commands/files/list.d.ts +56 -0
- package/dist/node/cli/commands/files/list.d.ts.map +1 -0
- package/dist/node/cli/commands/files/list.js +53 -0
- package/dist/node/cli/commands/files/list.js.map +1 -0
- package/dist/node/cli/commands/files/update.d.ts +56 -0
- package/dist/node/cli/commands/files/update.d.ts.map +1 -0
- package/dist/node/cli/commands/files/update.js +53 -0
- package/dist/node/cli/commands/files/update.js.map +1 -0
- package/dist/node/cli/commands/files/upload.d.ts +73 -0
- package/dist/node/cli/commands/files/upload.d.ts.map +1 -0
- package/dist/node/cli/commands/files/upload.js +87 -0
- package/dist/node/cli/commands/files/upload.js.map +1 -0
- package/dist/node/cli/commands/uploads/abort.d.ts +37 -0
- package/dist/node/cli/commands/uploads/abort.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/abort.js +26 -0
- package/dist/node/cli/commands/uploads/abort.js.map +1 -0
- package/dist/node/cli/commands/uploads/complete.d.ts +41 -0
- package/dist/node/cli/commands/uploads/complete.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/complete.js +45 -0
- package/dist/node/cli/commands/uploads/complete.js.map +1 -0
- package/dist/node/cli/commands/uploads/content.d.ts +46 -0
- package/dist/node/cli/commands/uploads/content.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/content.js +43 -0
- package/dist/node/cli/commands/uploads/content.js.map +1 -0
- package/dist/node/cli/commands/uploads/create.d.ts +72 -0
- package/dist/node/cli/commands/uploads/create.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/create.js +84 -0
- package/dist/node/cli/commands/uploads/create.js.map +1 -0
- package/dist/node/cli/commands/uploads/get.d.ts +37 -0
- package/dist/node/cli/commands/uploads/get.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/get.js +26 -0
- package/dist/node/cli/commands/uploads/get.js.map +1 -0
- package/dist/node/cli/commands/uploads/parts-complete.d.ts +41 -0
- package/dist/node/cli/commands/uploads/parts-complete.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/parts-complete.js +44 -0
- package/dist/node/cli/commands/uploads/parts-complete.js.map +1 -0
- package/dist/node/cli/commands/uploads/parts-list.d.ts +37 -0
- package/dist/node/cli/commands/uploads/parts-list.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/parts-list.js +26 -0
- package/dist/node/cli/commands/uploads/parts-list.js.map +1 -0
- package/dist/node/cli/commands/uploads/parts-urls.d.ts +46 -0
- package/dist/node/cli/commands/uploads/parts-urls.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/parts-urls.js +57 -0
- package/dist/node/cli/commands/uploads/parts-urls.js.map +1 -0
- package/dist/node/cli/commands/uploads/progress.d.ts +45 -0
- package/dist/node/cli/commands/uploads/progress.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/progress.js +40 -0
- package/dist/node/cli/commands/uploads/progress.js.map +1 -0
- package/dist/node/cli/commands/uploads/transfer.d.ts +73 -0
- package/dist/node/cli/commands/uploads/transfer.d.ts.map +1 -0
- package/dist/node/cli/commands/uploads/transfer.js +170 -0
- package/dist/node/cli/commands/uploads/transfer.js.map +1 -0
- package/dist/node/cli/index.d.ts +27 -0
- package/dist/node/cli/index.d.ts.map +1 -0
- package/dist/node/cli/index.js +198 -0
- package/dist/node/cli/index.js.map +1 -0
- package/dist/node/cli/utils/client.js +174 -0
- package/dist/node/cli/utils/client.js.map +1 -0
- package/dist/node/cli/utils/options.js +135 -0
- package/dist/node/cli/utils/options.js.map +1 -0
- package/dist/node/client/clients.d.ts +295 -0
- package/dist/node/client/clients.d.ts.map +1 -0
- package/dist/node/client/clients.js +49 -0
- package/dist/node/client/clients.js.map +1 -0
- package/dist/node/client/helpers.d.ts +51 -0
- package/dist/node/client/helpers.d.ts.map +1 -0
- package/dist/node/client/helpers.js +242 -0
- package/dist/node/client/helpers.js.map +1 -0
- package/dist/node/client/react.d.ts +295 -0
- package/dist/node/client/react.d.ts.map +1 -0
- package/dist/node/client/react.js +11 -0
- package/dist/node/client/react.js.map +1 -0
- package/dist/node/client/solid.d.ts +303 -0
- package/dist/node/client/solid.d.ts.map +1 -0
- package/dist/node/client/solid.js +11 -0
- package/dist/node/client/solid.js.map +1 -0
- package/dist/node/client/svelte.d.ts +295 -0
- package/dist/node/client/svelte.d.ts.map +1 -0
- package/dist/node/client/svelte.js +11 -0
- package/dist/node/client/svelte.js.map +1 -0
- package/dist/node/client/vanilla.d.ts +296 -0
- package/dist/node/client/vanilla.d.ts.map +1 -0
- package/dist/node/client/vanilla.js +11 -0
- package/dist/node/client/vanilla.js.map +1 -0
- package/dist/node/client/vue.d.ts +295 -0
- package/dist/node/client/vue.d.ts.map +1 -0
- package/dist/node/client/vue.js +11 -0
- package/dist/node/client/vue.js.map +1 -0
- package/dist/node/config.d.ts +41 -0
- package/dist/node/config.d.ts.map +1 -0
- package/dist/node/config.js +26 -0
- package/dist/node/config.js.map +1 -0
- package/dist/node/definition.d.ts +829 -0
- package/dist/node/definition.d.ts.map +1 -0
- package/dist/node/definition.js +59 -0
- package/dist/node/definition.js.map +1 -0
- package/dist/node/index.d.ts +1246 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +19 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/keys.d.ts +12 -0
- package/dist/node/keys.d.ts.map +1 -0
- package/dist/node/keys.js +63 -0
- package/dist/node/keys.js.map +1 -0
- package/dist/node/routes/files.js +450 -0
- package/dist/node/routes/files.js.map +1 -0
- package/dist/node/routes/index.d.ts +2023 -0
- package/dist/node/routes/index.d.ts.map +1 -0
- package/dist/node/routes/index.js +9 -0
- package/dist/node/routes/index.js.map +1 -0
- package/dist/node/routes/shared.js +66 -0
- package/dist/node/routes/shared.js.map +1 -0
- package/dist/node/routes/uploads.js +454 -0
- package/dist/node/routes/uploads.js.map +1 -0
- package/dist/node/schema.d.ts +14 -0
- package/dist/node/schema.d.ts.map +1 -0
- package/dist/node/schema.js +30 -0
- package/dist/node/schema.js.map +1 -0
- package/dist/node/services/files.d.ts +20 -0
- package/dist/node/services/files.d.ts.map +1 -0
- package/dist/node/services/files.js +93 -0
- package/dist/node/services/files.js.map +1 -0
- package/dist/node/services/helpers.js +36 -0
- package/dist/node/services/helpers.js.map +1 -0
- package/dist/node/services/index.js +4 -0
- package/dist/node/services/uploads.d.ts +50 -0
- package/dist/node/services/uploads.d.ts.map +1 -0
- package/dist/node/services/uploads.js +358 -0
- package/dist/node/services/uploads.js.map +1 -0
- package/dist/node/storage/fs.d.ts +16 -0
- package/dist/node/storage/fs.d.ts.map +1 -0
- package/dist/node/storage/fs.js +94 -0
- package/dist/node/storage/fs.js.map +1 -0
- package/dist/node/storage/r2.d.ts +103 -0
- package/dist/node/storage/r2.d.ts.map +1 -0
- package/dist/node/storage/r2.js +23 -0
- package/dist/node/storage/r2.js.map +1 -0
- package/dist/node/storage/s3.d.ts +44 -0
- package/dist/node/storage/s3.d.ts.map +1 -0
- package/dist/node/storage/s3.js +398 -0
- package/dist/node/storage/s3.js.map +1 -0
- package/dist/node/storage/types.d.ts +118 -0
- package/dist/node/storage/types.d.ts.map +1 -0
- package/dist/node/types.d.ts +32 -0
- package/dist/node/types.d.ts.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +105 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/routes/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;cAGa,2CAAY,aAAoD,oBAAA;kBAApD;;;;;;;;;;;MAAZ,eAAgE,EAAA,CAAA,OAAA,sBAAA,EAAA,GAAA,IAAA,UAAA,CAAA,IAAA,CAAA;IAAA,CAAA,CAAA;KAAA,OAAA,gBAAA,EAAA,6BAAA,CAAA;IAApD,EAAA,mCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGstC;;;;;;;;sBAAiQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAAjQ,EAAA,CAAA,IAAA,0CAAA;;MAAiQ,WAAA,EAAA,CAAA,OAAA,iBAAA,EAAA,GAAA,IAAA,UAAA,CAAA,IAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2CAHv9C,CAAA,GAAA,CAAA;yCAAA,CAAA,KAAA,EAAA,4BAAA,0CAAA,CAAA,OAAA,EAAA,OAAA,CAAA,GAAA,SAAA,mBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uCAAA,oBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGstC;;;;;;;;sBAAiQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAjQ,SAAA,MAAA;;IAAiQ,WAAA,MAAA,GAAA,IAAA"}
|
|
@@ -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":[],"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,MAAa,eAAe,CAAC,qBAAqB,kBAAkB"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import "../schema.js";
|
|
2
|
+
import { decodeFileKey } from "../keys.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/routes/shared.ts
|
|
6
|
+
const fileKeyPartsSchema = z.array(z.union([z.string(), z.number().int()]));
|
|
7
|
+
const checksumSchema = z.object({
|
|
8
|
+
algo: z.enum(["sha256", "md5"]),
|
|
9
|
+
value: z.string()
|
|
10
|
+
}).nullable().optional();
|
|
11
|
+
const visibilitySchema = z.enum([
|
|
12
|
+
"private",
|
|
13
|
+
"public",
|
|
14
|
+
"unlisted"
|
|
15
|
+
]);
|
|
16
|
+
const fileMetadataSchema = z.object({
|
|
17
|
+
fileKey: z.string(),
|
|
18
|
+
fileKeyParts: fileKeyPartsSchema,
|
|
19
|
+
uploaderId: z.string().nullable(),
|
|
20
|
+
filename: z.string(),
|
|
21
|
+
sizeBytes: z.number(),
|
|
22
|
+
contentType: z.string(),
|
|
23
|
+
checksum: z.object({
|
|
24
|
+
algo: z.enum(["sha256", "md5"]),
|
|
25
|
+
value: z.string()
|
|
26
|
+
}).nullable(),
|
|
27
|
+
visibility: visibilitySchema,
|
|
28
|
+
tags: z.array(z.string()).nullable(),
|
|
29
|
+
metadata: z.record(z.string(), z.unknown()).nullable(),
|
|
30
|
+
status: z.enum(["ready", "deleted"]),
|
|
31
|
+
storageProvider: z.string(),
|
|
32
|
+
createdAt: z.string(),
|
|
33
|
+
updatedAt: z.string(),
|
|
34
|
+
completedAt: z.string().nullable(),
|
|
35
|
+
deletedAt: z.string().nullable(),
|
|
36
|
+
errorCode: z.string().nullable(),
|
|
37
|
+
errorMessage: z.string().nullable()
|
|
38
|
+
});
|
|
39
|
+
const toFileMetadata = (file) => {
|
|
40
|
+
const fileKeyParts = Array.from(decodeFileKey(file.fileKey));
|
|
41
|
+
const toIsoString = (value) => value ? value.toISOString() : null;
|
|
42
|
+
return {
|
|
43
|
+
fileKey: file.fileKey,
|
|
44
|
+
fileKeyParts,
|
|
45
|
+
uploaderId: file.uploaderId,
|
|
46
|
+
filename: file.filename,
|
|
47
|
+
sizeBytes: Number(file.sizeBytes),
|
|
48
|
+
contentType: file.contentType,
|
|
49
|
+
checksum: file.checksum,
|
|
50
|
+
visibility: file.visibility,
|
|
51
|
+
tags: file.tags,
|
|
52
|
+
metadata: file.metadata,
|
|
53
|
+
status: file.status,
|
|
54
|
+
storageProvider: file.storageProvider,
|
|
55
|
+
createdAt: file.createdAt.toISOString(),
|
|
56
|
+
updatedAt: file.updatedAt.toISOString(),
|
|
57
|
+
completedAt: toIsoString(file.completedAt),
|
|
58
|
+
deletedAt: toIsoString(file.deletedAt),
|
|
59
|
+
errorCode: file.errorCode,
|
|
60
|
+
errorMessage: file.errorMessage
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
//#endregion
|
|
65
|
+
export { checksumSchema, fileKeyPartsSchema, fileMetadataSchema, toFileMetadata, visibilitySchema };
|
|
66
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","names":[],"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,MAAa,qBAAqB,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAElF,MAAa,iBAAiB,EAC3B,OAAO;CACN,MAAM,EAAE,KAAK,CAAC,UAAU,MAAM,CAAC;CAC/B,OAAO,EAAE,QAAQ;CAClB,CAAC,CACD,UAAU,CACV,UAAU;AAEb,MAAa,mBAAmB,EAAE,KAAK;CAAC;CAAW;CAAU;CAAW,CAAC;AAEzE,MAAa,qBAAqB,EAAE,OAAO;CACzC,SAAS,EAAE,QAAQ;CACnB,cAAc;CACd,YAAY,EAAE,QAAQ,CAAC,UAAU;CACjC,UAAU,EAAE,QAAQ;CACpB,WAAW,EAAE,QAAQ;CACrB,aAAa,EAAE,QAAQ;CACvB,UAAU,EACP,OAAO;EACN,MAAM,EAAE,KAAK,CAAC,UAAU,MAAM,CAAC;EAC/B,OAAO,EAAE,QAAQ;EAClB,CAAC,CACD,UAAU;CACb,YAAY;CACZ,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;CACpC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,UAAU;CACtD,QAAQ,EAAE,KAAK,CAAC,SAAS,UAAU,CAAC;CACpC,iBAAiB,EAAE,QAAQ;CAC3B,WAAW,EAAE,QAAQ;CACrB,WAAW,EAAE,QAAQ;CACrB,aAAa,EAAE,QAAQ,CAAC,UAAU;CAClC,WAAW,EAAE,QAAQ,CAAC,UAAU;CAChC,WAAW,EAAE,QAAQ,CAAC,UAAU;CAChC,cAAc,EAAE,QAAQ,CAAC,UAAU;CACpC,CAAC;AAEF,MAAa,kBAAkB,SAAgC;CAC7D,MAAM,eAAe,MAAM,KAAK,cAAc,KAAK,QAAQ,CAAC;CAE5D,MAAM,eAAe,UAAoC,QAAQ,MAAM,aAAa,GAAG;AAEvF,QAAO;EACL,SAAS,KAAK;EACd;EACA,YAAY,KAAK;EACjB,UAAU,KAAK;EACf,WAAW,OAAO,KAAK,UAAU;EACjC,aAAa,KAAK;EAClB,UAAU,KAAK;EACf,YAAY,KAAK;EACjB,MAAM,KAAK;EACX,UAAU,KAAK;EACf,QAAQ,KAAK;EACb,iBAAiB,KAAK;EACtB,WAAW,KAAK,UAAU,aAAa;EACvC,WAAW,KAAK,UAAU,aAAa;EACvC,aAAa,YAAY,KAAK,YAAY;EAC1C,WAAW,YAAY,KAAK,UAAU;EACtC,WAAW,KAAK;EAChB,cAAc,KAAK;EACpB"}
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import { resolveUploadFragmentConfig } from "../config.js";
|
|
2
|
+
import { resolveFileKeyInput } from "../services/helpers.js";
|
|
3
|
+
import { uploadFragmentDefinition } from "../definition.js";
|
|
4
|
+
import { checksumSchema, fileKeyPartsSchema, fileMetadataSchema, toFileMetadata } from "./shared.js";
|
|
5
|
+
import { defineRoutes } from "@fragno-dev/core";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
|
|
8
|
+
//#region src/routes/uploads.ts
|
|
9
|
+
const uploadStrategySchema = z.enum([
|
|
10
|
+
"direct-single",
|
|
11
|
+
"direct-multipart",
|
|
12
|
+
"proxy"
|
|
13
|
+
]);
|
|
14
|
+
const safeIntSchema = z.number().int().min(0).max(Number.MAX_SAFE_INTEGER);
|
|
15
|
+
const createUploadInputSchema = z.object({
|
|
16
|
+
keyParts: fileKeyPartsSchema.optional(),
|
|
17
|
+
fileKey: z.string().optional(),
|
|
18
|
+
filename: z.string().min(1),
|
|
19
|
+
sizeBytes: safeIntSchema,
|
|
20
|
+
contentType: z.string().min(1),
|
|
21
|
+
checksum: checksumSchema.optional(),
|
|
22
|
+
tags: z.array(z.string()).optional(),
|
|
23
|
+
visibility: z.enum([
|
|
24
|
+
"private",
|
|
25
|
+
"public",
|
|
26
|
+
"unlisted"
|
|
27
|
+
]).optional(),
|
|
28
|
+
uploaderId: z.string().optional(),
|
|
29
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
30
|
+
});
|
|
31
|
+
const progressSchema = z.object({
|
|
32
|
+
bytesUploaded: safeIntSchema.optional(),
|
|
33
|
+
partsUploaded: z.number().int().min(0).optional()
|
|
34
|
+
});
|
|
35
|
+
const partNumbersSchema = z.object({ partNumbers: z.array(z.number().int().min(1)).min(1) });
|
|
36
|
+
const completePartsSchema = z.object({ parts: z.array(z.object({
|
|
37
|
+
partNumber: z.number().int().min(1),
|
|
38
|
+
etag: z.string().min(1),
|
|
39
|
+
sizeBytes: safeIntSchema
|
|
40
|
+
})).min(1) });
|
|
41
|
+
const completeUploadSchema = z.object({ parts: z.array(z.object({
|
|
42
|
+
partNumber: z.number().int().min(1),
|
|
43
|
+
etag: z.string().min(1)
|
|
44
|
+
})).optional() });
|
|
45
|
+
const uploadStatusSchema = z.object({
|
|
46
|
+
uploadId: z.string(),
|
|
47
|
+
fileKey: z.string(),
|
|
48
|
+
status: z.enum([
|
|
49
|
+
"created",
|
|
50
|
+
"in_progress",
|
|
51
|
+
"completed",
|
|
52
|
+
"aborted",
|
|
53
|
+
"failed",
|
|
54
|
+
"expired"
|
|
55
|
+
]),
|
|
56
|
+
strategy: uploadStrategySchema,
|
|
57
|
+
expectedSizeBytes: z.number(),
|
|
58
|
+
bytesUploaded: z.number(),
|
|
59
|
+
partsUploaded: z.number(),
|
|
60
|
+
partSizeBytes: z.number().nullable(),
|
|
61
|
+
expiresAt: z.date(),
|
|
62
|
+
createdAt: z.date(),
|
|
63
|
+
updatedAt: z.date(),
|
|
64
|
+
completedAt: z.date().nullable(),
|
|
65
|
+
errorCode: z.string().nullable(),
|
|
66
|
+
errorMessage: z.string().nullable()
|
|
67
|
+
});
|
|
68
|
+
const errorCodes = [
|
|
69
|
+
"UPLOAD_NOT_FOUND",
|
|
70
|
+
"UPLOAD_ALREADY_ACTIVE",
|
|
71
|
+
"UPLOAD_METADATA_MISMATCH",
|
|
72
|
+
"FILE_ALREADY_EXISTS",
|
|
73
|
+
"UPLOAD_EXPIRED",
|
|
74
|
+
"UPLOAD_INVALID_STATE",
|
|
75
|
+
"INVALID_FILE_KEY",
|
|
76
|
+
"INVALID_CHECKSUM",
|
|
77
|
+
"INVALID_REQUEST",
|
|
78
|
+
"STORAGE_ERROR"
|
|
79
|
+
];
|
|
80
|
+
const handleServiceError = (err, error) => {
|
|
81
|
+
if (!(err instanceof Error)) throw err;
|
|
82
|
+
switch (err.message) {
|
|
83
|
+
case "UPLOAD_NOT_FOUND": return error({
|
|
84
|
+
message: "Upload not found",
|
|
85
|
+
code: "UPLOAD_NOT_FOUND"
|
|
86
|
+
}, 404);
|
|
87
|
+
case "FILE_ALREADY_EXISTS": return error({
|
|
88
|
+
message: "File already exists",
|
|
89
|
+
code: "FILE_ALREADY_EXISTS"
|
|
90
|
+
}, 409);
|
|
91
|
+
case "UPLOAD_ALREADY_ACTIVE": return error({
|
|
92
|
+
message: "Upload already active",
|
|
93
|
+
code: "UPLOAD_ALREADY_ACTIVE"
|
|
94
|
+
}, 409);
|
|
95
|
+
case "UPLOAD_METADATA_MISMATCH": return error({
|
|
96
|
+
message: "Upload metadata mismatch",
|
|
97
|
+
code: "UPLOAD_METADATA_MISMATCH"
|
|
98
|
+
}, 409);
|
|
99
|
+
case "UPLOAD_EXPIRED": return error({
|
|
100
|
+
message: "Upload expired",
|
|
101
|
+
code: "UPLOAD_EXPIRED"
|
|
102
|
+
}, 410);
|
|
103
|
+
case "UPLOAD_INVALID_STATE": return error({
|
|
104
|
+
message: "Upload invalid state",
|
|
105
|
+
code: "UPLOAD_INVALID_STATE"
|
|
106
|
+
}, 409);
|
|
107
|
+
case "INVALID_FILE_KEY": return error({
|
|
108
|
+
message: "Invalid file key",
|
|
109
|
+
code: "INVALID_FILE_KEY"
|
|
110
|
+
}, 400);
|
|
111
|
+
case "INVALID_CHECKSUM": return error({
|
|
112
|
+
message: "Invalid checksum",
|
|
113
|
+
code: "INVALID_CHECKSUM"
|
|
114
|
+
}, 400);
|
|
115
|
+
case "INVALID_REQUEST": return error({
|
|
116
|
+
message: "Invalid request",
|
|
117
|
+
code: "INVALID_REQUEST"
|
|
118
|
+
}, 400);
|
|
119
|
+
case "STORAGE_ERROR": return error({
|
|
120
|
+
message: "Storage error",
|
|
121
|
+
code: "STORAGE_ERROR"
|
|
122
|
+
}, 502);
|
|
123
|
+
default: throw err;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const uploadRoutesFactory = defineRoutes(uploadFragmentDefinition).create(({ services, defineRoute, config }) => {
|
|
127
|
+
const getResolvedConfig = () => resolveUploadFragmentConfig(config);
|
|
128
|
+
return [
|
|
129
|
+
defineRoute({
|
|
130
|
+
method: "POST",
|
|
131
|
+
path: "/uploads",
|
|
132
|
+
inputSchema: createUploadInputSchema,
|
|
133
|
+
outputSchema: z.object({
|
|
134
|
+
uploadId: z.string(),
|
|
135
|
+
fileKey: z.string(),
|
|
136
|
+
status: z.enum(["created", "in_progress"]),
|
|
137
|
+
strategy: uploadStrategySchema,
|
|
138
|
+
expiresAt: z.date(),
|
|
139
|
+
upload: z.object({
|
|
140
|
+
mode: z.enum(["single", "multipart"]),
|
|
141
|
+
transport: z.enum(["direct", "proxy"]),
|
|
142
|
+
uploadUrl: z.string().optional(),
|
|
143
|
+
uploadHeaders: z.record(z.string(), z.string()).optional(),
|
|
144
|
+
partSizeBytes: z.number().optional(),
|
|
145
|
+
maxParts: z.number().optional(),
|
|
146
|
+
partsEndpoint: z.string().optional(),
|
|
147
|
+
completeEndpoint: z.string(),
|
|
148
|
+
contentEndpoint: z.string().optional()
|
|
149
|
+
})
|
|
150
|
+
}),
|
|
151
|
+
errorCodes,
|
|
152
|
+
handler: async function({ input }, { json, error }) {
|
|
153
|
+
const payload = await input.valid();
|
|
154
|
+
const resolvedConfig = getResolvedConfig();
|
|
155
|
+
let resolvedKey;
|
|
156
|
+
try {
|
|
157
|
+
resolvedKey = resolveFileKeyInput({
|
|
158
|
+
keyParts: payload.keyParts,
|
|
159
|
+
fileKey: payload.fileKey
|
|
160
|
+
});
|
|
161
|
+
} catch (err) {
|
|
162
|
+
return handleServiceError(err, error);
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
const existing = await this.handlerTx().withServiceCalls(() => [services.checkUploadAvailability(payload, { allowIdempotentReuse: true })]).transform(({ serviceResult: [result] }) => result).execute();
|
|
166
|
+
if (existing) return json(existing);
|
|
167
|
+
} catch (err) {
|
|
168
|
+
return handleServiceError(err, error);
|
|
169
|
+
}
|
|
170
|
+
let storageInit;
|
|
171
|
+
try {
|
|
172
|
+
storageInit = await resolvedConfig.storage.initUpload({
|
|
173
|
+
fileKey: resolvedKey.fileKey,
|
|
174
|
+
fileKeyParts: resolvedKey.fileKeyParts,
|
|
175
|
+
sizeBytes: BigInt(payload.sizeBytes),
|
|
176
|
+
contentType: payload.contentType,
|
|
177
|
+
checksum: payload.checksum ?? null,
|
|
178
|
+
metadata: payload.metadata ?? null
|
|
179
|
+
});
|
|
180
|
+
} catch (err) {
|
|
181
|
+
if (err instanceof Error && err.message === "INVALID_CHECKSUM") return error({
|
|
182
|
+
message: "Invalid checksum",
|
|
183
|
+
code: "INVALID_CHECKSUM"
|
|
184
|
+
}, 400);
|
|
185
|
+
return error({
|
|
186
|
+
message: "Storage error",
|
|
187
|
+
code: "STORAGE_ERROR"
|
|
188
|
+
}, 502);
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
const result = await this.handlerTx().withServiceCalls(() => [services.createUploadRecord({
|
|
192
|
+
...payload,
|
|
193
|
+
storageInit,
|
|
194
|
+
allowIdempotentReuse: true
|
|
195
|
+
})]).transform(({ serviceResult: [created] }) => created).execute();
|
|
196
|
+
if (result.reused && storageInit.strategy === "direct-multipart" && resolvedConfig.storage.abortMultipartUpload && storageInit.storageUploadId) try {
|
|
197
|
+
await resolvedConfig.storage.abortMultipartUpload({
|
|
198
|
+
storageKey: storageInit.storageKey,
|
|
199
|
+
storageUploadId: storageInit.storageUploadId
|
|
200
|
+
});
|
|
201
|
+
} catch {}
|
|
202
|
+
return json(result.result);
|
|
203
|
+
} catch (err) {
|
|
204
|
+
if (storageInit.strategy === "direct-multipart" && resolvedConfig.storage.abortMultipartUpload && storageInit.storageUploadId) try {
|
|
205
|
+
await resolvedConfig.storage.abortMultipartUpload({
|
|
206
|
+
storageKey: storageInit.storageKey,
|
|
207
|
+
storageUploadId: storageInit.storageUploadId
|
|
208
|
+
});
|
|
209
|
+
} catch {}
|
|
210
|
+
return handleServiceError(err, error);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}),
|
|
214
|
+
defineRoute({
|
|
215
|
+
method: "GET",
|
|
216
|
+
path: "/uploads/:uploadId",
|
|
217
|
+
outputSchema: uploadStatusSchema,
|
|
218
|
+
errorCodes,
|
|
219
|
+
handler: async function({ pathParams }, { json, error }) {
|
|
220
|
+
try {
|
|
221
|
+
const upload = await this.handlerTx().withServiceCalls(() => [services.getUploadStatus(pathParams.uploadId)]).transform(({ serviceResult: [result] }) => result).execute();
|
|
222
|
+
return json({
|
|
223
|
+
uploadId: upload.id.toString(),
|
|
224
|
+
fileKey: upload.fileKey,
|
|
225
|
+
status: upload.status,
|
|
226
|
+
strategy: upload.strategy,
|
|
227
|
+
expectedSizeBytes: Number(upload.expectedSizeBytes),
|
|
228
|
+
bytesUploaded: Number(upload.bytesUploaded),
|
|
229
|
+
partsUploaded: upload.partsUploaded,
|
|
230
|
+
partSizeBytes: upload.partSizeBytes,
|
|
231
|
+
expiresAt: upload.expiresAt,
|
|
232
|
+
createdAt: upload.createdAt,
|
|
233
|
+
updatedAt: upload.updatedAt,
|
|
234
|
+
completedAt: upload.completedAt,
|
|
235
|
+
errorCode: upload.errorCode,
|
|
236
|
+
errorMessage: upload.errorMessage
|
|
237
|
+
});
|
|
238
|
+
} catch (err) {
|
|
239
|
+
return handleServiceError(err, error);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}),
|
|
243
|
+
defineRoute({
|
|
244
|
+
method: "POST",
|
|
245
|
+
path: "/uploads/:uploadId/progress",
|
|
246
|
+
inputSchema: progressSchema,
|
|
247
|
+
outputSchema: z.object({
|
|
248
|
+
bytesUploaded: z.number(),
|
|
249
|
+
partsUploaded: z.number()
|
|
250
|
+
}),
|
|
251
|
+
errorCodes,
|
|
252
|
+
handler: async function({ pathParams, input }, { json, error }) {
|
|
253
|
+
const payload = await input.valid();
|
|
254
|
+
try {
|
|
255
|
+
const result = await this.handlerTx().withServiceCalls(() => [services.recordUploadProgress(pathParams.uploadId, payload)]).transform(({ serviceResult: [updated] }) => updated).execute();
|
|
256
|
+
return json({
|
|
257
|
+
bytesUploaded: Number(result.bytesUploaded),
|
|
258
|
+
partsUploaded: result.partsUploaded
|
|
259
|
+
});
|
|
260
|
+
} catch (err) {
|
|
261
|
+
return handleServiceError(err, error);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}),
|
|
265
|
+
defineRoute({
|
|
266
|
+
method: "POST",
|
|
267
|
+
path: "/uploads/:uploadId/parts",
|
|
268
|
+
inputSchema: partNumbersSchema,
|
|
269
|
+
outputSchema: z.object({ parts: z.array(z.object({
|
|
270
|
+
partNumber: z.number(),
|
|
271
|
+
url: z.string(),
|
|
272
|
+
headers: z.record(z.string(), z.string()).optional()
|
|
273
|
+
})) }),
|
|
274
|
+
errorCodes,
|
|
275
|
+
handler: async function({ pathParams, input }, { json, error }) {
|
|
276
|
+
const payload = await input.valid();
|
|
277
|
+
const resolvedConfig = getResolvedConfig();
|
|
278
|
+
try {
|
|
279
|
+
const upload = await this.handlerTx().withServiceCalls(() => [services.getUploadStorageInfo(pathParams.uploadId)]).transform(({ serviceResult: [result] }) => result).execute();
|
|
280
|
+
if (upload.strategy !== "direct-multipart") return error({
|
|
281
|
+
message: "Upload invalid state",
|
|
282
|
+
code: "UPLOAD_INVALID_STATE"
|
|
283
|
+
}, 409);
|
|
284
|
+
if (!resolvedConfig.storage.getPartUploadUrls) return error({
|
|
285
|
+
message: "Storage error",
|
|
286
|
+
code: "STORAGE_ERROR"
|
|
287
|
+
}, 502);
|
|
288
|
+
return json({ parts: await resolvedConfig.storage.getPartUploadUrls({
|
|
289
|
+
storageKey: upload.storageKey,
|
|
290
|
+
storageUploadId: upload.storageUploadId ?? "",
|
|
291
|
+
partNumbers: payload.partNumbers,
|
|
292
|
+
partSizeBytes: upload.partSizeBytes ?? 0
|
|
293
|
+
}) });
|
|
294
|
+
} catch (err) {
|
|
295
|
+
return handleServiceError(err, error);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}),
|
|
299
|
+
defineRoute({
|
|
300
|
+
method: "GET",
|
|
301
|
+
path: "/uploads/:uploadId/parts",
|
|
302
|
+
outputSchema: z.object({ parts: z.array(z.object({
|
|
303
|
+
partNumber: z.number(),
|
|
304
|
+
etag: z.string(),
|
|
305
|
+
sizeBytes: z.number(),
|
|
306
|
+
createdAt: z.date()
|
|
307
|
+
})) }),
|
|
308
|
+
errorCodes,
|
|
309
|
+
handler: async function({ pathParams }, { json, error }) {
|
|
310
|
+
try {
|
|
311
|
+
return json({ parts: (await this.handlerTx().withServiceCalls(() => [services.getUploadParts(pathParams.uploadId)]).transform(({ serviceResult: [result] }) => result).execute()).map((part) => ({
|
|
312
|
+
partNumber: part.partNumber,
|
|
313
|
+
etag: part.etag,
|
|
314
|
+
sizeBytes: Number(part.sizeBytes),
|
|
315
|
+
createdAt: part.createdAt
|
|
316
|
+
})) });
|
|
317
|
+
} catch (err) {
|
|
318
|
+
return handleServiceError(err, error);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}),
|
|
322
|
+
defineRoute({
|
|
323
|
+
method: "POST",
|
|
324
|
+
path: "/uploads/:uploadId/parts/complete",
|
|
325
|
+
inputSchema: completePartsSchema,
|
|
326
|
+
outputSchema: z.object({
|
|
327
|
+
bytesUploaded: z.number(),
|
|
328
|
+
partsUploaded: z.number()
|
|
329
|
+
}),
|
|
330
|
+
errorCodes,
|
|
331
|
+
handler: async function({ pathParams, input }, { json, error }) {
|
|
332
|
+
const payload = await input.valid();
|
|
333
|
+
try {
|
|
334
|
+
const result = await this.handlerTx().withServiceCalls(() => [services.recordUploadParts(pathParams.uploadId, payload)]).transform(({ serviceResult: [updated] }) => updated).execute();
|
|
335
|
+
return json({
|
|
336
|
+
bytesUploaded: Number(result.bytesUploaded),
|
|
337
|
+
partsUploaded: result.partsUploaded
|
|
338
|
+
});
|
|
339
|
+
} catch (err) {
|
|
340
|
+
return handleServiceError(err, error);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}),
|
|
344
|
+
defineRoute({
|
|
345
|
+
method: "POST",
|
|
346
|
+
path: "/uploads/:uploadId/complete",
|
|
347
|
+
inputSchema: completeUploadSchema,
|
|
348
|
+
outputSchema: fileMetadataSchema,
|
|
349
|
+
errorCodes,
|
|
350
|
+
handler: async function({ pathParams, input }, { json, error }) {
|
|
351
|
+
const payload = await input.valid();
|
|
352
|
+
const resolvedConfig = getResolvedConfig();
|
|
353
|
+
try {
|
|
354
|
+
const upload = await this.handlerTx().withServiceCalls(() => [services.getUploadStorageInfo(pathParams.uploadId)]).transform(({ serviceResult: [result] }) => result).execute();
|
|
355
|
+
if (await this.handlerTx().withServiceCalls(() => [services.findFileByKey(upload.fileKey)]).transform(({ serviceResult: [result] }) => result).execute()) return error({
|
|
356
|
+
message: "File already exists",
|
|
357
|
+
code: "FILE_ALREADY_EXISTS"
|
|
358
|
+
}, 409);
|
|
359
|
+
let finalizeResult;
|
|
360
|
+
if (upload.strategy === "direct-multipart") {
|
|
361
|
+
if (!resolvedConfig.storage.completeMultipartUpload) return error({
|
|
362
|
+
message: "Storage error",
|
|
363
|
+
code: "STORAGE_ERROR"
|
|
364
|
+
}, 502);
|
|
365
|
+
if (!payload.parts || payload.parts.length === 0) return error({
|
|
366
|
+
message: "Upload invalid state",
|
|
367
|
+
code: "UPLOAD_INVALID_STATE"
|
|
368
|
+
}, 409);
|
|
369
|
+
await resolvedConfig.storage.completeMultipartUpload({
|
|
370
|
+
storageKey: upload.storageKey,
|
|
371
|
+
storageUploadId: upload.storageUploadId ?? "",
|
|
372
|
+
parts: payload.parts
|
|
373
|
+
});
|
|
374
|
+
} else if (resolvedConfig.storage.finalizeUpload) finalizeResult = await resolvedConfig.storage.finalizeUpload({
|
|
375
|
+
storageKey: upload.storageKey,
|
|
376
|
+
expectedSizeBytes: upload.expectedSizeBytes,
|
|
377
|
+
checksum: upload.checksum
|
|
378
|
+
});
|
|
379
|
+
return json(toFileMetadata((await this.handlerTx().withServiceCalls(() => [services.markUploadComplete(upload.id.toString(), upload.fileKey, finalizeResult?.sizeBytes ? { sizeBytes: finalizeResult.sizeBytes } : void 0)]).transform(({ serviceResult: [result] }) => result).execute()).file));
|
|
380
|
+
} catch (err) {
|
|
381
|
+
return handleServiceError(err, error);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}),
|
|
385
|
+
defineRoute({
|
|
386
|
+
method: "POST",
|
|
387
|
+
path: "/uploads/:uploadId/abort",
|
|
388
|
+
outputSchema: z.object({ ok: z.literal(true) }),
|
|
389
|
+
errorCodes,
|
|
390
|
+
handler: async function({ pathParams }, { json, error }) {
|
|
391
|
+
const resolvedConfig = getResolvedConfig();
|
|
392
|
+
try {
|
|
393
|
+
const upload = await this.handlerTx().withServiceCalls(() => [services.getUploadStorageInfo(pathParams.uploadId)]).transform(({ serviceResult: [result] }) => result).execute();
|
|
394
|
+
if (upload.strategy === "direct-multipart" && resolvedConfig.storage.abortMultipartUpload) await resolvedConfig.storage.abortMultipartUpload({
|
|
395
|
+
storageKey: upload.storageKey,
|
|
396
|
+
storageUploadId: upload.storageUploadId ?? ""
|
|
397
|
+
});
|
|
398
|
+
await this.handlerTx().withServiceCalls(() => [services.markUploadAborted(upload.id.toString())]).execute();
|
|
399
|
+
return json({ ok: true });
|
|
400
|
+
} catch (err) {
|
|
401
|
+
return handleServiceError(err, error);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}),
|
|
405
|
+
defineRoute({
|
|
406
|
+
method: "PUT",
|
|
407
|
+
path: "/uploads/:uploadId/content",
|
|
408
|
+
contentType: "application/octet-stream",
|
|
409
|
+
outputSchema: fileMetadataSchema,
|
|
410
|
+
errorCodes,
|
|
411
|
+
handler: async function(context, { json, error }) {
|
|
412
|
+
const { pathParams } = context;
|
|
413
|
+
const resolvedConfig = getResolvedConfig();
|
|
414
|
+
try {
|
|
415
|
+
const upload = await this.handlerTx().withServiceCalls(() => [services.getUploadStorageInfo(pathParams.uploadId)]).transform(({ serviceResult: [result$1] }) => result$1).execute();
|
|
416
|
+
if (upload.strategy !== "proxy") return error({
|
|
417
|
+
message: "Upload invalid state",
|
|
418
|
+
code: "UPLOAD_INVALID_STATE"
|
|
419
|
+
}, 409);
|
|
420
|
+
if (await this.handlerTx().withServiceCalls(() => [services.findFileByKey(upload.fileKey)]).transform(({ serviceResult: [result$1] }) => result$1).execute()) return error({
|
|
421
|
+
message: "File already exists",
|
|
422
|
+
code: "FILE_ALREADY_EXISTS"
|
|
423
|
+
}, 409);
|
|
424
|
+
if (!resolvedConfig.storage.writeStream) return error({
|
|
425
|
+
message: "Storage error",
|
|
426
|
+
code: "STORAGE_ERROR"
|
|
427
|
+
}, 502);
|
|
428
|
+
let result;
|
|
429
|
+
try {
|
|
430
|
+
result = await resolvedConfig.storage.writeStream({
|
|
431
|
+
storageKey: upload.storageKey,
|
|
432
|
+
body: context.bodyStream(),
|
|
433
|
+
contentType: upload.contentType,
|
|
434
|
+
sizeBytes: upload.expectedSizeBytes
|
|
435
|
+
});
|
|
436
|
+
} catch {
|
|
437
|
+
await this.handlerTx().withServiceCalls(() => [services.markUploadFailed(upload.id.toString(), "STORAGE_ERROR", "Storage upload failed")]).execute();
|
|
438
|
+
return error({
|
|
439
|
+
message: "Storage error",
|
|
440
|
+
code: "STORAGE_ERROR"
|
|
441
|
+
}, 502);
|
|
442
|
+
}
|
|
443
|
+
return json(toFileMetadata((await this.handlerTx().withServiceCalls(() => [services.markUploadComplete(upload.id.toString(), upload.fileKey, result?.sizeBytes ? { sizeBytes: result.sizeBytes } : void 0)]).transform(({ serviceResult: [done] }) => done).execute()).file));
|
|
444
|
+
} catch (err) {
|
|
445
|
+
return handleServiceError(err, error);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
})
|
|
449
|
+
];
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
//#endregion
|
|
453
|
+
export { uploadRoutesFactory };
|
|
454
|
+
//# sourceMappingURL=uploads.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploads.js","names":["finalizeResult: { sizeBytes?: bigint } | undefined","result","result: Awaited<ReturnType<NonNullable<typeof resolvedConfig.storage.writeStream>>>"],"sources":["../../../src/routes/uploads.ts"],"sourcesContent":["import { defineRoutes } from \"@fragno-dev/core\";\nimport type { FragnoRouteConfig } from \"@fragno-dev/core\";\nimport { z } from \"zod\";\nimport { resolveUploadFragmentConfig } from \"../config\";\nimport { uploadFragmentDefinition } from \"../definition\";\nimport { resolveFileKeyInput } from \"../services/helpers\";\nimport { checksumSchema, fileKeyPartsSchema, fileMetadataSchema, toFileMetadata } from \"./shared\";\nimport type { UploadStatus, UploadStrategy } from \"../types\";\nimport type { UploadChecksum } from \"../storage/types\";\n\nconst uploadStrategySchema = z.enum([\"direct-single\", \"direct-multipart\", \"proxy\"]);\nconst safeIntSchema = z.number().int().min(0).max(Number.MAX_SAFE_INTEGER);\n\nconst createUploadInputSchema = z.object({\n keyParts: fileKeyPartsSchema.optional(),\n fileKey: z.string().optional(),\n filename: z.string().min(1),\n sizeBytes: safeIntSchema,\n contentType: z.string().min(1),\n checksum: checksumSchema.optional(),\n tags: z.array(z.string()).optional(),\n visibility: z.enum([\"private\", \"public\", \"unlisted\"]).optional(),\n uploaderId: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nconst progressSchema = z.object({\n bytesUploaded: safeIntSchema.optional(),\n partsUploaded: z.number().int().min(0).optional(),\n});\n\nconst partNumbersSchema = z.object({\n partNumbers: z.array(z.number().int().min(1)).min(1),\n});\n\nconst completePartsSchema = z.object({\n parts: z\n .array(\n z.object({\n partNumber: z.number().int().min(1),\n etag: z.string().min(1),\n sizeBytes: safeIntSchema,\n }),\n )\n .min(1),\n});\n\nconst completeUploadSchema = z.object({\n parts: z\n .array(\n z.object({\n partNumber: z.number().int().min(1),\n etag: z.string().min(1),\n }),\n )\n .optional(),\n});\n\nconst uploadStatusSchema = z.object({\n uploadId: z.string(),\n fileKey: z.string(),\n status: z.enum([\"created\", \"in_progress\", \"completed\", \"aborted\", \"failed\", \"expired\"]),\n strategy: uploadStrategySchema,\n expectedSizeBytes: z.number(),\n bytesUploaded: z.number(),\n partsUploaded: z.number(),\n partSizeBytes: z.number().nullable(),\n expiresAt: z.date(),\n createdAt: z.date(),\n updatedAt: z.date(),\n completedAt: z.date().nullable(),\n errorCode: z.string().nullable(),\n errorMessage: z.string().nullable(),\n});\n\nconst errorCodes = [\n \"UPLOAD_NOT_FOUND\",\n \"UPLOAD_ALREADY_ACTIVE\",\n \"UPLOAD_METADATA_MISMATCH\",\n \"FILE_ALREADY_EXISTS\",\n \"UPLOAD_EXPIRED\",\n \"UPLOAD_INVALID_STATE\",\n \"INVALID_FILE_KEY\",\n \"INVALID_CHECKSUM\",\n \"INVALID_REQUEST\",\n \"STORAGE_ERROR\",\n] as const;\n\ntype UploadErrorCode = (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 UploadErrorCode>(\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 \"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_METADATA_MISMATCH\":\n return error(\n { message: \"Upload metadata mismatch\", code: \"UPLOAD_METADATA_MISMATCH\" 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 case \"STORAGE_ERROR\":\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" as Code }, 502);\n default:\n throw err;\n }\n};\n\nexport const uploadRoutesFactory = defineRoutes(uploadFragmentDefinition).create(\n ({ services, defineRoute, config }) => {\n const getResolvedConfig = () => resolveUploadFragmentConfig(config);\n\n return [\n defineRoute({\n method: \"POST\",\n path: \"/uploads\",\n inputSchema: createUploadInputSchema,\n outputSchema: z.object({\n uploadId: z.string(),\n fileKey: z.string(),\n status: z.enum([\"created\", \"in_progress\"]),\n strategy: uploadStrategySchema,\n expiresAt: z.date(),\n upload: z.object({\n mode: z.enum([\"single\", \"multipart\"]),\n transport: z.enum([\"direct\", \"proxy\"]),\n uploadUrl: z.string().optional(),\n uploadHeaders: z.record(z.string(), z.string()).optional(),\n partSizeBytes: z.number().optional(),\n maxParts: z.number().optional(),\n partsEndpoint: z.string().optional(),\n completeEndpoint: z.string(),\n contentEndpoint: z.string().optional(),\n }),\n }),\n errorCodes,\n handler: async function ({ input }, { json, error }) {\n const payload = await input.valid();\n const resolvedConfig = getResolvedConfig();\n\n let resolvedKey;\n try {\n resolvedKey = resolveFileKeyInput({\n keyParts: payload.keyParts,\n fileKey: payload.fileKey,\n });\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n try {\n const existing = await this.handlerTx()\n .withServiceCalls(() => [\n services.checkUploadAvailability(payload, { allowIdempotentReuse: true }),\n ])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n if (existing) {\n return json(existing);\n }\n } catch (err) {\n return handleServiceError(err, error);\n }\n\n let storageInit;\n try {\n storageInit = await resolvedConfig.storage.initUpload({\n fileKey: resolvedKey.fileKey,\n fileKeyParts: resolvedKey.fileKeyParts,\n sizeBytes: BigInt(payload.sizeBytes),\n contentType: payload.contentType,\n checksum: payload.checksum ?? null,\n metadata: payload.metadata ?? null,\n });\n } catch (err) {\n if (err instanceof Error && err.message === \"INVALID_CHECKSUM\") {\n return error({ message: \"Invalid checksum\", code: \"INVALID_CHECKSUM\" }, 400);\n }\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n\n try {\n const result = await this.handlerTx()\n .withServiceCalls(() => [\n services.createUploadRecord({\n ...payload,\n storageInit,\n allowIdempotentReuse: true,\n }),\n ])\n .transform(({ serviceResult: [created] }) => created)\n .execute();\n\n if (\n result.reused &&\n storageInit.strategy === \"direct-multipart\" &&\n resolvedConfig.storage.abortMultipartUpload &&\n storageInit.storageUploadId\n ) {\n try {\n await resolvedConfig.storage.abortMultipartUpload({\n storageKey: storageInit.storageKey,\n storageUploadId: storageInit.storageUploadId,\n });\n } catch {\n // Ignore abort failures for races.\n }\n }\n\n return json(result.result);\n } catch (err) {\n if (\n storageInit.strategy === \"direct-multipart\" &&\n resolvedConfig.storage.abortMultipartUpload &&\n storageInit.storageUploadId\n ) {\n try {\n await resolvedConfig.storage.abortMultipartUpload({\n storageKey: storageInit.storageKey,\n storageUploadId: storageInit.storageUploadId,\n });\n } catch {\n // Ignore abort failures for races.\n }\n }\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/uploads/:uploadId\",\n outputSchema: uploadStatusSchema,\n errorCodes,\n handler: async function ({ pathParams }, { json, error }) {\n try {\n const upload = await this.handlerTx()\n .withServiceCalls(() => [services.getUploadStatus(pathParams.uploadId)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n return json({\n uploadId: upload.id.toString(),\n fileKey: upload.fileKey,\n status: upload.status as UploadStatus,\n strategy: upload.strategy as UploadStrategy,\n expectedSizeBytes: Number(upload.expectedSizeBytes),\n bytesUploaded: Number(upload.bytesUploaded),\n partsUploaded: upload.partsUploaded,\n partSizeBytes: upload.partSizeBytes,\n expiresAt: upload.expiresAt,\n createdAt: upload.createdAt,\n updatedAt: upload.updatedAt,\n completedAt: upload.completedAt,\n errorCode: upload.errorCode,\n errorMessage: upload.errorMessage,\n });\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/uploads/:uploadId/progress\",\n inputSchema: progressSchema,\n outputSchema: z.object({\n bytesUploaded: z.number(),\n partsUploaded: z.number(),\n }),\n errorCodes,\n handler: async function ({ pathParams, input }, { json, error }) {\n const payload = await input.valid();\n try {\n const result = await this.handlerTx()\n .withServiceCalls(() => [services.recordUploadProgress(pathParams.uploadId, payload)])\n .transform(({ serviceResult: [updated] }) => updated)\n .execute();\n\n return json({\n bytesUploaded: Number(result.bytesUploaded),\n partsUploaded: result.partsUploaded,\n });\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/uploads/:uploadId/parts\",\n inputSchema: partNumbersSchema,\n outputSchema: z.object({\n parts: z.array(\n z.object({\n partNumber: z.number(),\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n }),\n ),\n }),\n errorCodes,\n handler: async function ({ pathParams, input }, { json, error }) {\n const payload = await input.valid();\n const resolvedConfig = getResolvedConfig();\n try {\n const upload = await this.handlerTx()\n .withServiceCalls(() => [services.getUploadStorageInfo(pathParams.uploadId)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n if (upload.strategy !== \"direct-multipart\") {\n return error({ message: \"Upload invalid state\", code: \"UPLOAD_INVALID_STATE\" }, 409);\n }\n\n if (!resolvedConfig.storage.getPartUploadUrls) {\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n\n const parts = await resolvedConfig.storage.getPartUploadUrls({\n storageKey: upload.storageKey,\n storageUploadId: upload.storageUploadId ?? \"\",\n partNumbers: payload.partNumbers,\n partSizeBytes: upload.partSizeBytes ?? 0,\n });\n\n return json({ parts });\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/uploads/:uploadId/parts\",\n outputSchema: z.object({\n parts: z.array(\n z.object({\n partNumber: z.number(),\n etag: z.string(),\n sizeBytes: z.number(),\n createdAt: z.date(),\n }),\n ),\n }),\n errorCodes,\n handler: async function ({ pathParams }, { json, error }) {\n try {\n const parts = await this.handlerTx()\n .withServiceCalls(() => [services.getUploadParts(pathParams.uploadId)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n const typedParts = parts as {\n partNumber: number;\n etag: string;\n sizeBytes: bigint;\n createdAt: Date;\n }[];\n\n return json({\n parts: typedParts.map((part) => ({\n partNumber: part.partNumber,\n etag: part.etag,\n sizeBytes: Number(part.sizeBytes),\n createdAt: part.createdAt,\n })),\n });\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/uploads/:uploadId/parts/complete\",\n inputSchema: completePartsSchema,\n outputSchema: z.object({\n bytesUploaded: z.number(),\n partsUploaded: z.number(),\n }),\n errorCodes,\n handler: async function ({ pathParams, input }, { json, error }) {\n const payload = await input.valid();\n try {\n const result = await this.handlerTx()\n .withServiceCalls(() => [services.recordUploadParts(pathParams.uploadId, payload)])\n .transform(({ serviceResult: [updated] }) => updated)\n .execute();\n\n return json({\n bytesUploaded: Number(result.bytesUploaded),\n partsUploaded: result.partsUploaded,\n });\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/uploads/:uploadId/complete\",\n inputSchema: completeUploadSchema,\n outputSchema: fileMetadataSchema,\n errorCodes,\n handler: async function ({ pathParams, input }, { json, error }) {\n const payload = await input.valid();\n const resolvedConfig = getResolvedConfig();\n try {\n const upload = await this.handlerTx()\n .withServiceCalls(() => [services.getUploadStorageInfo(pathParams.uploadId)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n const existingFile = await this.handlerTx()\n .withServiceCalls(() => [services.findFileByKey(upload.fileKey)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n if (existingFile) {\n return error({ message: \"File already exists\", code: \"FILE_ALREADY_EXISTS\" }, 409);\n }\n\n let finalizeResult: { sizeBytes?: bigint } | undefined;\n\n if (upload.strategy === \"direct-multipart\") {\n if (!resolvedConfig.storage.completeMultipartUpload) {\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n\n if (!payload.parts || payload.parts.length === 0) {\n return error(\n { message: \"Upload invalid state\", code: \"UPLOAD_INVALID_STATE\" },\n 409,\n );\n }\n\n await resolvedConfig.storage.completeMultipartUpload({\n storageKey: upload.storageKey,\n storageUploadId: upload.storageUploadId ?? \"\",\n parts: payload.parts,\n });\n } else if (resolvedConfig.storage.finalizeUpload) {\n finalizeResult = await resolvedConfig.storage.finalizeUpload({\n storageKey: upload.storageKey,\n expectedSizeBytes: upload.expectedSizeBytes,\n checksum: upload.checksum as UploadChecksum | null,\n });\n }\n\n const completed = await this.handlerTx()\n .withServiceCalls(() => [\n services.markUploadComplete(\n upload.id.toString(),\n upload.fileKey,\n finalizeResult?.sizeBytes ? { sizeBytes: finalizeResult.sizeBytes } : undefined,\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: \"POST\",\n path: \"/uploads/:uploadId/abort\",\n outputSchema: z.object({ ok: z.literal(true) }),\n errorCodes,\n handler: async function ({ pathParams }, { json, error }) {\n const resolvedConfig = getResolvedConfig();\n try {\n const upload = await this.handlerTx()\n .withServiceCalls(() => [services.getUploadStorageInfo(pathParams.uploadId)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n if (\n upload.strategy === \"direct-multipart\" &&\n resolvedConfig.storage.abortMultipartUpload\n ) {\n await resolvedConfig.storage.abortMultipartUpload({\n storageKey: upload.storageKey,\n storageUploadId: upload.storageUploadId ?? \"\",\n });\n }\n\n await this.handlerTx()\n .withServiceCalls(() => [services.markUploadAborted(upload.id.toString())])\n .execute();\n\n return json({ ok: true });\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n\n defineRoute({\n method: \"PUT\",\n path: \"/uploads/:uploadId/content\",\n contentType: \"application/octet-stream\",\n outputSchema: fileMetadataSchema,\n errorCodes,\n handler: async function (context, { json, error }) {\n const { pathParams } = context;\n const resolvedConfig = getResolvedConfig();\n try {\n const upload = await this.handlerTx()\n .withServiceCalls(() => [services.getUploadStorageInfo(pathParams.uploadId)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n if (upload.strategy !== \"proxy\") {\n return error({ message: \"Upload invalid state\", code: \"UPLOAD_INVALID_STATE\" }, 409);\n }\n\n const existingFile = await this.handlerTx()\n .withServiceCalls(() => [services.findFileByKey(upload.fileKey)])\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n if (existingFile) {\n return error({ message: \"File already exists\", code: \"FILE_ALREADY_EXISTS\" }, 409);\n }\n\n if (!resolvedConfig.storage.writeStream) {\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n\n let result: Awaited<ReturnType<NonNullable<typeof resolvedConfig.storage.writeStream>>>;\n try {\n result = await resolvedConfig.storage.writeStream({\n storageKey: upload.storageKey,\n body: context.bodyStream(),\n contentType: upload.contentType,\n sizeBytes: upload.expectedSizeBytes,\n });\n } catch {\n await this.handlerTx()\n .withServiceCalls(() => [\n services.markUploadFailed(\n upload.id.toString(),\n \"STORAGE_ERROR\",\n \"Storage upload failed\",\n ),\n ])\n .execute();\n return error({ message: \"Storage error\", code: \"STORAGE_ERROR\" }, 502);\n }\n\n const completed = await this.handlerTx()\n .withServiceCalls(() => [\n services.markUploadComplete(\n upload.id.toString(),\n upload.fileKey,\n result?.sizeBytes ? { sizeBytes: result.sizeBytes } : undefined,\n ),\n ])\n .transform(({ serviceResult: [done] }) => done)\n .execute();\n\n return json(toFileMetadata(completed.file));\n } catch (err) {\n return handleServiceError(err, error);\n }\n },\n }),\n ];\n },\n);\n"],"mappings":"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"}
|