@visulima/storage 1.0.0-alpha.1 → 1.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +33 -14
  3. package/dist/adapter/nuxt/module.d.ts +39 -0
  4. package/dist/adapter/nuxt/module.js +93 -0
  5. package/dist/adapter/nuxt/package.json +20 -0
  6. package/dist/handler/base/base-handler-core.d.ts +91 -0
  7. package/dist/handler/base/base-handler-fetch.d.ts +76 -0
  8. package/dist/handler/base/base-handler-node.d.ts +137 -0
  9. package/dist/handler/http/fetch/index.d.ts +4 -0
  10. package/dist/handler/http/fetch/index.js +4 -0
  11. package/dist/handler/http/hono/index.d.ts +67 -0
  12. package/dist/handler/http/hono/index.js +65 -0
  13. package/dist/handler/http/nextjs/index.d.ts +61 -0
  14. package/dist/handler/http/nextjs/index.js +37 -0
  15. package/dist/handler/http/node/index.d.ts +4 -0
  16. package/dist/handler/http/node/index.js +4 -0
  17. package/dist/handler/http/solid-start/index.d.ts +60 -0
  18. package/dist/handler/http/solid-start/index.js +44 -0
  19. package/dist/handler/multipart/multipart-base.d.ts +84 -0
  20. package/dist/handler/multipart/multipart-fetch.d.ts +64 -0
  21. package/dist/handler/multipart/multipart.d.ts +49 -0
  22. package/dist/handler/rest/rest-base.d.ts +106 -0
  23. package/dist/handler/rest/rest-fetch.d.ts +88 -0
  24. package/dist/handler/rest/rest.d.ts +93 -0
  25. package/dist/handler/tus/tus-base.d.ts +152 -0
  26. package/dist/handler/tus/tus-fetch.d.ts +72 -0
  27. package/dist/handler/tus/tus.d.ts +78 -0
  28. package/dist/handler/types.d.ts +53 -0
  29. package/dist/handler/utils/request-parser.d.ts +72 -0
  30. package/dist/handler/utils/response-builder.d.ts +83 -0
  31. package/dist/handler/utils/storage-utils.d.ts +10 -0
  32. package/dist/handler/utils/stream-utils.d.ts +29 -0
  33. package/dist/handler/utils/upload-handlers.d.ts +76 -0
  34. package/dist/index.d.ts +17 -0
  35. package/dist/index.js +13 -0
  36. package/dist/metrics/index.d.ts +2 -0
  37. package/dist/metrics/no-op-metrics.d.ts +15 -0
  38. package/dist/metrics/opentelemetry-metrics.d.ts +55 -0
  39. package/dist/openapi/index.d.ts +5 -0
  40. package/dist/openapi/index.js +5 -0
  41. package/dist/openapi/rest.d.ts +7 -0
  42. package/dist/openapi/shared.d.ts +13 -0
  43. package/dist/openapi/transform.d.ts +3 -0
  44. package/dist/openapi/tus.d.ts +7 -0
  45. package/dist/openapi/xhr.d.ts +7 -0
  46. package/dist/packem_shared/AwsLightFile-tTneXZgG.js +11 -0
  47. package/dist/packem_shared/AwsLightMetaStorage-BWSOtVaN.js +4 -0
  48. package/dist/packem_shared/AwsLightStorage-Blv-GP4v.js +133 -0
  49. package/dist/packem_shared/AzureFile-CesgFzps.js +8 -0
  50. package/dist/packem_shared/AzureSMetaStorage-CFs-OYJT.js +88 -0
  51. package/dist/packem_shared/AzureStorage-B0v048hG.js +357 -0
  52. package/dist/packem_shared/BaseTransformer-C2gLib6v.js +82 -0
  53. package/dist/packem_shared/DiskStorage-BlltBst6.js +12 -0
  54. package/dist/packem_shared/DiskStorageWithChecksum-BJTmMklc.js +238 -0
  55. package/dist/packem_shared/ERRORS-D0apMqnc.js +97 -0
  56. package/dist/packem_shared/File-Bb3P23dr.js +69 -0
  57. package/dist/packem_shared/GCSConfig-vPP22kN6.js +11 -0
  58. package/dist/packem_shared/GCSFile-BIEunhAN.js +8 -0
  59. package/dist/packem_shared/GCSMetaStorage-BMFEdzJ7.js +7 -0
  60. package/dist/packem_shared/GCStorage-DnhiwaS9.js +406 -0
  61. package/dist/packem_shared/LocalMetaStorage-CZHhKkMd.js +7 -0
  62. package/dist/packem_shared/MediaTransformer-D6658DL1.js +1197 -0
  63. package/dist/packem_shared/MetaStorage-pECeFOad.js +46 -0
  64. package/dist/packem_shared/Metadata-DRLXeJ0F.js +89 -0
  65. package/dist/packem_shared/Multipart-CNFK_Okz.js +163 -0
  66. package/dist/packem_shared/Multipart-CtUL7BQw.js +128 -0
  67. package/dist/packem_shared/NetlifyBlobFile-CXzyjqrD.js +14 -0
  68. package/dist/packem_shared/NetlifyBlobMetaStorage-DxZ5aDvD.js +9 -0
  69. package/dist/packem_shared/NetlifyBlobStorage-CLPtjHqd.js +376 -0
  70. package/dist/packem_shared/NoOpMetrics-DhAk5rXc.js +10 -0
  71. package/dist/packem_shared/OpenTelemetryMetrics-BnxhqIaH.js +67 -0
  72. package/dist/packem_shared/Rest-CAOAEkOj.js +267 -0
  73. package/dist/packem_shared/Rest-DNuLwBrK.js +228 -0
  74. package/dist/packem_shared/S3File-DZiyk9Qt.js +11 -0
  75. package/dist/packem_shared/S3MetaStorage-Dz9aDabA.js +76 -0
  76. package/dist/packem_shared/S3Storage-DHmTk-hU.js +316 -0
  77. package/dist/packem_shared/TUS_RESUMABLE-GJzZ9R-f.js +434 -0
  78. package/dist/packem_shared/Tus-B8PmlMgR.js +200 -0
  79. package/dist/packem_shared/Tus-C4F1aYOl.js +195 -0
  80. package/dist/packem_shared/ValidationError-BfF1aE4h.js +26 -0
  81. package/dist/packem_shared/VercelBlobFile-BCg4aTEq.js +18 -0
  82. package/dist/packem_shared/VercelBlobMetaStorage-Bd9F-VFm.js +9 -0
  83. package/dist/packem_shared/VercelBlobStorage-DD9LMOS6.js +261 -0
  84. package/dist/packem_shared/_commonjsHelpers-B85MJLTf.js +5 -0
  85. package/dist/packem_shared/aws-light-meta-storage-DKJBgbR6.js +446 -0
  86. package/dist/packem_shared/backblaze-BlMnIcBC.js +20 -0
  87. package/dist/packem_shared/base-handler-core-BKuf4YLT.js +303 -0
  88. package/dist/packem_shared/base-handler-fetch-Cr0hLiqg.js +291 -0
  89. package/dist/packem_shared/base-handler-node-gk5aN9Cx.js +730 -0
  90. package/dist/packem_shared/cache-B88MXQ_2.js +18 -0
  91. package/dist/packem_shared/cloudflare-Bi1q8wXE.js +21 -0
  92. package/dist/packem_shared/defaultCloudStorageFileNameValidation-DUuacjWv.js +11 -0
  93. package/dist/packem_shared/digitalOcean-CWQRJM3L.js +21 -0
  94. package/dist/packem_shared/disk-storage-Bh2wy3YW.js +810 -0
  95. package/dist/packem_shared/gcs-meta-storage-0tgMNnPO.js +158 -0
  96. package/dist/packem_shared/has-content-CY66ehMK.js +3 -0
  97. package/dist/packem_shared/headers-DoS5nwM-.js +3220 -0
  98. package/dist/packem_shared/is-expired-CTThU1q5.js +8 -0
  99. package/dist/packem_shared/isRetryableError-Dycp7127.js +82 -0
  100. package/dist/packem_shared/isValidMediaType-BeDgiObq.js +35 -0
  101. package/dist/packem_shared/local-meta-storage-By-3SNBI.js +649 -0
  102. package/dist/packem_shared/minio-C2YBZQOw.js +22 -0
  103. package/dist/packem_shared/multipart-base-B3i67SSX.js +102 -0
  104. package/dist/packem_shared/part-match-BMNqHDYD.js +96 -0
  105. package/dist/packem_shared/path-CR6YkPXX-7R1-9CMk.js +161 -0
  106. package/dist/packem_shared/response-builder-BtnRiBUI.js +45 -0
  107. package/dist/packem_shared/rest-base-GRCcnan7.js +457 -0
  108. package/dist/packem_shared/restOpenApiSpec-CwcHHY2C.js +800 -0
  109. package/dist/packem_shared/s3-base-storage-C1DIHTYY.js +510 -0
  110. package/dist/packem_shared/sharedGet-Cpo7QUyu.js +1019 -0
  111. package/dist/packem_shared/storage-C6NSXb8h.js +1175 -0
  112. package/dist/packem_shared/tigris-Hac8TKnX.js +21 -0
  113. package/dist/packem_shared/transformOpenApiSpec-DWM5WtnN.js +975 -0
  114. package/dist/packem_shared/tusOpenApiSpec-6ohiToBy.js +740 -0
  115. package/dist/packem_shared/update-size-CCGm6i1J.js +8 -0
  116. package/dist/packem_shared/validator-BeX_lJet.js +78 -0
  117. package/dist/packem_shared/waitForStorage-Cscw85sx.js +18 -0
  118. package/dist/packem_shared/wasabi-DIyflHSd.js +21 -0
  119. package/dist/packem_shared/xhrOpenApiSpec-DS17brnx.js +264 -0
  120. package/dist/storage/aws/clients/backblaze.d.ts +12 -0
  121. package/dist/storage/aws/clients/cloudflare.d.ts +13 -0
  122. package/dist/storage/aws/clients/digital-ocean.d.ts +12 -0
  123. package/dist/storage/aws/clients/index.d.ts +6 -0
  124. package/dist/storage/aws/clients/index.js +6 -0
  125. package/dist/storage/aws/clients/minio.d.ts +13 -0
  126. package/dist/storage/aws/clients/tigris.d.ts +12 -0
  127. package/dist/storage/aws/clients/types.d.ts +95 -0
  128. package/dist/storage/aws/clients/wasabi.d.ts +12 -0
  129. package/dist/storage/aws/index.d.ts +4 -0
  130. package/dist/storage/aws/index.js +3 -0
  131. package/dist/storage/aws/s3-base-storage.d.ts +248 -0
  132. package/dist/storage/aws/s3-client-adapter.d.ts +110 -0
  133. package/dist/storage/aws/s3-file.d.ts +10 -0
  134. package/dist/storage/aws/s3-meta-storage.d.ts +15 -0
  135. package/dist/storage/aws/s3-storage.d.ts +70 -0
  136. package/dist/storage/aws/types.d.ts +119 -0
  137. package/dist/storage/aws-light/aws-light-api-adapter.d.ts +130 -0
  138. package/dist/storage/aws-light/aws-light-file.d.ts +10 -0
  139. package/dist/storage/aws-light/aws-light-meta-storage.d.ts +19 -0
  140. package/dist/storage/aws-light/aws-light-storage.d.ts +65 -0
  141. package/dist/storage/aws-light/index.d.ts +4 -0
  142. package/dist/storage/aws-light/index.js +3 -0
  143. package/dist/storage/aws-light/types.d.ts +37 -0
  144. package/dist/storage/azure/azure-file.d.ts +6 -0
  145. package/dist/storage/azure/azure-meta-storage.d.ts +15 -0
  146. package/dist/storage/azure/azure-storage.d.ts +69 -0
  147. package/dist/storage/azure/index.d.ts +4 -0
  148. package/dist/storage/azure/index.js +3 -0
  149. package/dist/storage/azure/types.d.ts +62 -0
  150. package/dist/storage/gcs/fetch-error.d.ts +11 -0
  151. package/dist/storage/gcs/gcs-config.d.ts +2 -0
  152. package/dist/storage/gcs/gcs-file.d.ts +6 -0
  153. package/dist/storage/gcs/gcs-meta-storage.d.ts +27 -0
  154. package/dist/storage/gcs/gcs-storage.d.ts +91 -0
  155. package/dist/storage/gcs/index.d.ts +5 -0
  156. package/dist/storage/gcs/index.js +4 -0
  157. package/dist/storage/gcs/types.d.ts +55 -0
  158. package/dist/storage/gcs/utils.d.ts +7 -0
  159. package/dist/storage/local/disk-storage-with-checksum.d.ts +15 -0
  160. package/dist/storage/local/disk-storage.d.ts +135 -0
  161. package/dist/storage/local/index.d.ts +4 -0
  162. package/dist/storage/local/index.js +3 -0
  163. package/dist/storage/local/local-meta-storage.d.ts +32 -0
  164. package/dist/storage/meta-storage.d.ts +30 -0
  165. package/dist/storage/netlify-blob/index.d.ts +4 -0
  166. package/dist/storage/netlify-blob/index.js +3 -0
  167. package/dist/storage/netlify-blob/netlify-blob-file.d.ts +12 -0
  168. package/dist/storage/netlify-blob/netlify-blob-meta-storage.d.ts +7 -0
  169. package/dist/storage/netlify-blob/netlify-blob-storage.d.ts +93 -0
  170. package/dist/storage/netlify-blob/types.d.ts +30 -0
  171. package/dist/storage/storage.d.ts +353 -0
  172. package/dist/storage/types.d.ts +221 -0
  173. package/dist/storage/utils/file/file.d.ts +25 -0
  174. package/dist/storage/utils/file/get-file-status.d.ts +9 -0
  175. package/dist/storage/utils/file/has-content.d.ts +9 -0
  176. package/dist/storage/utils/file/index.d.ts +10 -0
  177. package/dist/storage/utils/file/is-expired.d.ts +8 -0
  178. package/dist/storage/utils/file/metadata.d.ts +18 -0
  179. package/dist/storage/utils/file/part-match.d.ts +11 -0
  180. package/dist/storage/utils/file/types.d.ts +37 -0
  181. package/dist/storage/utils/file/update-metadata.d.ts +10 -0
  182. package/dist/storage/utils/file/update-size.d.ts +10 -0
  183. package/dist/storage/vercel-blob/index.d.ts +4 -0
  184. package/dist/storage/vercel-blob/index.js +3 -0
  185. package/dist/storage/vercel-blob/types.d.ts +32 -0
  186. package/dist/storage/vercel-blob/vercel-blob-file.d.ts +16 -0
  187. package/dist/storage/vercel-blob/vercel-blob-meta-storage.d.ts +7 -0
  188. package/dist/storage/vercel-blob/vercel-blob-storage.d.ts +76 -0
  189. package/dist/transformer/audio-transformer.d.ts +128 -0
  190. package/dist/transformer/audio-transformer.js +278 -0
  191. package/dist/transformer/base-transformer.d.ts +63 -0
  192. package/dist/transformer/image-transformer.d.ts +571 -0
  193. package/dist/transformer/image-transformer.js +1100 -0
  194. package/dist/transformer/index.d.ts +5 -0
  195. package/dist/transformer/index.js +4 -0
  196. package/dist/transformer/media-transformer.d.ts +332 -0
  197. package/dist/transformer/types.d.ts +652 -0
  198. package/dist/transformer/utils.d.ts +33 -0
  199. package/dist/transformer/validation-error.d.ts +23 -0
  200. package/dist/transformer/video-transformer.d.ts +145 -0
  201. package/dist/transformer/video-transformer.js +310 -0
  202. package/dist/utils/cache.d.ts +32 -0
  203. package/dist/utils/chunked-upload.d.ts +65 -0
  204. package/dist/utils/detect-file-type.d.ts +28 -0
  205. package/dist/utils/errors.d.ts +74 -0
  206. package/dist/utils/file-path-url-matcher.d.ts +18 -0
  207. package/dist/utils/headers.d.ts +111 -0
  208. package/dist/utils/http.d.ts +92 -0
  209. package/dist/utils/locker.d.ts +26 -0
  210. package/dist/utils/pipes/stream-checksum.d.ts +47 -0
  211. package/dist/utils/pipes/stream-length.d.ts +22 -0
  212. package/dist/utils/primitives/get-last-one.d.ts +3 -0
  213. package/dist/utils/primitives/is-record.d.ts +2 -0
  214. package/dist/utils/primitives/map-values.d.ts +9 -0
  215. package/dist/utils/primitives/pick.d.ts +2 -0
  216. package/dist/utils/primitives/to-milliseconds.d.ts +12 -0
  217. package/dist/utils/primitives/to-seconds.d.ts +12 -0
  218. package/dist/utils/range-checksum.d.ts +33 -0
  219. package/dist/utils/range-hasher.d.ts +46 -0
  220. package/dist/utils/retry.d.ts +64 -0
  221. package/dist/utils/types.d.ts +108 -0
  222. package/dist/utils/validation-error.d.ts +22 -0
  223. package/dist/utils/validator.d.ts +36 -0
  224. package/package.json +5 -5
