@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
package/LICENSE.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Copyright 2025 - present "ReJot Nederland B.V.", and individual contributors.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
4
|
+
associated documentation files (the “Software”), to deal in the Software without restriction,
|
|
5
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
6
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|
7
|
+
furnished to do so, subject to the following conditions:
|
|
8
|
+
|
|
9
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
10
|
+
portions of the Software.
|
|
11
|
+
|
|
12
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
13
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
14
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
|
15
|
+
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
16
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Fragno Fragment
|
|
2
|
+
|
|
3
|
+
You've created a new [Fragno](https://fragno.dev/) fragment!
|
|
4
|
+
|
|
5
|
+
## Build
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run types:check
|
|
9
|
+
npm run build
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## CLI
|
|
13
|
+
|
|
14
|
+
The upload fragment ships with a CLI to interact with its HTTP API.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# From the workspace
|
|
18
|
+
pnpm -C packages/fragment-upload build
|
|
19
|
+
node packages/fragment-upload/bin/run.js --help
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Use the CLI (base URL points to the mounted upload fragment)
|
|
24
|
+
fragno-upload --help
|
|
25
|
+
fragno-upload uploads create -b https://host.example.com/api/uploads --file-key s~Zm9v --filename demo.txt --size-bytes 10 --content-type text/plain
|
|
26
|
+
fragno-upload uploads transfer -b https://host.example.com/api/uploads -f ./demo.txt --file-key s~Zm9v
|
|
27
|
+
fragno-upload files list -b https://host.example.com/api/uploads --prefix s~Zm9v.
|
|
28
|
+
fragno-upload files download -b https://host.example.com/api/uploads --file-key s~Zm9v -o ./download.txt
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Environment defaults:
|
|
32
|
+
|
|
33
|
+
- `FRAGNO_UPLOAD_BASE_URL`
|
|
34
|
+
- `FRAGNO_UPLOAD_HEADERS`
|
|
35
|
+
- `FRAGNO_UPLOAD_TIMEOUT_MS`
|
|
36
|
+
- `FRAGNO_UPLOAD_RETRIES`
|
|
37
|
+
- `FRAGNO_UPLOAD_RETRY_DELAY_MS`
|
|
38
|
+
|
|
39
|
+
## Next Steps
|
|
40
|
+
|
|
41
|
+
- Define your routes in `src/index.ts`
|
|
42
|
+
- Add framework-specific clients in `src/client/`
|
|
43
|
+
- See `AGENTS.md` for detailed development patterns
|
package/bin/run.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { createClientBuilder } from "./packages/fragno/dist/client/client.js";
|
|
2
|
+
import { uploadFragmentDefinition } from "./packages/fragment-upload/src/definition.js";
|
|
3
|
+
import { uploadRoutes } from "./packages/fragment-upload/src/routes/index.js";
|
|
4
|
+
import { createUploadHelpers } from "./helpers.js";
|
|
5
|
+
|
|
6
|
+
//#region src/client/clients.ts
|
|
7
|
+
function createUploadFragmentClients(config = {}) {
|
|
8
|
+
const builder = createClientBuilder(uploadFragmentDefinition, config, uploadRoutes);
|
|
9
|
+
const { fetcher, defaultOptions } = builder.getFetcher();
|
|
10
|
+
const helpers = createUploadHelpers({
|
|
11
|
+
buildUrl: (path) => builder.buildUrl(path),
|
|
12
|
+
fetcher,
|
|
13
|
+
defaultOptions
|
|
14
|
+
});
|
|
15
|
+
return {
|
|
16
|
+
useFiles: builder.createHook("/files"),
|
|
17
|
+
useFile: builder.createHook("/files/:fileKey"),
|
|
18
|
+
useCreateUpload: builder.createMutator("POST", "/uploads"),
|
|
19
|
+
useUploadStatus: builder.createHook("/uploads/:uploadId"),
|
|
20
|
+
useCompleteUpload: builder.createMutator("POST", "/uploads/:uploadId/complete", (invalidate, params) => {
|
|
21
|
+
const uploadId = params.pathParams.uploadId;
|
|
22
|
+
if (!uploadId) return;
|
|
23
|
+
invalidate("GET", "/uploads/:uploadId", { pathParams: { uploadId } });
|
|
24
|
+
invalidate("GET", "/files", {});
|
|
25
|
+
}),
|
|
26
|
+
useAbortUpload: builder.createMutator("POST", "/uploads/:uploadId/abort", (invalidate, params) => {
|
|
27
|
+
const uploadId = params.pathParams.uploadId;
|
|
28
|
+
if (!uploadId) return;
|
|
29
|
+
invalidate("GET", "/uploads/:uploadId", { pathParams: { uploadId } });
|
|
30
|
+
}),
|
|
31
|
+
useUpdateFile: builder.createMutator("PATCH", "/files/:fileKey", (invalidate, params) => {
|
|
32
|
+
const fileKey = params.pathParams.fileKey;
|
|
33
|
+
if (!fileKey) return;
|
|
34
|
+
invalidate("GET", "/files/:fileKey", { pathParams: { fileKey } });
|
|
35
|
+
invalidate("GET", "/files", {});
|
|
36
|
+
}),
|
|
37
|
+
useDeleteFile: builder.createMutator("DELETE", "/files/:fileKey", (invalidate, params) => {
|
|
38
|
+
const fileKey = params.pathParams.fileKey;
|
|
39
|
+
if (!fileKey) return;
|
|
40
|
+
invalidate("GET", "/files/:fileKey", { pathParams: { fileKey } });
|
|
41
|
+
invalidate("GET", "/files", {});
|
|
42
|
+
}),
|
|
43
|
+
useUploadHelpers: builder.createStore(helpers)
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
export { createUploadFragmentClients };
|
|
49
|
+
//# sourceMappingURL=clients.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clients.js","names":["createClientBuilder","FragnoPublicClientConfig","uploadFragmentDefinition","uploadRoutes","createUploadHelpers","createUploadFragmentClients","config","builder","fetcher","defaultOptions","getFetcher","helpers","buildUrl","path","useFiles","createHook","useFile","useCreateUpload","createMutator","useUploadStatus","useCompleteUpload","invalidate","params","uploadId","pathParams","useAbortUpload","useUpdateFile","fileKey","useDeleteFile","useUploadHelpers","createStore"],"sources":["../../../src/client/clients.ts"],"sourcesContent":["import { createClientBuilder } from \"@fragno-dev/core/client\";\nimport type { FragnoPublicClientConfig } from \"@fragno-dev/core/client\";\nimport { uploadFragmentDefinition } from \"../definition\";\nimport { uploadRoutes } from \"../routes\";\nimport { createUploadHelpers } from \"./helpers\";\n\nexport function createUploadFragmentClients(config: FragnoPublicClientConfig = {}) {\n const builder = createClientBuilder(uploadFragmentDefinition, config, uploadRoutes);\n const { fetcher, defaultOptions } = builder.getFetcher();\n const helpers = createUploadHelpers({\n buildUrl: (path) => builder.buildUrl(path),\n fetcher,\n defaultOptions,\n });\n\n return {\n useFiles: builder.createHook(\"/files\"),\n useFile: builder.createHook(\"/files/:fileKey\"),\n useCreateUpload: builder.createMutator(\"POST\", \"/uploads\"),\n useUploadStatus: builder.createHook(\"/uploads/:uploadId\"),\n useCompleteUpload: builder.createMutator(\n \"POST\",\n \"/uploads/:uploadId/complete\",\n (invalidate, params) => {\n const uploadId = params.pathParams.uploadId;\n if (!uploadId) {\n return;\n }\n invalidate(\"GET\", \"/uploads/:uploadId\", { pathParams: { uploadId } });\n invalidate(\"GET\", \"/files\", {});\n },\n ),\n useAbortUpload: builder.createMutator(\n \"POST\",\n \"/uploads/:uploadId/abort\",\n (invalidate, params) => {\n const uploadId = params.pathParams.uploadId;\n if (!uploadId) {\n return;\n }\n invalidate(\"GET\", \"/uploads/:uploadId\", { pathParams: { uploadId } });\n },\n ),\n useUpdateFile: builder.createMutator(\"PATCH\", \"/files/:fileKey\", (invalidate, params) => {\n const fileKey = params.pathParams.fileKey;\n if (!fileKey) {\n return;\n }\n invalidate(\"GET\", \"/files/:fileKey\", { pathParams: { fileKey } });\n invalidate(\"GET\", \"/files\", {});\n }),\n useDeleteFile: builder.createMutator(\"DELETE\", \"/files/:fileKey\", (invalidate, params) => {\n const fileKey = params.pathParams.fileKey;\n if (!fileKey) {\n return;\n }\n invalidate(\"GET\", \"/files/:fileKey\", { pathParams: { fileKey } });\n invalidate(\"GET\", \"/files\", {});\n }),\n useUploadHelpers: builder.createStore(helpers),\n };\n}\n"],"mappings":";;;;;;AAMA,SAAgBK,4BAA4BC,SAAmC,EAAE,EAAE;CACjF,MAAMC,UAAUP,oBAAoBE,0BAA0BI,QAAQH,aAAa;CACnF,MAAM,EAAEK,SAASC,mBAAmBF,QAAQG,YAAY;CACxD,MAAMC,UAAUP,oBAAoB;EAClCQ,WAAWC,SAASN,QAAQK,SAASC,KAAK;EAC1CL;EACAC;EACD,CAAC;AAEF,QAAO;EACLK,UAAUP,QAAQQ,WAAW,SAAS;EACtCC,SAAST,QAAQQ,WAAW,kBAAkB;EAC9CE,iBAAiBV,QAAQW,cAAc,QAAQ,WAAW;EAC1DC,iBAAiBZ,QAAQQ,WAAW,qBAAqB;EACzDK,mBAAmBb,QAAQW,cACzB,QACA,gCACCG,YAAYC,WAAW;GACtB,MAAMC,WAAWD,OAAOE,WAAWD;AACnC,OAAI,CAACA,SACH;AAEFF,cAAW,OAAO,sBAAsB,EAAEG,YAAY,EAAED,UAAS,EAAG,CAAC;AACrEF,cAAW,OAAO,UAAU,EAAE,CAAC;IAElC;EACDI,gBAAgBlB,QAAQW,cACtB,QACA,6BACCG,YAAYC,WAAW;GACtB,MAAMC,WAAWD,OAAOE,WAAWD;AACnC,OAAI,CAACA,SACH;AAEFF,cAAW,OAAO,sBAAsB,EAAEG,YAAY,EAAED,UAAS,EAAG,CAAC;IAExE;EACDG,eAAenB,QAAQW,cAAc,SAAS,oBAAoBG,YAAYC,WAAW;GACvF,MAAMK,UAAUL,OAAOE,WAAWG;AAClC,OAAI,CAACA,QACH;AAEFN,cAAW,OAAO,mBAAmB,EAAEG,YAAY,EAAEG,SAAQ,EAAG,CAAC;AACjEN,cAAW,OAAO,UAAU,EAAE,CAAC;IAC/B;EACFO,eAAerB,QAAQW,cAAc,UAAU,oBAAoBG,YAAYC,WAAW;GACxF,MAAMK,UAAUL,OAAOE,WAAWG;AAClC,OAAI,CAACA,QACH;AAEFN,cAAW,OAAO,mBAAmB,EAAEG,YAAY,EAAEG,SAAQ,EAAG,CAAC;AACjEN,cAAW,OAAO,UAAU,EAAE,CAAC;IAC/B;EACFQ,kBAAkBtB,QAAQuB,YAAYnB,QAAO;EAC9C"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { FileKeyEncoded, FileKeyParts } from "./packages/fragment-upload/src/keys.js";
|
|
2
|
+
import { UploadChecksum } from "./packages/fragment-upload/src/storage/types.js";
|
|
3
|
+
import { FileMetadata, FileVisibility, UploadStrategy } from "./packages/fragment-upload/src/types.js";
|
|
4
|
+
|
|
5
|
+
//#region src/client/helpers.d.ts
|
|
6
|
+
type UploadProgress = {
|
|
7
|
+
bytesUploaded: number;
|
|
8
|
+
totalBytes: number;
|
|
9
|
+
partsUploaded: number;
|
|
10
|
+
totalParts?: number;
|
|
11
|
+
};
|
|
12
|
+
type CreateUploadAndTransferOptions = {
|
|
13
|
+
keyParts?: FileKeyParts;
|
|
14
|
+
fileKey?: FileKeyEncoded;
|
|
15
|
+
filename?: string;
|
|
16
|
+
contentType?: string;
|
|
17
|
+
checksum?: UploadChecksum | null;
|
|
18
|
+
tags?: string[];
|
|
19
|
+
visibility?: FileVisibility;
|
|
20
|
+
uploaderId?: string;
|
|
21
|
+
metadata?: Record<string, unknown>;
|
|
22
|
+
onProgress?: (progress: UploadProgress) => void;
|
|
23
|
+
};
|
|
24
|
+
type UploadCreateResponse = {
|
|
25
|
+
uploadId: string;
|
|
26
|
+
fileKey: string;
|
|
27
|
+
status: "created";
|
|
28
|
+
strategy: UploadStrategy;
|
|
29
|
+
expiresAt: string;
|
|
30
|
+
upload: {
|
|
31
|
+
mode: "single" | "multipart";
|
|
32
|
+
transport: "direct" | "proxy";
|
|
33
|
+
uploadUrl?: string;
|
|
34
|
+
uploadHeaders?: Record<string, string>;
|
|
35
|
+
partSizeBytes?: number;
|
|
36
|
+
maxParts?: number;
|
|
37
|
+
partsEndpoint?: string;
|
|
38
|
+
completeEndpoint: string;
|
|
39
|
+
contentEndpoint?: string;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
type UploadHelpers = {
|
|
43
|
+
createUploadAndTransfer: (file: Blob, options: CreateUploadAndTransferOptions) => Promise<{
|
|
44
|
+
upload: UploadCreateResponse;
|
|
45
|
+
file: FileMetadata;
|
|
46
|
+
}>;
|
|
47
|
+
downloadFile: (fileKeyOrParts: FileKeyEncoded | FileKeyParts) => Promise<Response>;
|
|
48
|
+
};
|
|
49
|
+
//#endregion
|
|
50
|
+
export { CreateUploadAndTransferOptions, UploadCreateResponse, UploadHelpers };
|
|
51
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","names":[],"sources":["../../../src/client/helpers.ts"],"sourcesContent":[],"mappings":";;;;;KAIY,cAAA;;EAAA,UAAA,EAAA,MAAc;EAOd,aAAA,EAAA,MAAA;EAA8B,UAAA,CAAA,EAAA,MAAA;;AAE9B,KAFA,8BAAA,GAEA;UAGC,CAAA,EAJA,YAIA;SAEE,CAAA,EALH,cAKG;UAEF,CAAA,EAAA,MAAA;aACa,CAAA,EAAA,MAAA;EAAc,QAAA,CAAA,EAL3B,cAK2B,GAAA,IAAA;EAG5B,IAAA,CAAA,EAAA,MAAA,EAAA;EAAoB,UAAA,CAAA,EANjB,cAMiB;YAIpB,CAAA,EAAA,MAAA;UAMQ,CAAA,EAdP,MAcO,CAAA,MAAA,EAAA,OAAA,CAAA;EAAM,UAAA,CAAA,EAAA,CAAA,QAAA,EAbA,cAaA,EAAA,GAAA,IAAA;AAS1B,CAAA;AAAyB,KAnBb,oBAAA,GAmBa;UAEf,EAAA,MAAA;SACG,EAAA,MAAA;QACY,EAAA,SAAA;UAA4B,EAnBzC,cAmByC;WAA9C,EAAA,MAAA;QAC0B,EAAA;IAAiB,IAAA,EAAA,QAAA,GAAA,WAAA;IAAyB,SAAA,EAAA,QAAA,GAAA,OAAA;IAAR,SAAA,CAAA,EAAA,MAAA;IAAO,aAAA,CAAA,EAdtD,MAcsD,CAAA,MAAA,EAAA,MAAA,CAAA;;;;;;;;KAL9D,aAAA;kCAEF,eACG,mCACN;YAAkB;UAA4B;;iCACpB,iBAAiB,iBAAiB,QAAQ"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { encodeFileKey } from "./packages/fragment-upload/src/keys.js";
|
|
2
|
+
|
|
3
|
+
//#region src/client/helpers.ts
|
|
4
|
+
const DEFAULT_CONTENT_TYPE = "application/octet-stream";
|
|
5
|
+
const mergeHeaders = (base, next) => {
|
|
6
|
+
const merged = new Headers(base ?? void 0);
|
|
7
|
+
if (!next) return merged;
|
|
8
|
+
if (next instanceof Headers) for (const [key, value] of next.entries()) merged.set(key, value);
|
|
9
|
+
else if (Array.isArray(next)) for (const [key, value] of next) merged.set(key, value);
|
|
10
|
+
else for (const [key, value] of Object.entries(next)) merged.set(key, value);
|
|
11
|
+
return merged;
|
|
12
|
+
};
|
|
13
|
+
const buildRequestInit = (defaults, init) => {
|
|
14
|
+
if (!defaults) return init;
|
|
15
|
+
return {
|
|
16
|
+
...defaults,
|
|
17
|
+
...init,
|
|
18
|
+
headers: mergeHeaders(defaults.headers, init.headers)
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
const readJsonSafely = async (response) => {
|
|
22
|
+
try {
|
|
23
|
+
return await response.json();
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const createUploadHelpers = (input) => {
|
|
29
|
+
const { buildUrl, fetcher, defaultOptions } = input;
|
|
30
|
+
const fetchJson = async (path, init, expectedErrorCode) => {
|
|
31
|
+
const response = await fetcher(buildUrl(path), buildRequestInit(defaultOptions, init));
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
const payload = await readJsonSafely(response);
|
|
34
|
+
const code = typeof payload === "object" && payload ? payload.code : void 0;
|
|
35
|
+
if (expectedErrorCode && code === expectedErrorCode) throw new Error(expectedErrorCode);
|
|
36
|
+
const message = typeof payload === "object" && payload && "message" in payload ? String(payload.message) : `Request failed (${response.status})`;
|
|
37
|
+
throw new Error(message);
|
|
38
|
+
}
|
|
39
|
+
return await response.json();
|
|
40
|
+
};
|
|
41
|
+
const reportProgress = async (uploadId, progress, onProgress) => {
|
|
42
|
+
onProgress?.(progress);
|
|
43
|
+
await fetchJson(`/uploads/${uploadId}/progress`, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: { "Content-Type": "application/json" },
|
|
46
|
+
body: JSON.stringify({
|
|
47
|
+
bytesUploaded: progress.bytesUploaded,
|
|
48
|
+
partsUploaded: progress.partsUploaded
|
|
49
|
+
})
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
const createUploadAndTransfer = async (file, options) => {
|
|
53
|
+
const filename = options.filename ?? (typeof File !== "undefined" && file instanceof File && file.name ? file.name : "upload");
|
|
54
|
+
const contentType = options.contentType ?? (file.type && file.type.length > 0 ? file.type : void 0) ?? DEFAULT_CONTENT_TYPE;
|
|
55
|
+
const sizeBytes = file.size;
|
|
56
|
+
if (!options.keyParts && !options.fileKey) throw new Error("File key parts or file key is required");
|
|
57
|
+
const upload = await fetchJson("/uploads", {
|
|
58
|
+
method: "POST",
|
|
59
|
+
headers: { "Content-Type": "application/json" },
|
|
60
|
+
body: JSON.stringify({
|
|
61
|
+
keyParts: options.keyParts,
|
|
62
|
+
fileKey: options.fileKey,
|
|
63
|
+
filename,
|
|
64
|
+
sizeBytes,
|
|
65
|
+
contentType,
|
|
66
|
+
checksum: options.checksum ?? null,
|
|
67
|
+
tags: options.tags,
|
|
68
|
+
visibility: options.visibility,
|
|
69
|
+
uploaderId: options.uploaderId,
|
|
70
|
+
metadata: options.metadata
|
|
71
|
+
})
|
|
72
|
+
});
|
|
73
|
+
const totalBytes = sizeBytes;
|
|
74
|
+
let bytesUploaded = 0;
|
|
75
|
+
let partsUploaded = 0;
|
|
76
|
+
if (upload.strategy === "direct-single") {
|
|
77
|
+
if (!upload.upload.uploadUrl) throw new Error("Missing upload URL for direct upload");
|
|
78
|
+
const uploadResponse = await fetcher(upload.upload.uploadUrl, {
|
|
79
|
+
method: "PUT",
|
|
80
|
+
headers: upload.upload.uploadHeaders,
|
|
81
|
+
body: file
|
|
82
|
+
});
|
|
83
|
+
if (!uploadResponse.ok) throw new Error(`Direct upload failed (${uploadResponse.status})`);
|
|
84
|
+
bytesUploaded = totalBytes;
|
|
85
|
+
partsUploaded = 1;
|
|
86
|
+
await reportProgress(upload.uploadId, {
|
|
87
|
+
bytesUploaded,
|
|
88
|
+
totalBytes,
|
|
89
|
+
partsUploaded,
|
|
90
|
+
totalParts: 1
|
|
91
|
+
}, options.onProgress);
|
|
92
|
+
return {
|
|
93
|
+
upload,
|
|
94
|
+
file: await fetchJson(upload.upload.completeEndpoint, {
|
|
95
|
+
method: "POST",
|
|
96
|
+
headers: { "Content-Type": "application/json" },
|
|
97
|
+
body: JSON.stringify({})
|
|
98
|
+
})
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
if (upload.strategy === "direct-multipart") {
|
|
102
|
+
const partSizeBytes = upload.upload.partSizeBytes;
|
|
103
|
+
if (!partSizeBytes || !upload.upload.partsEndpoint) throw new Error("Missing multipart configuration for upload");
|
|
104
|
+
const totalParts = Math.ceil(totalBytes / partSizeBytes);
|
|
105
|
+
if (upload.upload.maxParts && totalParts > upload.upload.maxParts) throw new Error("Multipart upload exceeds maximum parts");
|
|
106
|
+
const partNumbers = Array.from({ length: totalParts }, (_, i) => i + 1);
|
|
107
|
+
const parts = (await fetchJson(upload.upload.partsEndpoint, {
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: { "Content-Type": "application/json" },
|
|
110
|
+
body: JSON.stringify({ partNumbers })
|
|
111
|
+
})).parts.sort((a, b) => a.partNumber - b.partNumber);
|
|
112
|
+
const completedParts = [];
|
|
113
|
+
const completionParts = [];
|
|
114
|
+
for (const part of parts) {
|
|
115
|
+
const start = (part.partNumber - 1) * partSizeBytes;
|
|
116
|
+
const end = Math.min(start + partSizeBytes, totalBytes);
|
|
117
|
+
const partBlob = file.slice(start, end);
|
|
118
|
+
const response = await fetcher(part.url, {
|
|
119
|
+
method: "PUT",
|
|
120
|
+
headers: part.headers,
|
|
121
|
+
body: partBlob
|
|
122
|
+
});
|
|
123
|
+
if (!response.ok) throw new Error(`Multipart upload failed (${response.status})`);
|
|
124
|
+
const etag = response.headers.get("ETag") ?? response.headers.get("etag");
|
|
125
|
+
if (!etag) throw new Error("Missing ETag for uploaded part");
|
|
126
|
+
const partSize = partBlob.size;
|
|
127
|
+
completedParts.push({
|
|
128
|
+
partNumber: part.partNumber,
|
|
129
|
+
etag,
|
|
130
|
+
sizeBytes: partSize
|
|
131
|
+
});
|
|
132
|
+
completionParts.push({
|
|
133
|
+
partNumber: part.partNumber,
|
|
134
|
+
etag
|
|
135
|
+
});
|
|
136
|
+
bytesUploaded += partSize;
|
|
137
|
+
partsUploaded += 1;
|
|
138
|
+
await reportProgress(upload.uploadId, {
|
|
139
|
+
bytesUploaded,
|
|
140
|
+
totalBytes,
|
|
141
|
+
partsUploaded,
|
|
142
|
+
totalParts
|
|
143
|
+
}, options.onProgress);
|
|
144
|
+
}
|
|
145
|
+
await fetchJson(`/uploads/${upload.uploadId}/parts/complete`, {
|
|
146
|
+
method: "POST",
|
|
147
|
+
headers: { "Content-Type": "application/json" },
|
|
148
|
+
body: JSON.stringify({ parts: completedParts })
|
|
149
|
+
});
|
|
150
|
+
return {
|
|
151
|
+
upload,
|
|
152
|
+
file: await fetchJson(upload.upload.completeEndpoint, {
|
|
153
|
+
method: "POST",
|
|
154
|
+
headers: { "Content-Type": "application/json" },
|
|
155
|
+
body: JSON.stringify({ parts: completionParts })
|
|
156
|
+
})
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (!upload.upload.contentEndpoint) throw new Error("Missing proxy content endpoint for upload");
|
|
160
|
+
const source = file.stream();
|
|
161
|
+
const stream = new ReadableStream({ start(controller) {
|
|
162
|
+
const reader = source.getReader();
|
|
163
|
+
const pump = () => {
|
|
164
|
+
reader.read().then(({ done, value }) => {
|
|
165
|
+
if (done) {
|
|
166
|
+
controller.close();
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (value) {
|
|
170
|
+
bytesUploaded += value.byteLength;
|
|
171
|
+
options.onProgress?.({
|
|
172
|
+
bytesUploaded,
|
|
173
|
+
totalBytes,
|
|
174
|
+
partsUploaded: 0
|
|
175
|
+
});
|
|
176
|
+
controller.enqueue(value);
|
|
177
|
+
}
|
|
178
|
+
pump();
|
|
179
|
+
}, (error) => {
|
|
180
|
+
controller.error(error);
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
pump();
|
|
184
|
+
} });
|
|
185
|
+
const requestInit = buildRequestInit(defaultOptions, {
|
|
186
|
+
method: "PUT",
|
|
187
|
+
headers: { "Content-Type": DEFAULT_CONTENT_TYPE },
|
|
188
|
+
body: stream
|
|
189
|
+
});
|
|
190
|
+
requestInit.duplex = "half";
|
|
191
|
+
let proxyResponse;
|
|
192
|
+
try {
|
|
193
|
+
proxyResponse = await fetcher(buildUrl(upload.upload.contentEndpoint), requestInit);
|
|
194
|
+
} catch (_error) {
|
|
195
|
+
const fallbackResponse = await fetcher(buildUrl(upload.upload.contentEndpoint), buildRequestInit(defaultOptions, {
|
|
196
|
+
method: "PUT",
|
|
197
|
+
headers: { "Content-Type": DEFAULT_CONTENT_TYPE },
|
|
198
|
+
body: file
|
|
199
|
+
}));
|
|
200
|
+
if (!fallbackResponse.ok) throw new Error(`Proxy upload failed (${fallbackResponse.status})`);
|
|
201
|
+
options.onProgress?.({
|
|
202
|
+
bytesUploaded: totalBytes,
|
|
203
|
+
totalBytes,
|
|
204
|
+
partsUploaded: 0
|
|
205
|
+
});
|
|
206
|
+
return {
|
|
207
|
+
upload,
|
|
208
|
+
file: await fallbackResponse.json()
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
if (!proxyResponse.ok) throw new Error(`Proxy upload failed (${proxyResponse.status})`);
|
|
212
|
+
return {
|
|
213
|
+
upload,
|
|
214
|
+
file: await proxyResponse.json()
|
|
215
|
+
};
|
|
216
|
+
};
|
|
217
|
+
const downloadFile = async (fileKeyOrParts) => {
|
|
218
|
+
const fileKey = Array.isArray(fileKeyOrParts) ? encodeFileKey(fileKeyOrParts) : fileKeyOrParts;
|
|
219
|
+
const downloadUrlResponse = await fetcher(buildUrl(`/files/${fileKey}/download-url`), buildRequestInit(defaultOptions, { method: "GET" }));
|
|
220
|
+
if (downloadUrlResponse.ok) {
|
|
221
|
+
const payload = await downloadUrlResponse.json();
|
|
222
|
+
return fetcher(payload.url, {
|
|
223
|
+
method: "GET",
|
|
224
|
+
headers: payload.headers
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
const errorPayload = await readJsonSafely(downloadUrlResponse);
|
|
228
|
+
if ((typeof errorPayload === "object" && errorPayload ? errorPayload.code : void 0) !== "SIGNED_URL_UNSUPPORTED") {
|
|
229
|
+
const message = typeof errorPayload === "object" && errorPayload && "message" in errorPayload ? String(errorPayload.message) : `Download failed (${downloadUrlResponse.status})`;
|
|
230
|
+
throw new Error(message);
|
|
231
|
+
}
|
|
232
|
+
return fetcher(buildUrl(`/files/${fileKey}/content`), buildRequestInit(defaultOptions, { method: "GET" }));
|
|
233
|
+
};
|
|
234
|
+
return {
|
|
235
|
+
createUploadAndTransfer,
|
|
236
|
+
downloadFile
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
//#endregion
|
|
241
|
+
export { createUploadHelpers };
|
|
242
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","names":["encodeFileKey","FileKeyEncoded","FileKeyParts","UploadChecksum","FileMetadata","FileVisibility","UploadStrategy","UploadProgress","bytesUploaded","totalBytes","partsUploaded","totalParts","CreateUploadAndTransferOptions","keyParts","fileKey","filename","contentType","checksum","tags","visibility","uploaderId","metadata","Record","onProgress","progress","UploadCreateResponse","uploadId","status","strategy","expiresAt","upload","mode","transport","uploadUrl","uploadHeaders","partSizeBytes","maxParts","partsEndpoint","completeEndpoint","contentEndpoint","UploadHelpers","createUploadAndTransfer","file","Blob","options","Promise","downloadFile","fileKeyOrParts","Response","DEFAULT_CONTENT_TYPE","mergeHeaders","base","HeadersInit","next","merged","Headers","undefined","key","value","entries","set","Array","isArray","Object","buildRequestInit","defaults","RequestInit","init","headers","readJsonSafely","response","json","createUploadHelpers","input","buildUrl","path","fetcher","fetch","defaultOptions","fetchJson","expectedErrorCode","T","ok","payload","code","Error","message","String","reportProgress","method","body","JSON","stringify","File","name","type","length","sizeBytes","size","uploadResponse","fileMetadata","Math","ceil","partNumbers","from","_","i","partUrls","parts","partNumber","url","sort","a","b","completedParts","etag","completionParts","part","start","end","min","partBlob","slice","get","partSize","push","source","stream","ReadableStream","Uint8Array","controller","reader","getReader","pump","read","then","done","close","byteLength","enqueue","error","requestInit","duplex","proxyResponse","_error","fallbackResponse","fallbackMetadata","proxyMetadata","downloadUrlResponse","errorPayload","errorCode"],"sources":["../../../src/client/helpers.ts"],"sourcesContent":["import { encodeFileKey, type FileKeyEncoded, type FileKeyParts } from \"../keys\";\nimport type { UploadChecksum } from \"../storage/types\";\nimport type { FileMetadata, FileVisibility, UploadStrategy } from \"../types\";\n\nexport type UploadProgress = {\n bytesUploaded: number;\n totalBytes: number;\n partsUploaded: number;\n totalParts?: number;\n};\n\nexport type CreateUploadAndTransferOptions = {\n keyParts?: FileKeyParts;\n fileKey?: FileKeyEncoded;\n filename?: string;\n contentType?: string;\n checksum?: UploadChecksum | null;\n tags?: string[];\n visibility?: FileVisibility;\n uploaderId?: string;\n metadata?: Record<string, unknown>;\n onProgress?: (progress: UploadProgress) => void;\n};\n\nexport type UploadCreateResponse = {\n uploadId: string;\n fileKey: string;\n status: \"created\";\n strategy: UploadStrategy;\n expiresAt: string;\n upload: {\n mode: \"single\" | \"multipart\";\n transport: \"direct\" | \"proxy\";\n uploadUrl?: string;\n uploadHeaders?: Record<string, string>;\n partSizeBytes?: number;\n maxParts?: number;\n partsEndpoint?: string;\n completeEndpoint: string;\n contentEndpoint?: string;\n };\n};\n\nexport type UploadHelpers = {\n createUploadAndTransfer: (\n file: Blob,\n options: CreateUploadAndTransferOptions,\n ) => Promise<{ upload: UploadCreateResponse; file: FileMetadata }>;\n downloadFile: (fileKeyOrParts: FileKeyEncoded | FileKeyParts) => Promise<Response>;\n};\n\nconst DEFAULT_CONTENT_TYPE = \"application/octet-stream\";\n\nconst mergeHeaders = (base?: HeadersInit, next?: HeadersInit) => {\n const merged = new Headers(base ?? undefined);\n\n if (!next) {\n return merged;\n }\n\n if (next instanceof Headers) {\n for (const [key, value] of next.entries()) {\n merged.set(key, value);\n }\n } else if (Array.isArray(next)) {\n for (const [key, value] of next) {\n merged.set(key, value);\n }\n } else {\n for (const [key, value] of Object.entries(next)) {\n merged.set(key, value);\n }\n }\n\n return merged;\n};\n\nconst buildRequestInit = (defaults: RequestInit | undefined, init: RequestInit): RequestInit => {\n if (!defaults) {\n return init;\n }\n\n return {\n ...defaults,\n ...init,\n headers: mergeHeaders(defaults.headers, init.headers),\n };\n};\n\nconst readJsonSafely = async (response: Response) => {\n try {\n return (await response.json()) as unknown;\n } catch {\n return null;\n }\n};\n\nexport const createUploadHelpers = (input: {\n buildUrl: (path: string) => string;\n fetcher: typeof fetch;\n defaultOptions?: RequestInit;\n}): UploadHelpers => {\n const { buildUrl, fetcher, defaultOptions } = input;\n\n const fetchJson = async <T>(\n path: string,\n init: RequestInit,\n expectedErrorCode?: string,\n ): Promise<T> => {\n const response = await fetcher(buildUrl(path), buildRequestInit(defaultOptions, init));\n\n if (!response.ok) {\n const payload = await readJsonSafely(response);\n const code =\n typeof payload === \"object\" && payload ? (payload as { code?: string }).code : undefined;\n if (expectedErrorCode && code === expectedErrorCode) {\n throw new Error(expectedErrorCode);\n }\n const message =\n typeof payload === \"object\" && payload && \"message\" in payload\n ? String((payload as { message?: string }).message)\n : `Request failed (${response.status})`;\n throw new Error(message);\n }\n\n return (await response.json()) as T;\n };\n\n const reportProgress = async (\n uploadId: string,\n progress: UploadProgress,\n onProgress?: (progress: UploadProgress) => void,\n ) => {\n onProgress?.(progress);\n await fetchJson<{ bytesUploaded: number; partsUploaded: number }>(\n `/uploads/${uploadId}/progress`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n bytesUploaded: progress.bytesUploaded,\n partsUploaded: progress.partsUploaded,\n }),\n },\n );\n };\n\n const createUploadAndTransfer: UploadHelpers[\"createUploadAndTransfer\"] = async (\n file,\n options,\n ) => {\n const filename =\n options.filename ??\n (typeof File !== \"undefined\" && file instanceof File && file.name ? file.name : \"upload\");\n const contentType =\n options.contentType ??\n (file.type && file.type.length > 0 ? file.type : undefined) ??\n DEFAULT_CONTENT_TYPE;\n const sizeBytes = file.size;\n\n if (!options.keyParts && !options.fileKey) {\n throw new Error(\"File key parts or file key is required\");\n }\n\n const upload = await fetchJson<UploadCreateResponse>(\"/uploads\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n keyParts: options.keyParts,\n fileKey: options.fileKey,\n filename,\n sizeBytes,\n contentType,\n checksum: options.checksum ?? null,\n tags: options.tags,\n visibility: options.visibility,\n uploaderId: options.uploaderId,\n metadata: options.metadata,\n }),\n });\n\n const totalBytes = sizeBytes;\n let bytesUploaded = 0;\n let partsUploaded = 0;\n\n if (upload.strategy === \"direct-single\") {\n if (!upload.upload.uploadUrl) {\n throw new Error(\"Missing upload URL for direct upload\");\n }\n\n const uploadResponse = await fetcher(upload.upload.uploadUrl, {\n method: \"PUT\",\n headers: upload.upload.uploadHeaders,\n body: file,\n });\n\n if (!uploadResponse.ok) {\n throw new Error(`Direct upload failed (${uploadResponse.status})`);\n }\n\n bytesUploaded = totalBytes;\n partsUploaded = 1;\n await reportProgress(\n upload.uploadId,\n {\n bytesUploaded,\n totalBytes,\n partsUploaded,\n totalParts: 1,\n },\n options.onProgress,\n );\n\n const fileMetadata = await fetchJson<FileMetadata>(upload.upload.completeEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({}),\n });\n\n return { upload, file: fileMetadata };\n }\n\n if (upload.strategy === \"direct-multipart\") {\n const partSizeBytes = upload.upload.partSizeBytes;\n if (!partSizeBytes || !upload.upload.partsEndpoint) {\n throw new Error(\"Missing multipart configuration for upload\");\n }\n\n const totalParts = Math.ceil(totalBytes / partSizeBytes);\n if (upload.upload.maxParts && totalParts > upload.upload.maxParts) {\n throw new Error(\"Multipart upload exceeds maximum parts\");\n }\n\n const partNumbers = Array.from({ length: totalParts }, (_, i) => i + 1);\n const partUrls = await fetchJson<{\n parts: { partNumber: number; url: string; headers?: Record<string, string> }[];\n }>(upload.upload.partsEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ partNumbers }),\n });\n\n const parts = partUrls.parts.sort((a, b) => a.partNumber - b.partNumber);\n const completedParts: { partNumber: number; etag: string; sizeBytes: number }[] = [];\n const completionParts: { partNumber: number; etag: string }[] = [];\n\n for (const part of parts) {\n const start = (part.partNumber - 1) * partSizeBytes;\n const end = Math.min(start + partSizeBytes, totalBytes);\n const partBlob = file.slice(start, end);\n\n const response = await fetcher(part.url, {\n method: \"PUT\",\n headers: part.headers,\n body: partBlob,\n });\n\n if (!response.ok) {\n throw new Error(`Multipart upload failed (${response.status})`);\n }\n\n const etag = response.headers.get(\"ETag\") ?? response.headers.get(\"etag\");\n if (!etag) {\n throw new Error(\"Missing ETag for uploaded part\");\n }\n\n const partSize = partBlob.size;\n completedParts.push({ partNumber: part.partNumber, etag, sizeBytes: partSize });\n completionParts.push({ partNumber: part.partNumber, etag });\n\n bytesUploaded += partSize;\n partsUploaded += 1;\n await reportProgress(\n upload.uploadId,\n {\n bytesUploaded,\n totalBytes,\n partsUploaded,\n totalParts,\n },\n options.onProgress,\n );\n }\n\n await fetchJson<{ bytesUploaded: number; partsUploaded: number }>(\n `/uploads/${upload.uploadId}/parts/complete`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ parts: completedParts }),\n },\n );\n\n const fileMetadata = await fetchJson<FileMetadata>(upload.upload.completeEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ parts: completionParts }),\n });\n\n return { upload, file: fileMetadata };\n }\n\n if (!upload.upload.contentEndpoint) {\n throw new Error(\"Missing proxy content endpoint for upload\");\n }\n\n const source = file.stream();\n const stream = new ReadableStream<Uint8Array>({\n start(controller) {\n const reader = source.getReader();\n\n const pump = (): void => {\n reader.read().then(\n ({ done, value }) => {\n if (done) {\n controller.close();\n return;\n }\n\n if (value) {\n bytesUploaded += value.byteLength;\n options.onProgress?.({\n bytesUploaded,\n totalBytes,\n partsUploaded: 0,\n });\n controller.enqueue(value);\n }\n\n pump();\n },\n (error) => {\n controller.error(error);\n },\n );\n };\n\n pump();\n },\n });\n\n const requestInit = buildRequestInit(defaultOptions, {\n method: \"PUT\",\n headers: { \"Content-Type\": DEFAULT_CONTENT_TYPE },\n body: stream,\n }) as RequestInit & { duplex?: \"half\" };\n requestInit.duplex = \"half\";\n\n let proxyResponse: Response;\n try {\n proxyResponse = await fetcher(buildUrl(upload.upload.contentEndpoint), requestInit);\n } catch (_error) {\n const fallbackResponse = await fetcher(\n buildUrl(upload.upload.contentEndpoint),\n buildRequestInit(defaultOptions, {\n method: \"PUT\",\n headers: { \"Content-Type\": DEFAULT_CONTENT_TYPE },\n body: file,\n }),\n );\n\n if (!fallbackResponse.ok) {\n throw new Error(`Proxy upload failed (${fallbackResponse.status})`);\n }\n\n options.onProgress?.({\n bytesUploaded: totalBytes,\n totalBytes,\n partsUploaded: 0,\n });\n\n const fallbackMetadata = (await fallbackResponse.json()) as FileMetadata;\n return { upload, file: fallbackMetadata };\n }\n\n if (!proxyResponse.ok) {\n throw new Error(`Proxy upload failed (${proxyResponse.status})`);\n }\n\n const proxyMetadata = (await proxyResponse.json()) as FileMetadata;\n\n return { upload, file: proxyMetadata };\n };\n\n const downloadFile: UploadHelpers[\"downloadFile\"] = async (fileKeyOrParts) => {\n const fileKey = Array.isArray(fileKeyOrParts) ? encodeFileKey(fileKeyOrParts) : fileKeyOrParts;\n\n const downloadUrlResponse = await fetcher(\n buildUrl(`/files/${fileKey}/download-url`),\n buildRequestInit(defaultOptions, { method: \"GET\" }),\n );\n\n if (downloadUrlResponse.ok) {\n const payload = (await downloadUrlResponse.json()) as {\n url: string;\n headers?: Record<string, string>;\n };\n\n return fetcher(payload.url, {\n method: \"GET\",\n headers: payload.headers,\n });\n }\n\n const errorPayload = await readJsonSafely(downloadUrlResponse);\n const errorCode =\n typeof errorPayload === \"object\" && errorPayload\n ? (errorPayload as { code?: string }).code\n : undefined;\n\n if (errorCode !== \"SIGNED_URL_UNSUPPORTED\") {\n const message =\n typeof errorPayload === \"object\" && errorPayload && \"message\" in errorPayload\n ? String((errorPayload as { message?: string }).message)\n : `Download failed (${downloadUrlResponse.status})`;\n throw new Error(message);\n }\n\n return fetcher(\n buildUrl(`/files/${fileKey}/content`),\n buildRequestInit(defaultOptions, { method: \"GET\" }),\n );\n };\n\n return {\n createUploadAndTransfer,\n downloadFile,\n };\n};\n"],"mappings":"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"}
|