@@ -0,0 +1,65 @@
1
+ import Multipart from '../../../packem_shared/Multipart-CNFK_Okz.js';
2
+ import RestFetch from '../../../packem_shared/Rest-CAOAEkOj.js';
3
+ import { Tus } from '../../../packem_shared/Tus-B8PmlMgR.js';
4
+
5
+ const createHandlerFunction = (handler) => async (c) => {
6
+ try {
7
+ const request = c.req.raw;
8
+ return await handler.fetch(request);
9
+ } catch (error) {
10
+ const errorObject = error;
11
+ const statusCode = errorObject.statusCode || (errorObject.status ? Number.parseInt(errorObject.status, 10) : void 0) || 500;
12
+ return Response.json({ error: errorObject.message || "Request failed" }, { status: statusCode });
13
+ }
14
+ };
15
+ const createStorageHandler = (app, config) => {
16
+ const { path, type, ...handlerConfig } = config;
17
+ let handler;
18
+ switch (type) {
19
+ case "multipart": {
20
+ handler = new Multipart(handlerConfig);
21
+ break;
22
+ }
23
+ case "rest": {
24
+ handler = new RestFetch(handlerConfig);
25
+ break;
26
+ }
27
+ case "tus": {
28
+ handler = new Tus(handlerConfig);
29
+ break;
30
+ }
31
+ default: {
32
+ throw new Error(`Unknown handler type: ${String(type ?? "unknown")}`);
33
+ }
34
+ }
35
+ const handlerFunction = createHandlerFunction(handler);
36
+ switch (type) {
37
+ case "multipart": {
38
+ app.post(path, handlerFunction);
39
+ app.get(`${path}/:id?/:metadata?`, handlerFunction);
40
+ app.delete(`${path}/:id`, handlerFunction);
41
+ app.on("OPTIONS", path, handlerFunction);
42
+ break;
43
+ }
44
+ case "rest": {
45
+ app.post(path, handlerFunction);
46
+ app.put(`${path}/:id`, handlerFunction);
47
+ app.patch(`${path}/:id`, handlerFunction);
48
+ app.get(`${path}/:id?`, handlerFunction);
49
+ app.on("HEAD", `${path}/:id`, handlerFunction);
50
+ app.delete(`${path}/:id?`, handlerFunction);
51
+ app.on("OPTIONS", path, handlerFunction);
52
+ break;
53
+ }
54
+ case "tus": {
55
+ app.all(path, handlerFunction);
56
+ app.all(`${path}/:id`, handlerFunction);
57
+ break;
58
+ }
59
+ default: {
60
+ throw new Error(`Unknown handler type: ${String(type)}`);
61
+ }
62
+ }
63
+ };
64
+
65
+ export { createStorageHandler };
@@ -0,0 +1,61 @@
1
+ import type { NextRequest } from "next/server";
2
+ import { NextResponse } from "next/server";
3
+ import type { UploadFile } from "../../../storage/utils/index.d.ts";
4
+ import type { UploadOptions } from "../../types.d.ts";
5
+ /**
6
+ * Configuration for Next.js handler.
7
+ */
8
+ export interface NextjsHandlerConfig<TFile extends UploadFile> extends UploadOptions<TFile> {
9
+ /** Handler type to use */
10
+ type: "multipart" | "rest" | "tus";
11
+ }
12
+ /**
13
+ * Next.js route handler that automatically exports the correct HTTP methods for each handler type.
14
+ * @example
15
+ * ```ts
16
+ * // app/api/upload/multipart/route.ts
17
+ * import { DiskStorage } from "@visulima/storage";
18
+ * import { createHandler } from "@visulima/storage/handler/http/nextjs";
19
+ *
20
+ * const storage = new DiskStorage({ directory: "./uploads" });
21
+ * const handler = createHandler({ storage, type: "multipart" });
22
+ *
23
+ * export const POST = handler;
24
+ * export const DELETE = handler;
25
+ * export const GET = handler;
26
+ * export const OPTIONS = handler;
27
+ * ```
28
+ * @example
29
+ * ```ts
30
+ * // app/api/upload/rest/route.ts
31
+ * import { DiskStorage } from "@visulima/storage";
32
+ * import { createHandler } from "@visulima/storage/handler/http/nextjs";
33
+ *
34
+ * const storage = new DiskStorage({ directory: "./uploads" });
35
+ * const handler = createHandler({ storage, type: "rest" });
36
+ *
37
+ * export const POST = handler;
38
+ * export const PUT = handler;
39
+ * export const PATCH = handler;
40
+ * export const GET = handler;
41
+ * export const HEAD = handler;
42
+ * export const DELETE = handler;
43
+ * export const OPTIONS = handler;
44
+ * ```
45
+ * @example
46
+ * ```ts
47
+ * // app/api/upload/tus/route.ts
48
+ * import { DiskStorage } from "@visulima/storage";
49
+ * import { createHandler } from "@visulima/storage/handler/http/nextjs";
50
+ *
51
+ * const storage = new DiskStorage({ directory: "./uploads" });
52
+ * const handler = createHandler({ storage, type: "tus" });
53
+ *
54
+ * export const POST = handler;
55
+ * export const PATCH = handler;
56
+ * export const HEAD = handler;
57
+ * export const DELETE = handler;
58
+ * export const OPTIONS = handler;
59
+ * ```
60
+ */
61
+ export declare const createHandler: <TFile extends UploadFile>(config: NextjsHandlerConfig<TFile>) => (request: NextRequest) => Promise<NextResponse>;
@@ -0,0 +1,37 @@
1
+ import { NextResponse } from 'next/server';
2
+ import Multipart from '../../../packem_shared/Multipart-CNFK_Okz.js';
3
+ import RestFetch from '../../../packem_shared/Rest-CAOAEkOj.js';
4
+ import { Tus } from '../../../packem_shared/Tus-B8PmlMgR.js';
5
+
6
+ const createHandler = (config) => {
7
+ let handler;
8
+ switch (config.type) {
9
+ case "multipart": {
10
+ handler = new Multipart(config);
11
+ break;
12
+ }
13
+ case "rest": {
14
+ handler = new RestFetch(config);
15
+ break;
16
+ }
17
+ case "tus": {
18
+ handler = new Tus(config);
19
+ break;
20
+ }
21
+ default: {
22
+ throw new Error(`Unknown handler type: ${String(config.type ?? "unknown")}`);
23
+ }
24
+ }
25
+ const nextjsHandler = async (request) => {
26
+ try {
27
+ return await handler.fetch(request);
28
+ } catch (error) {
29
+ const errorObject = error;
30
+ const statusCode = errorObject.statusCode || (errorObject.status ? Number.parseInt(errorObject.status, 10) : void 0) || 500;
31
+ return NextResponse.json({ error: errorObject.message || "Request failed" }, { status: statusCode });
32
+ }
33
+ };
34
+ return nextjsHandler;
35
+ };
36
+
37
+ export { createHandler };
@@ -0,0 +1,4 @@
1
+ export { default as Multipart } from "../../multipart/multipart.d.ts";
2
+ export { default as Rest } from "../../rest/rest.d.ts";
3
+ export { Tus, TUS_RESUMABLE, TUS_VERSION } from "../../tus/tus.d.ts";
4
+ export type { AsyncHandler, BaseHandler, Handlers, MethodHandler, RequestEvent, UploadErrorEvent, UploadEvent, UploadOptions } from "../../types.d.ts";
@@ -0,0 +1,4 @@
1
+ export { default as Multipart } from '../../../packem_shared/Multipart-CtUL7BQw.js';
2
+ export { default as Rest } from '../../../packem_shared/Rest-DNuLwBrK.js';
3
+ export { Tus } from '../../../packem_shared/Tus-C4F1aYOl.js';
4
+ export { TUS_RESUMABLE, TUS_VERSION } from '../../../packem_shared/TUS_RESUMABLE-GJzZ9R-f.js';
@@ -0,0 +1,60 @@
1
+ import type { APIEvent } from "@solidjs/start/server";
2
+ import type { UploadFile } from "../../../storage/utils/index.d.ts";
3
+ import type { UploadOptions } from "../../types.d.ts";
4
+ /**
5
+ * Configuration for SolidStart handler.
6
+ */
7
+ export interface SolidStartHandlerConfig<TFile extends UploadFile> extends UploadOptions<TFile> {
8
+ /** Handler type to use */
9
+ type: "multipart" | "rest" | "tus";
10
+ }
11
+ /**
12
+ * SolidStart API route handler that automatically handles the correct HTTP methods for each handler type.
13
+ * @example
14
+ * ```ts
15
+ * // app/routes/api/upload/multipart.ts
16
+ * import { DiskStorage } from "@visulima/storage";
17
+ * import { createSolidStartHandler } from "@visulima/storage/handler/http/solid-start";
18
+ *
19
+ * const storage = new DiskStorage({ directory: "./uploads" });
20
+ * const handler = createSolidStartHandler({ storage, type: "multipart" });
21
+ *
22
+ * export const POST = handler;
23
+ * export const DELETE = handler;
24
+ * export const GET = handler;
25
+ * export const OPTIONS = handler;
26
+ * ```
27
+ * @example
28
+ * ```ts
29
+ * // app/routes/api/upload/rest.ts
30
+ * import { DiskStorage } from "@visulima/storage";
31
+ * import { createSolidStartHandler } from "@visulima/storage/handler/http/solid-start";
32
+ *
33
+ * const storage = new DiskStorage({ directory: "./uploads" });
34
+ * const handler = createSolidStartHandler({ storage, type: "rest" });
35
+ *
36
+ * export const POST = handler;
37
+ * export const PUT = handler;
38
+ * export const PATCH = handler;
39
+ * export const GET = handler;
40
+ * export const HEAD = handler;
41
+ * export const DELETE = handler;
42
+ * export const OPTIONS = handler;
43
+ * ```
44
+ * @example
45
+ * ```ts
46
+ * // app/routes/api/upload/tus.ts
47
+ * import { DiskStorage } from "@visulima/storage";
48
+ * import { createSolidStartHandler } from "@visulima/storage/handler/http/solid-start";
49
+ *
50
+ * const storage = new DiskStorage({ directory: "./uploads" });
51
+ * const handler = createSolidStartHandler({ storage, type: "tus" });
52
+ *
53
+ * export const POST = handler;
54
+ * export const PATCH = handler;
55
+ * export const HEAD = handler;
56
+ * export const DELETE = handler;
57
+ * export const OPTIONS = handler;
58
+ * ```
59
+ */
60
+ export declare const createSolidStartHandler: <TFile extends UploadFile>(config: SolidStartHandlerConfig<TFile>) => (event: APIEvent) => Promise<Response>;
@@ -0,0 +1,44 @@
1
+ import Multipart from '../../../packem_shared/Multipart-CNFK_Okz.js';
2
+ import RestFetch from '../../../packem_shared/Rest-CAOAEkOj.js';
3
+ import { Tus } from '../../../packem_shared/Tus-B8PmlMgR.js';
4
+
5
+ const createSolidStartHandler = (config) => {
6
+ let handler;
7
+ switch (config.type) {
8
+ case "multipart": {
9
+ handler = new Multipart(config);
10
+ break;
11
+ }
12
+ case "rest": {
13
+ handler = new RestFetch(config);
14
+ break;
15
+ }
16
+ case "tus": {
17
+ handler = new Tus(config);
18
+ break;
19
+ }
20
+ default: {
21
+ throw new Error(`Unknown handler type: ${String(config.type ?? "unknown")}`);
22
+ }
23
+ }
24
+ const solidStartHandler = async (event) => {
25
+ try {
26
+ return await handler.fetch(event.request);
27
+ } catch (error) {
28
+ const errorObject = error;
29
+ const statusCode = errorObject.statusCode || (errorObject.status ? Number.parseInt(errorObject.status, 10) : void 0) || 500;
30
+ return Response.json(
31
+ { error: errorObject.message || "Request failed" },
32
+ {
33
+ headers: {
34
+ "Content-Type": "application/json"
35
+ },
36
+ status: statusCode
37
+ }
38
+ );
39
+ }
40
+ };
41
+ return solidStartHandler;
42
+ };
43
+
44
+ export { createSolidStartHandler };
@@ -0,0 +1,84 @@
1
+ import type { FileInit, UploadFile } from "../../storage/utils/index.d.ts";
2
+ import type { ResponseFile } from "../types.d.ts";
3
+ /**
4
+ * Base class containing shared Multipart business logic.
5
+ * Platform-agnostic - contains no Node.js or Web API specific code.
6
+ * @template TFile The file type used by this handler.
7
+ */
8
+ declare abstract class MultipartBase<TFile extends UploadFile> {
9
+ /**
10
+ * Handle multipart POST (upload file).
11
+ * @param filePart File part from multipart parser
12
+ * @param filePart.bytes File bytes data
13
+ * @param filePart.filename Original filename
14
+ * @param filePart.mediaType Content type
15
+ * @param filePart.size File size in bytes
16
+ * @param metadataParts All parts from multipart parser (for extracting metadata)
17
+ * @param requestUrl Request URL for Location header
18
+ * @returns Promise resolving to ResponseFile with upload result
19
+ */
20
+ handlePost(filePart: {
21
+ bytes: unknown;
22
+ filename?: string;
23
+ mediaType?: string;
24
+ size: number;
25
+ }, metadataParts: {
26
+ isFile: boolean;
27
+ name?: string;
28
+ text?: string;
29
+ }[], requestUrl: string): Promise<ResponseFile<TFile>>;
30
+ /**
31
+ * Handle DELETE (delete file).
32
+ * @param id File ID from URL
33
+ * @returns Promise resolving to ResponseFile with deletion result
34
+ */
35
+ handleDelete(id: string): Promise<ResponseFile<TFile>>;
36
+ /**
37
+ * Storage instance for file operations.
38
+ */
39
+ protected get storage(): {
40
+ create: (config: FileInit) => Promise<TFile>;
41
+ delete: (options: {
42
+ id: string;
43
+ }) => Promise<TFile>;
44
+ maxUploadSize: number;
45
+ update: (options: {
46
+ id: string;
47
+ }, updates: {
48
+ metadata?: Record<string, unknown>;
49
+ }) => Promise<TFile>;
50
+ write: (options: {
51
+ body: unknown;
52
+ contentLength: number;
53
+ id: string;
54
+ start: number;
55
+ }) => Promise<TFile>;
56
+ };
57
+ /**
58
+ * Maximum file size allowed for multipart uploads
59
+ */
60
+ protected abstract get maxFileSize(): number;
61
+ /**
62
+ * Maximum header size allowed for multipart parser
63
+ */
64
+ protected abstract get maxHeaderSize(): number;
65
+ /**
66
+ * Build file URL from request URL and file data.
67
+ * @param _requestUrl Request URL string
68
+ * @param _file File object containing ID and content type
69
+ * @returns Constructed file URL with extension based on content type
70
+ */
71
+ protected buildFileUrl(_requestUrl: string, _file: TFile): string;
72
+ /**
73
+ * Create a stream from bytes data.
74
+ * @param bytes Bytes data (Uint8Array, Buffer, or other)
75
+ * @returns Stream object
76
+ */
77
+ protected abstract createStreamFromBytes(bytes: unknown): unknown;
78
+ /**
79
+ * Create an empty stream for signaling completion.
80
+ * @returns Empty stream object
81
+ */
82
+ protected abstract createEmptyStream(): unknown;
83
+ }
84
+ export default MultipartBase;
@@ -0,0 +1,64 @@
1
+ import type { UploadFile } from "../../storage/utils/index.d.ts";
2
+ import BaseHandlerFetch from "../base/base-handler-fetch.d.ts";
3
+ import type { Handlers, ResponseFile, UploadOptions } from "../types.d.ts";
4
+ /**
5
+ * Multipart/form-data upload handler (Web API Fetch version).
6
+ * @example
7
+ * ```ts
8
+ * const multipart = new MultipartFetch({
9
+ * storage,
10
+ * maxFileSize: 100 * 1024 * 1024, // 100MB
11
+ * });
12
+ *
13
+ * // Use with Hono, Cloudflare Workers, etc.
14
+ * app.all('/files/*', async (c) => {
15
+ * return multipart.fetch(c.req.raw);
16
+ * });
17
+ * ```
18
+ */
19
+ declare class Multipart<TFile extends UploadFile> extends BaseHandlerFetch<TFile> {
20
+ /**
21
+ * Limiting enabled http method handler
22
+ */
23
+ static readonly methods: Handlers[];
24
+ private readonly multipartBase;
25
+ /**
26
+ * Maximum file size allowed for multipart uploads
27
+ */
28
+ private maxFileSize;
29
+ /**
30
+ * Maximum header size allowed for multipart parser
31
+ */
32
+ private maxHeaderSize;
33
+ constructor(options: UploadOptions<TFile>);
34
+ /**
35
+ * Handles multipart/form-data POST requests for file uploads.
36
+ * @param request Web API Request containing multipart data.
37
+ * @returns Promise resolving to ResponseFile with upload result.
38
+ */
39
+ post(request: Request): Promise<ResponseFile<TFile>>;
40
+ /**
41
+ * Delete an uploaded file.
42
+ * @param request Web API Request with file ID
43
+ * @returns Promise resolving to ResponseFile with deletion result
44
+ */
45
+ delete(request: Request): Promise<ResponseFile<TFile>>;
46
+ /**
47
+ * Handle OPTIONS requests with CORS headers.
48
+ * @param _request Web API Request (unused)
49
+ * @returns Promise resolving to ResponseFile with CORS headers
50
+ */
51
+ options(_request: Request): Promise<ResponseFile<TFile>>;
52
+ /**
53
+ * Retrieves a file or list of files based on the request path.
54
+ * Delegates to BaseHandlerFetch.fetch() method.
55
+ * @param _request Web API Request
56
+ * @returns Promise resolving to Web API Response
57
+ */
58
+ get(_request: Request): Promise<ResponseFile<TFile>>;
59
+ /**
60
+ * Compose and register HTTP method handlers.
61
+ */
62
+ protected compose(): void;
63
+ }
64
+ export default Multipart;
@@ -0,0 +1,49 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { UploadFile } from "../../storage/utils/index.d.ts";
3
+ import BaseHandlerNode from "../base/base-handler-node.d.ts";
4
+ import type { Handlers, ResponseFile, UploadOptions } from "../types.d.ts";
5
+ /**
6
+ * Multipart/form-data upload handler (Node.js version).
7
+ * @example
8
+ * ```ts
9
+ * const multipart = new Multipart({
10
+ * storage,
11
+ * maxFileSize: 100 * 1024 * 1024, // 100MB
12
+ * });
13
+ *
14
+ * app.use('/files', multipart.handle);
15
+ * ```
16
+ */
17
+ declare class Multipart<TFile extends UploadFile, NodeRequest extends IncomingMessage = IncomingMessage, NodeResponse extends ServerResponse = ServerResponse> extends BaseHandlerNode<TFile, NodeRequest, NodeResponse> {
18
+ /**
19
+ * Limiting enabled http method handler
20
+ */
21
+ static readonly methods: Handlers[];
22
+ private readonly multipartBase;
23
+ /**
24
+ * Maximum file size allowed for multipart uploads
25
+ */
26
+ private maxFileSize;
27
+ /**
28
+ * Maximum header size allowed for multipart parser
29
+ */
30
+ private maxHeaderSize;
31
+ constructor(options: UploadOptions<TFile>);
32
+ /**
33
+ * Handles multipart/form-data POST requests for file uploads.
34
+ * @param request Node.js IncomingMessage containing multipart data.
35
+ * @returns Promise resolving to ResponseFile with upload result.
36
+ */
37
+ post(request: NodeRequest): Promise<ResponseFile<TFile>>;
38
+ /**
39
+ * Delete an uploaded file.
40
+ * @param request Node.js IncomingMessage with file ID
41
+ * @returns Promise resolving to ResponseFile with deletion result
42
+ */
43
+ delete(request: NodeRequest): Promise<ResponseFile<TFile>>;
44
+ /**
45
+ * Compose and register HTTP method handlers.
46
+ */
47
+ protected compose(): void;
48
+ }
49
+ export default Multipart;
@@ -0,0 +1,106 @@
1
+ import type { FileInit, UploadFile } from "../../storage/utils/index.d.ts";
2
+ import type { ResponseFile, ResponseList } from "../types.d.ts";
3
+ /**
4
+ * Base class containing shared REST API business logic.
5
+ * Platform-agnostic - contains no Node.js or Web API specific code.
6
+ * @template TFile The file type used by this handler.
7
+ */
8
+ declare abstract class RestBase<TFile extends UploadFile> {
9
+ /**
10
+ * Handle single file deletion.
11
+ * @param id File ID to delete
12
+ * @returns Promise resolving to ResponseFile with deletion result
13
+ */
14
+ deleteSingle(id: string): Promise<ResponseFile<TFile>>;
15
+ /**
16
+ * Handle file creation (POST).
17
+ * @param config File initialization config
18
+ * @param isChunkedUpload Whether this is a chunked upload initialization
19
+ * @param requestUrl Request URL for Location header
20
+ * @param bodyStream Request body stream (for non-chunked uploads)
21
+ * @param contentLength Content length (for non-chunked uploads)
22
+ * @returns Promise resolving to ResponseFile with upload result
23
+ */
24
+ handlePost(config: FileInit, isChunkedUpload: boolean, requestUrl: string, bodyStream: unknown, contentLength: number): Promise<ResponseFile<TFile>>;
25
+ /**
26
+ * Handle file update or creation (PUT).
27
+ * @param id File ID from URL
28
+ * @param config File initialization config (for new files)
29
+ * @param requestUrl Request URL for Location header
30
+ * @param bodyStream Request body stream
31
+ * @param contentLength Content length
32
+ * @param metadata Optional metadata to merge (for updates)
33
+ * @returns Promise resolving to ResponseFile with upload result
34
+ */
35
+ handlePut(id: string, config: FileInit, requestUrl: string, bodyStream: unknown, contentLength: number, metadata?: Record<string, unknown>): Promise<ResponseFile<TFile>>;
36
+ /**
37
+ * Handle chunked upload chunk (PATCH).
38
+ * @param id File ID from URL
39
+ * @param chunkOffset Chunk offset in bytes
40
+ * @param contentLength Chunk content length
41
+ * @param chunkChecksum Optional chunk checksum
42
+ * @param requestUrl Request URL for Location header
43
+ * @param bodyStream Request body stream
44
+ * @returns Promise resolving to ResponseFile with upload progress
45
+ */
46
+ handlePatch(id: string, chunkOffset: number, contentLength: number, chunkChecksum: string | undefined, requestUrl: string, bodyStream: unknown): Promise<ResponseFile<TFile>>;
47
+ /**
48
+ * Handle file metadata retrieval (HEAD).
49
+ * @param id File ID from URL
50
+ * @returns Promise resolving to ResponseFile with metadata headers
51
+ */
52
+ handleHead(id: string): Promise<ResponseFile<TFile>>;
53
+ /**
54
+ * Handle OPTIONS request with REST API capabilities.
55
+ * @param methods Array of supported HTTP methods
56
+ * @param maxUploadSize Maximum upload size
57
+ * @returns ResponseFile with CORS headers
58
+ */
59
+ handleOptions(methods: string[], maxUploadSize: number): ResponseFile<TFile>;
60
+ /**
61
+ * Handle batch file deletion.
62
+ * @param ids Array of file IDs to delete
63
+ * @returns Promise resolving to ResponseList with deletion results
64
+ */
65
+ deleteBatch(ids: string[]): Promise<ResponseList<TFile>>;
66
+ /**
67
+ * Storage instance for file operations.
68
+ */
69
+ protected get storage(): {
70
+ create: (config: FileInit) => Promise<TFile>;
71
+ delete: (options: {
72
+ id: string;
73
+ }) => Promise<TFile>;
74
+ deleteBatch: (ids: string[]) => Promise<{
75
+ failed: {
76
+ error: string;
77
+ id: string;
78
+ }[];
79
+ failedCount: number;
80
+ successful: TFile[];
81
+ successfulCount: number;
82
+ }>;
83
+ getMeta: (id: string) => Promise<TFile>;
84
+ maxUploadSize: number;
85
+ update: (options: {
86
+ id: string;
87
+ }, updates: {
88
+ metadata?: Record<string, unknown>;
89
+ status?: string;
90
+ }) => Promise<void>;
91
+ write: (options: {
92
+ body: unknown;
93
+ contentLength: number;
94
+ id: string;
95
+ start: number;
96
+ }) => Promise<TFile>;
97
+ };
98
+ /**
99
+ * Build file URL from request URL and file data.
100
+ * @param _requestUrl Request URL string
101
+ * @param _file File object containing ID and content type
102
+ * @returns Constructed file URL with extension based on content type
103
+ */
104
+ protected buildFileUrl(_requestUrl: string, _file: TFile): string;
105
+ }
106
+ export default RestBase;
@@ -0,0 +1,88 @@
1
+ import type { UploadFile } from "../../storage/utils/index.d.ts";
2
+ import BaseHandlerFetch from "../base/base-handler-fetch.d.ts";
3
+ import type { Handlers, ResponseFile, ResponseList, UploadOptions } from "../types.d.ts";
4
+ /**
5
+ * REST API handler for direct binary file uploads (Web API Fetch version).
6
+ *
7
+ * This handler provides a clean REST interface for file operations using Web API Request/Response:
8
+ * - POST: Create a new file with raw binary data or initialize chunked upload
9
+ * - PUT: Create or update a file (requires ID in URL)
10
+ * - PATCH: Upload chunks for chunked uploads (requires ID in URL)
11
+ * - GET: Retrieve a file or list files
12
+ * - DELETE: Delete a file (single) or multiple files (via ?ids=id1,id2 or JSON body)
13
+ * - HEAD: Get file metadata and upload progress
14
+ * - OPTIONS: CORS preflight
15
+ * @example
16
+ * ```ts
17
+ * const rest = new RestFetch({
18
+ * storage,
19
+ * });
20
+ *
21
+ * // Use with Hono, Cloudflare Workers, etc.
22
+ * app.all('/files/*', async (c) => {
23
+ * return rest.fetch(c.req.raw);
24
+ * });
25
+ * ```
26
+ */
27
+ declare class RestFetch<TFile extends UploadFile> extends BaseHandlerFetch<TFile> {
28
+ /**
29
+ * Limiting enabled http method handler
30
+ */
31
+ static readonly methods: Handlers[];
32
+ private readonly restBase;
33
+ constructor(options: UploadOptions<TFile>);
34
+ /**
35
+ * Compose and register HTTP method handlers.
36
+ */
37
+ protected compose(): void;
38
+ /**
39
+ * Creates a new file via POST request with raw binary data.
40
+ * Supports both full file uploads and chunked upload initialization.
41
+ * @param request Web API Request with file data.
42
+ * @returns Promise resolving to ResponseFile with upload result.
43
+ */
44
+ post(request: Request): Promise<ResponseFile<TFile>>;
45
+ /**
46
+ * Create or update a file via PUT request.
47
+ * Requires file ID in the URL path.
48
+ * @param request Web API Request with file ID and data
49
+ * @returns Promise resolving to ResponseFile with upload result
50
+ */
51
+ put(request: Request): Promise<ResponseFile<TFile>>;
52
+ /**
53
+ * Delete an uploaded file or multiple files.
54
+ * Supports single file (ID in URL) or batch delete (via ?ids=id1,id2 or JSON body).
55
+ * @param request Web API Request with file ID(s)
56
+ * @returns Promise resolving to ResponseFile (single) or ResponseList (batch) with deletion result
57
+ */
58
+ delete(request: Request): Promise<ResponseFile<TFile> | ResponseList<TFile>>;
59
+ /**
60
+ * Uploads a chunk via PATCH request for chunked uploads.
61
+ * Headers required: X-Chunk-Offset (byte offset), Content-Length (chunk size).
62
+ * Optional: X-Chunk-Checksum (SHA256 checksum for validation).
63
+ * @param request Web API Request with chunk data.
64
+ * @returns Promise resolving to ResponseFile with upload progress.
65
+ */
66
+ patch(request: Request): Promise<ResponseFile<TFile>>;
67
+ /**
68
+ * Get file metadata via HEAD request.
69
+ * For chunked uploads, also returns upload progress information.
70
+ * @param request Web API Request with file ID
71
+ * @returns Promise resolving to ResponseFile with metadata headers
72
+ */
73
+ head(request: Request): Promise<ResponseFile<TFile>>;
74
+ /**
75
+ * Handle OPTIONS requests with REST API capabilities.
76
+ * @param _request Web API Request
77
+ * @returns Promise resolving to ResponseFile with CORS headers
78
+ */
79
+ options(_request: Request): Promise<ResponseFile<TFile>>;
80
+ /**
81
+ * Retrieves a file or list of files based on the request path.
82
+ * Delegates to BaseHandlerFetch.fetch() method.
83
+ * @param _request Web API Request
84
+ * @returns Promise resolving to Web API Response
85
+ */
86
+ get(_request: Request): Promise<ResponseFile<TFile> | ResponseList<TFile>>;
87
+ }
88
+ export default RestFetch;