@dimah-s3/server 0.7.3 → 0.8.0

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 (118) hide show
  1. package/README.md +8 -9
  2. package/dist/adapters/express.js +36 -49
  3. package/dist/adapters/express.js.map +1 -1
  4. package/dist/adapters/fastify.js +36 -49
  5. package/dist/adapters/fastify.js.map +1 -1
  6. package/dist/adapters/next.d.ts +3 -1
  7. package/dist/adapters/next.d.ts.map +1 -1
  8. package/dist/adapters/next.js +2 -0
  9. package/dist/adapters/next.js.map +1 -1
  10. package/dist/adapters/node.d.ts +1 -1
  11. package/dist/adapters/node.d.ts.map +1 -1
  12. package/dist/adapters/node.js +36 -49
  13. package/dist/adapters/node.js.map +1 -1
  14. package/dist/adapters/types.d.ts +1 -1
  15. package/dist/adapters/types.d.ts.map +1 -1
  16. package/dist/api/assert-feature-enabled.d.ts +5 -0
  17. package/dist/api/assert-feature-enabled.d.ts.map +1 -0
  18. package/dist/api/bind-endpoints.d.ts +8 -0
  19. package/dist/api/bind-endpoints.d.ts.map +1 -0
  20. package/dist/api/context.d.ts +10 -0
  21. package/dist/api/context.d.ts.map +1 -0
  22. package/dist/api/create-s3-endpoint.d.ts +141 -0
  23. package/dist/api/create-s3-endpoint.d.ts.map +1 -0
  24. package/dist/api/create-s3-middleware.d.ts +23 -0
  25. package/dist/api/create-s3-middleware.d.ts.map +1 -0
  26. package/dist/api/index.d.ts +6 -0
  27. package/dist/api/index.d.ts.map +1 -0
  28. package/dist/api/index.js +758 -0
  29. package/dist/api/index.js.map +1 -0
  30. package/dist/api/routes/confirm.d.ts +14 -0
  31. package/dist/api/routes/confirm.d.ts.map +1 -0
  32. package/dist/api/routes/delete.d.ts +16 -0
  33. package/dist/api/routes/delete.d.ts.map +1 -0
  34. package/dist/api/routes/download.d.ts +19 -0
  35. package/dist/api/routes/download.d.ts.map +1 -0
  36. package/dist/api/routes/index.d.ts +170 -0
  37. package/dist/api/routes/index.d.ts.map +1 -0
  38. package/dist/api/routes/multipart/abort.d.ts +20 -0
  39. package/dist/api/routes/multipart/abort.d.ts.map +1 -0
  40. package/dist/api/routes/multipart/complete.d.ts +22 -0
  41. package/dist/api/routes/multipart/complete.d.ts.map +1 -0
  42. package/dist/api/routes/multipart/init.d.ts +26 -0
  43. package/dist/api/routes/multipart/init.d.ts.map +1 -0
  44. package/dist/api/routes/multipart/list-parts.d.ts +17 -0
  45. package/dist/api/routes/multipart/list-parts.d.ts.map +1 -0
  46. package/dist/api/routes/multipart/part.d.ts +22 -0
  47. package/dist/api/routes/multipart/part.d.ts.map +1 -0
  48. package/dist/api/routes/upload.d.ts +26 -0
  49. package/dist/api/routes/upload.d.ts.map +1 -0
  50. package/dist/dimah-s3.d.ts +41 -12
  51. package/dist/dimah-s3.d.ts.map +1 -1
  52. package/dist/errors.d.ts +8 -22
  53. package/dist/errors.d.ts.map +1 -1
  54. package/dist/helpers/resolve-target.d.ts +51 -0
  55. package/dist/helpers/resolve-target.d.ts.map +1 -0
  56. package/dist/index.d.ts +7 -5
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +521 -483
  59. package/dist/index.js.map +1 -1
  60. package/dist/internal-helpers.d.ts +4 -8
  61. package/dist/internal-helpers.d.ts.map +1 -1
  62. package/dist/plugin/apply-plugins.d.ts.map +1 -1
  63. package/dist/plugin/chain-hooks.d.ts +1 -1
  64. package/dist/plugin/define-plugin.d.ts +4 -13
  65. package/dist/plugin/define-plugin.d.ts.map +1 -1
  66. package/dist/plugin/hook-registry.d.ts +2 -2
  67. package/dist/plugin/hook-registry.d.ts.map +1 -1
  68. package/dist/plugin/index.d.ts +1 -2
  69. package/dist/plugin/index.d.ts.map +1 -1
  70. package/dist/plugin/types.d.ts +21 -41
  71. package/dist/plugin/types.d.ts.map +1 -1
  72. package/dist/plugins.d.ts +7 -0
  73. package/dist/plugins.d.ts.map +1 -0
  74. package/dist/plugins.js +984 -0
  75. package/dist/plugins.js.map +1 -0
  76. package/dist/router.d.ts +12 -0
  77. package/dist/router.d.ts.map +1 -0
  78. package/dist/types/config.d.ts +61 -22
  79. package/dist/types/config.d.ts.map +1 -1
  80. package/dist/types/hook-contexts.d.ts +11 -6
  81. package/dist/types/hook-contexts.d.ts.map +1 -1
  82. package/dist/types/index.d.ts +2 -2
  83. package/dist/types/index.d.ts.map +1 -1
  84. package/package.json +16 -6
  85. package/dist/adapters/adapters.test.d.ts +0 -2
  86. package/dist/adapters/adapters.test.d.ts.map +0 -1
  87. package/dist/api.d.ts +0 -5
  88. package/dist/api.d.ts.map +0 -1
  89. package/dist/handler.d.ts +0 -5
  90. package/dist/handler.d.ts.map +0 -1
  91. package/dist/helpers/is-aws-not-found.test.d.ts +0 -2
  92. package/dist/helpers/is-aws-not-found.test.d.ts.map +0 -1
  93. package/dist/internal-helpers.test.d.ts +0 -2
  94. package/dist/internal-helpers.test.d.ts.map +0 -1
  95. package/dist/plugin/apply-plugins.test.d.ts +0 -2
  96. package/dist/plugin/apply-plugins.test.d.ts.map +0 -1
  97. package/dist/plugin/create-endpoint.d.ts +0 -20
  98. package/dist/plugin/create-endpoint.d.ts.map +0 -1
  99. package/dist/procedures/confirm.d.ts +0 -8
  100. package/dist/procedures/confirm.d.ts.map +0 -1
  101. package/dist/procedures/delete.d.ts +0 -8
  102. package/dist/procedures/delete.d.ts.map +0 -1
  103. package/dist/procedures/download.d.ts +0 -10
  104. package/dist/procedures/download.d.ts.map +0 -1
  105. package/dist/procedures/multipart/abort.d.ts +0 -13
  106. package/dist/procedures/multipart/abort.d.ts.map +0 -1
  107. package/dist/procedures/multipart/complete.d.ts +0 -12
  108. package/dist/procedures/multipart/complete.d.ts.map +0 -1
  109. package/dist/procedures/multipart/init.d.ts +0 -13
  110. package/dist/procedures/multipart/init.d.ts.map +0 -1
  111. package/dist/procedures/multipart/list-parts.d.ts +0 -9
  112. package/dist/procedures/multipart/list-parts.d.ts.map +0 -1
  113. package/dist/procedures/multipart/part.d.ts +0 -12
  114. package/dist/procedures/multipart/part.d.ts.map +0 -1
  115. package/dist/procedures/registry.d.ts +0 -78
  116. package/dist/procedures/registry.d.ts.map +0 -1
  117. package/dist/procedures/upload.d.ts +0 -14
  118. package/dist/procedures/upload.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/errors.ts","../../src/internal-helpers.ts","../../src/api/create-s3-middleware.ts","../../src/api/create-s3-endpoint.ts","../../src/helpers/is-aws-not-found.ts","../../src/helpers/resolve-object-acl.ts","../../src/helpers/resolve-target.ts","../../src/api/assert-feature-enabled.ts","../../src/api/routes/confirm.ts","../../src/api/routes/delete.ts","../../src/api/routes/download.ts","../../src/api/routes/multipart/abort.ts","../../src/api/routes/multipart/complete.ts","../../src/api/routes/multipart/init.ts","../../src/api/routes/multipart/list-parts.ts","../../src/api/routes/multipart/part.ts","../../src/api/routes/upload.ts","../../src/api/routes/index.ts"],"names":["isAPIError","DimahS3Error","HeadObjectCommand","S3_API_ROUTES","parseFileName","buildContentDisposition","ListPartsCommand","getSignedUrl","url"],"mappings":"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","file":"index.js","sourcesContent":["import {\n DimahS3Error,\n S3_ERROR_CODES,\n isAPIError,\n isDimahS3Error,\n isS3ErrorCode,\n} from \"@dimah-s3/core\";\n\nexport { DimahS3Error, isAPIError, isDimahS3Error, isS3ErrorCode };\n\n/** English API errors with stable codes for client-side localization. */\nexport const errors = {\n notFound: () => DimahS3Error.from(\"NOT_FOUND\", S3_ERROR_CODES.NOT_FOUND),\n\n unauthorized: () =>\n DimahS3Error.from(\"UNAUTHORIZED\", S3_ERROR_CODES.UNAUTHORIZED),\n\n forbidden: () => DimahS3Error.from(\"FORBIDDEN\", S3_ERROR_CODES.FORBIDDEN),\n\n conflict: () => DimahS3Error.from(\"CONFLICT\", S3_ERROR_CODES.CONFLICT),\n\n internalError: () =>\n DimahS3Error.from(\"INTERNAL_SERVER_ERROR\", S3_ERROR_CODES.INTERNAL_ERROR),\n\n objectNotFound: () =>\n DimahS3Error.from(\"NOT_FOUND\", S3_ERROR_CODES.OBJECT_NOT_FOUND),\n\n featureDisabled: (feature: string) =>\n DimahS3Error.from(\"NOT_FOUND\", {\n code: S3_ERROR_CODES.FEATURE_DISABLED.code,\n message: S3_ERROR_CODES.FEATURE_DISABLED.message.replaceAll(\n \"{feature}\",\n feature,\n ),\n params: { feature },\n }),\n\n invalidKey: () =>\n DimahS3Error.from(\"BAD_REQUEST\", S3_ERROR_CODES.INVALID_KEY),\n\n invalidBucket: (bucket: string) =>\n DimahS3Error.from(\"FORBIDDEN\", {\n code: S3_ERROR_CODES.INVALID_BUCKET.code,\n message: S3_ERROR_CODES.INVALID_BUCKET.message,\n params: { bucket },\n }),\n\n s3NetworkError: (code: string) =>\n DimahS3Error.from(\"BAD_GATEWAY\", {\n code: S3_ERROR_CODES.S3_NETWORK_ERROR.code,\n message: S3_ERROR_CODES.S3_NETWORK_ERROR.message.replaceAll(\n \"{code}\",\n code,\n ),\n params: { code },\n }),\n\n fileSizeRequiredUpload: () =>\n DimahS3Error.from(\"BAD_REQUEST\", S3_ERROR_CODES.FILE_SIZE_REQUIRED_UPLOAD),\n\n fileSizeRequiredMultipart: () =>\n DimahS3Error.from(\n \"BAD_REQUEST\",\n S3_ERROR_CODES.FILE_SIZE_REQUIRED_MULTIPART,\n ),\n\n validationError: (message: string) =>\n DimahS3Error.from(\"BAD_REQUEST\", {\n code: S3_ERROR_CODES.VALIDATION_ERROR.code,\n message,\n }),\n} as const;\n\nexport type ServerErrors = typeof errors;\n","import { DimahS3Error, isAPIError } from \"@dimah-s3/core\";\nimport { errors } from \"./errors\";\n\n/**\n * Run a guard hook. {@link isAPIError} values are preserved; plain Errors keep\n * their English message without a library `code` so client\n * `useFormatDimahError` does not replace them with a generic mapped string.\n */\nexport async function runHook<T extends { request: Request }>(\n hook: ((context: T) => Promise<void> | void) | undefined,\n context: T,\n): Promise<void> {\n if (!hook) return;\n try {\n await hook(context);\n } catch (err) {\n if (isAPIError(err)) throw err;\n if (err instanceof Error && err.message.trim()) {\n throw new DimahS3Error(\"FORBIDDEN\", {\n message: err.message,\n cause: err,\n });\n }\n throw errors.forbidden();\n }\n}\n\n/**\n * Run a lifecycle `on*` hook. Failures become {@link errors.internalError}\n * (or preserve an existing APIError).\n */\nexport async function runLifecycleHook<T extends { request: Request }>(\n hook: ((context: T) => Promise<void> | void) | undefined,\n context: T,\n): Promise<void> {\n if (!hook) return;\n try {\n await hook(context);\n } catch (err) {\n if (isAPIError(err)) throw err;\n console.error(\"[S3 API] lifecycle hook failed\", err);\n throw errors.internalError();\n }\n}\n\nexport function normalizeExpiresIn(value: unknown): number {\n const n = Number(value);\n return Number.isFinite(n) && n > 0 ? Math.floor(n) : 600;\n}\n\n/** Build a synthetic Request for server-side `api` calls. */\nexport function requestFromHeaders(headers?: HeadersInit): Request {\n return new Request(\"http://dimah-s3.local\", { headers });\n}\n","import { createMiddleware } from \"better-call\";\nimport { requestFromHeaders, runHook } from \"../internal-helpers\";\nimport type { S3EndpointContext } from \"./context\";\n\n/**\n * Injects `config` / `request` and runs the global `guard`.\n * Used by {@link createS3Endpoint} so HTTP and `s3.api` share the same path.\n */\nexport const s3ContextMiddleware = createMiddleware(async (ctx) => {\n const injected = ctx.context as Partial<S3EndpointContext> | undefined;\n if (!injected?.config) {\n throw new Error(\n \"createS3Endpoint requires dimahS3 router context. Call endpoints through dimahS3().api or the HTTP handler.\",\n );\n }\n\n const request =\n ctx.request ??\n injected.request ??\n requestFromHeaders(ctx.headers as HeadersInit | undefined);\n\n await runHook(injected.config.guard, { request });\n\n return {\n config: injected.config,\n request,\n } satisfies S3EndpointContext;\n});\n\n/**\n * Middleware factory with dimah-s3 context already applied — same idea as\n * Better Auth `createAuthMiddleware`.\n */\nexport const createS3Middleware = createMiddleware.create({\n use: [s3ContextMiddleware],\n});\n","import { createEndpoint, type EndpointOptions } from \"better-call\";\nimport { errors } from \"../errors\";\nimport { s3ContextMiddleware } from \"./create-s3-middleware\";\n\nconst createEndpointWithContext = createEndpoint.create({\n use: [s3ContextMiddleware],\n});\n\nfunction withS3Validation<O extends EndpointOptions>(options: O): O {\n return {\n ...options,\n onValidationError:\n options.onValidationError ??\n (({ message }: { message: string }) => {\n throw errors.validationError(message);\n }),\n };\n}\n\ntype CreateS3Endpoint = typeof createEndpointWithContext;\n\n/**\n * Typed endpoint for dimah-s3 plugins and core routes.\n *\n * Paths are absolute under `basePath` (e.g. `/db/objects`). Context\n * (`config`, `request`) is injected by the router / `s3.api`.\n * Zod failures throw `DimahS3Error` (`VALIDATION_ERROR`) via\n * better-call `onValidationError`.\n *\n * ```ts\n * endpoints: {\n * recent: createS3Endpoint(\"/audit/recent\", { method: \"GET\" }, async (ctx) => {\n * return { events: [] };\n * }),\n * }\n * ```\n */\nexport const createS3Endpoint: CreateS3Endpoint = ((\n pathOrOptions: string | EndpointOptions,\n optionsOrHandler: EndpointOptions | ((...args: never[]) => unknown),\n maybeHandler?: (...args: never[]) => unknown,\n) => {\n if (typeof pathOrOptions === \"string\") {\n return createEndpointWithContext(\n pathOrOptions,\n withS3Validation(optionsOrHandler as EndpointOptions),\n maybeHandler as never,\n );\n }\n return createEndpointWithContext(\n withS3Validation(pathOrOptions),\n optionsOrHandler as never,\n );\n}) as unknown as CreateS3Endpoint;\n","/** True when an AWS SDK throw means the object (or key) does not exist. */\nexport function isAwsNotFound(err: unknown): boolean {\n const e = err as {\n name?: string;\n Code?: string;\n $metadata?: { httpStatusCode?: number };\n };\n return (\n e?.name === \"NoSuchKey\" ||\n e?.name === \"NotFound\" ||\n e?.Code === \"NoSuchKey\" ||\n e?.Code === \"NotFound\" ||\n e?.$metadata?.httpStatusCode === 404\n );\n}\n","import { GetObjectAclCommand, type S3Client } from \"@aws-sdk/client-s3\";\n\nconst DEFAULT_ACL_LOOKUP_TIMEOUT_MS = 1_500;\n\n/**\n * Determines the ACL of an S3 object by querying `GetObjectAcl`.\n *\n * Returns `\"public-read\"` when the `AllUsers` grantee has `READ` or\n * `FULL_CONTROL` permission, `\"private\"` when ACL is resolvable but not public,\n * and `undefined` when ACL cannot be resolved (e.g. unsupported providers).\n */\nexport async function resolveObjectAcl(\n s3: S3Client,\n bucket: string,\n key: string,\n timeoutMs: number = DEFAULT_ACL_LOOKUP_TIMEOUT_MS,\n): Promise<\"public-read\" | \"private\" | undefined> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const result = await s3.send(\n new GetObjectAclCommand({ Bucket: bucket, Key: key }),\n { abortSignal: controller.signal },\n );\n const isPublic = result.Grants?.some(\n (g) =>\n g.Grantee?.URI === \"http://acs.amazonaws.com/groups/global/AllUsers\" &&\n (g.Permission === \"READ\" || g.Permission === \"FULL_CONTROL\"),\n );\n return isPublic ? \"public-read\" : \"private\";\n } catch {\n return undefined;\n } finally {\n clearTimeout(timeout);\n }\n}\n","import { errors } from \"../errors\";\nimport type {\n DownloadConfig,\n DeleteConfig,\n FeatureToggle,\n KeyPrefix,\n MultipartConfig,\n ResolvedDimahS3Config,\n ResolveKeyContext,\n UploadConfig,\n} from \"../types\";\n\ntype KeyPolicy = {\n prefix?: KeyPrefix;\n resolveKey?: (context: ResolveKeyContext) => string | Promise<string>;\n};\n\n/**\n * Normalize a client-proposed object key: strip leading slashes, reject\n * `.` / `..` segments, NUL, and backslashes.\n */\nexport function assertSafeObjectKey(key: string): string {\n const trimmed = key.replace(/^\\/+/u, \"\").replace(/\\/+$/u, \"\");\n if (!trimmed) {\n throw errors.invalidKey();\n }\n if (trimmed.includes(\"\\\\\") || trimmed.includes(\"\\0\")) {\n throw errors.invalidKey();\n }\n const parts = trimmed.split(\"/\");\n if (parts.some((part) => part === \"\" || part === \".\" || part === \"..\")) {\n throw errors.invalidKey();\n }\n return parts.join(\"/\");\n}\n\nfunction applyPrefix(prefix: string, key: string): string {\n const p = assertSafeObjectKey(prefix);\n const k = assertSafeObjectKey(key);\n if (k === p || k.startsWith(`${p}/`)) return k;\n return `${p}/${k}`;\n}\n\nexport async function resolveObjectKey(\n policy: KeyPolicy | undefined,\n context: ResolveKeyContext,\n): Promise<string> {\n if (policy?.resolveKey) {\n return assertSafeObjectKey(await policy.resolveKey(context));\n }\n const prefix =\n typeof policy?.prefix === \"function\"\n ? await policy.prefix(context)\n : policy?.prefix;\n if (prefix) {\n return applyPrefix(prefix, context.proposedKey);\n }\n return assertSafeObjectKey(context.proposedKey);\n}\n\nexport function resolveBucket(\n config: ResolvedDimahS3Config,\n requested?: string,\n): string {\n if (!requested) return config.bucket;\n if (config.allowClientBucket) return requested;\n if (config.buckets?.length) {\n if (config.buckets.includes(requested)) return requested;\n throw errors.invalidBucket(requested);\n }\n return config.bucket;\n}\n\nexport async function resolveRequestTarget(\n config: ResolvedDimahS3Config,\n policy: KeyPolicy | undefined,\n input: {\n request: Request;\n key: string;\n bucket?: string;\n fileName?: string;\n contentType?: string;\n },\n): Promise<{ key: string; bucket: string }> {\n const bucket = resolveBucket(config, input.bucket);\n const key = await resolveObjectKey(policy, {\n request: input.request,\n proposedKey: input.key,\n fileName: input.fileName,\n contentType: input.contentType,\n bucket,\n });\n return { key, bucket };\n}\n\nexport function normalizeFeature<T extends { enabled?: boolean }>(\n value: FeatureToggle<T> | undefined,\n): (T & { enabled: boolean }) | undefined {\n if (value === undefined) return undefined;\n if (value === false) return { enabled: false } as T & { enabled: boolean };\n if (value === true) return { enabled: true } as T & { enabled: boolean };\n return { ...value, enabled: value.enabled ?? true };\n}\n\nexport function isFeatureEnabled(\n config: ResolvedDimahS3Config,\n feature: \"upload\" | \"download\" | \"delete\" | \"multipart\",\n): boolean {\n return config[feature]?.enabled === true;\n}\n\nexport function applyMultipartDefault(\n config: ResolvedDimahS3Config,\n multipartInput: FeatureToggle<MultipartConfig> | undefined,\n): ResolvedDimahS3Config {\n let next = config;\n if (multipartInput === undefined && config.upload?.enabled) {\n next = {\n ...config,\n multipart: { ...config.multipart, enabled: true },\n };\n }\n if (next.multipart && next.upload) {\n next = {\n ...next,\n multipart: {\n ...next.multipart,\n prefix: next.multipart.prefix ?? next.upload.prefix,\n resolveKey: next.multipart.resolveKey ?? next.upload.resolveKey,\n },\n };\n }\n return next;\n}\n\nexport type NormalizedFeatures = {\n upload?: UploadConfig & { enabled: boolean };\n download?: DownloadConfig & { enabled: boolean };\n delete?: DeleteConfig & { enabled: boolean };\n multipart?: MultipartConfig & { enabled: boolean };\n};\n\nexport function normalizeFeatures(config: {\n upload?: FeatureToggle<UploadConfig>;\n download?: FeatureToggle<DownloadConfig>;\n delete?: FeatureToggle<DeleteConfig>;\n multipart?: FeatureToggle<MultipartConfig>;\n}): NormalizedFeatures {\n return {\n upload: normalizeFeature(config.upload),\n download: normalizeFeature(config.download),\n delete: normalizeFeature(config.delete),\n multipart: normalizeFeature(config.multipart),\n };\n}\n","import { errors } from \"../errors\";\nimport { isFeatureEnabled } from \"../helpers/resolve-target\";\nimport type { ResolvedDimahS3Config } from \"../types\";\n\nexport type FeatureFlag = \"upload\" | \"download\" | \"delete\" | \"multipart\";\n\n/** Disabled features respond 404 (`FEATURE_DISABLED`) from both HTTP and `s3.api`. */\nexport function assertFeatureEnabled(\n config: ResolvedDimahS3Config,\n feature: FeatureFlag,\n): void {\n if (!isFeatureEnabled(config, feature)) {\n throw errors.featureDisabled(feature);\n }\n}\n","import { HeadObjectCommand } from \"@aws-sdk/client-s3\";\nimport {\n confirmBodySchema,\n parseFileName,\n S3_API_ROUTES,\n type UploadConfirmResponse,\n} from \"@dimah-s3/core\";\nimport { resolveObjectAcl } from \"../../helpers\";\nimport { runHook, runLifecycleHook } from \"../../internal-helpers\";\nimport type { ResolvedDimahS3Config } from \"../../types\";\nimport { resolveRequestTarget } from \"../../helpers/resolve-target\";\nimport { assertFeatureEnabled } from \"../assert-feature-enabled\";\nimport { createS3Endpoint } from \"../create-s3-endpoint\";\n\nasync function handleConfirm(\n config: ResolvedDimahS3Config,\n input: typeof confirmBodySchema._output,\n request: Request,\n): Promise<UploadConfirmResponse> {\n const { key, bucket } = await resolveRequestTarget(config, config.upload, {\n request,\n key: input.key,\n bucket: input.bucket,\n });\n\n await runHook(config.upload?.confirmGuard, {\n request,\n key,\n bucket,\n });\n\n const head = await config.client.send(\n new HeadObjectCommand({ Bucket: bucket, Key: key }),\n );\n\n const acl = config.resolveObjectAcl\n ? await resolveObjectAcl(config.client, bucket, key)\n : undefined;\n const fileName = parseFileName(head.ContentDisposition);\n\n const context = {\n request,\n key,\n bucket,\n contentType: head.ContentType,\n contentLength: head.ContentLength ?? 0,\n eTag: head.ETag?.replace(/\"/g, \"\"),\n metadata: head.Metadata,\n acl,\n fileName,\n versionId: head.VersionId,\n lastModified: head.LastModified?.toISOString(),\n };\n\n await runLifecycleHook(config.upload?.onConfirmed, context);\n\n return {\n key,\n bucket,\n contentType: context.contentType,\n contentLength: context.contentLength,\n eTag: context.eTag,\n metadata: context.metadata ?? {},\n acl,\n fileName,\n versionId: context.versionId,\n lastModified: context.lastModified,\n };\n}\n\nexport const confirm = createS3Endpoint(\n S3_API_ROUTES.uploadConfirm,\n { method: \"POST\", body: confirmBodySchema },\n async (ctx) => {\n assertFeatureEnabled(ctx.context.config, \"upload\");\n return handleConfirm(ctx.context.config, ctx.body, ctx.context.request);\n },\n);\n","import { DeleteObjectCommand, HeadObjectCommand } from \"@aws-sdk/client-s3\";\nimport {\n deleteQuerySchema,\n S3_API_ROUTES,\n type DeleteResponse,\n} from \"@dimah-s3/core\";\nimport { errors } from \"../../errors\";\nimport { isAwsNotFound } from \"../../helpers\";\nimport { runHook, runLifecycleHook } from \"../../internal-helpers\";\nimport type { ResolvedDimahS3Config } from \"../../types\";\nimport { resolveRequestTarget } from \"../../helpers/resolve-target\";\nimport { assertFeatureEnabled } from \"../assert-feature-enabled\";\nimport { createS3Endpoint } from \"../create-s3-endpoint\";\n\nasync function handleDelete(\n config: ResolvedDimahS3Config,\n input: typeof deleteQuerySchema._output,\n request: Request,\n): Promise<DeleteResponse> {\n const { key, bucket } = await resolveRequestTarget(config, config.delete, {\n request,\n key: input.key,\n bucket: input.bucket,\n });\n\n await runHook(config.delete?.guard, {\n request,\n key,\n bucket,\n });\n\n try {\n await config.client.send(\n new HeadObjectCommand({ Bucket: bucket, Key: key }),\n );\n } catch (err: unknown) {\n if (isAwsNotFound(err)) {\n throw errors.objectNotFound();\n }\n throw err;\n }\n\n await config.client.send(\n new DeleteObjectCommand({ Bucket: bucket, Key: key }),\n );\n\n await runLifecycleHook(config.delete?.onDeleted, { request, key, bucket });\n\n return { success: true, bucket, key };\n}\n\nexport const deleteObject = createS3Endpoint(\n S3_API_ROUTES.delete,\n { method: \"DELETE\", query: deleteQuerySchema },\n async (ctx) => {\n assertFeatureEnabled(ctx.context.config, \"delete\");\n return handleDelete(ctx.context.config, ctx.query, ctx.context.request);\n },\n);\n","import { GetObjectCommand, HeadObjectCommand } from \"@aws-sdk/client-s3\";\nimport { getSignedUrl } from \"@aws-sdk/s3-request-presigner\";\nimport {\n buildContentDisposition,\n downloadQuerySchema,\n S3_API_ROUTES,\n type PresignResponse,\n} from \"@dimah-s3/core\";\nimport { errors } from \"../../errors\";\nimport { isAwsNotFound } from \"../../helpers\";\nimport {\n normalizeExpiresIn,\n runHook,\n runLifecycleHook,\n} from \"../../internal-helpers\";\nimport type { ResolvedDimahS3Config } from \"../../types\";\nimport { resolveRequestTarget } from \"../../helpers/resolve-target\";\nimport { assertFeatureEnabled } from \"../assert-feature-enabled\";\nimport { createS3Endpoint } from \"../create-s3-endpoint\";\n\nasync function handleDownload(\n config: ResolvedDimahS3Config,\n input: typeof downloadQuerySchema._output,\n request: Request,\n): Promise<PresignResponse> {\n const { key, bucket } = await resolveRequestTarget(config, config.download, {\n request,\n key: input.key,\n bucket: input.bucket,\n fileName: input.fileName,\n });\n const expiresIn = normalizeExpiresIn(input.expiresIn);\n const fileName = input.fileName;\n\n await runHook(config.download?.guard, {\n request,\n key,\n bucket,\n fileName,\n });\n\n try {\n await config.client.send(\n new HeadObjectCommand({ Bucket: bucket, Key: key }),\n );\n } catch (err: unknown) {\n if (isAwsNotFound(err)) {\n throw errors.objectNotFound();\n }\n throw err;\n }\n\n const url = await getSignedUrl(\n config.client,\n new GetObjectCommand({\n Bucket: bucket,\n Key: key,\n ResponseContentDisposition: fileName\n ? buildContentDisposition(fileName)\n : \"attachment\",\n }),\n { expiresIn },\n );\n\n await runLifecycleHook(config.download?.onPresigned, {\n request,\n key,\n bucket,\n fileName,\n url,\n expiresIn,\n });\n\n return { bucket, key, url, expiresIn };\n}\n\nexport const download = createS3Endpoint(\n S3_API_ROUTES.download,\n { method: \"GET\", query: downloadQuerySchema },\n async (ctx) => {\n assertFeatureEnabled(ctx.context.config, \"download\");\n return handleDownload(ctx.context.config, ctx.query, ctx.context.request);\n },\n);\n","import { AbortMultipartUploadCommand } from \"@aws-sdk/client-s3\";\nimport {\n multipartAbortBodySchema,\n S3_API_ROUTES,\n type MultipartAbortResponse,\n} from \"@dimah-s3/core\";\nimport { runHook, runLifecycleHook } from \"../../../internal-helpers\";\nimport type { ResolvedDimahS3Config } from \"../../../types\";\nimport { resolveRequestTarget } from \"../../../helpers/resolve-target\";\nimport { assertFeatureEnabled } from \"../../assert-feature-enabled\";\nimport { createS3Endpoint } from \"../../create-s3-endpoint\";\n\nasync function handleAbort(\n config: ResolvedDimahS3Config,\n input: typeof multipartAbortBodySchema._output,\n request: Request,\n): Promise<\n MultipartAbortResponse & { bucket: string; key: string; uploadId: string }\n> {\n const { key, bucket } = await resolveRequestTarget(config, config.multipart, {\n request,\n key: input.key,\n bucket: input.bucket,\n });\n const uploadId = input.uploadId;\n\n await runHook(config.multipart?.abortGuard, {\n request,\n key,\n bucket,\n uploadId,\n });\n\n await config.client.send(\n new AbortMultipartUploadCommand({\n Bucket: bucket,\n Key: key,\n UploadId: uploadId,\n }),\n );\n\n await runLifecycleHook(config.multipart?.onAbort, {\n request,\n key,\n bucket,\n uploadId,\n });\n\n return { bucket, key, uploadId, aborted: true };\n}\n\nexport const multipartAbort = createS3Endpoint(\n S3_API_ROUTES.multipartAbort,\n { method: \"POST\", body: multipartAbortBodySchema },\n async (ctx) => {\n assertFeatureEnabled(ctx.context.config, \"multipart\");\n return handleAbort(ctx.context.config, ctx.body, ctx.context.request);\n },\n);\n","import {\n CompleteMultipartUploadCommand,\n HeadObjectCommand,\n ListPartsCommand,\n} from \"@aws-sdk/client-s3\";\nimport {\n multipartCompleteBodySchema,\n parseFileName,\n S3_API_ROUTES,\n type MultipartCompleteResponse,\n} from \"@dimah-s3/core\";\nimport { resolveObjectAcl } from \"../../../helpers\";\nimport { runHook, runLifecycleHook } from \"../../../internal-helpers\";\nimport type { ResolvedDimahS3Config } from \"../../../types\";\nimport { resolveRequestTarget } from \"../../../helpers/resolve-target\";\nimport { assertFeatureEnabled } from \"../../assert-feature-enabled\";\nimport { createS3Endpoint } from \"../../create-s3-endpoint\";\n\nasync function handleComplete(\n config: ResolvedDimahS3Config,\n input: typeof multipartCompleteBodySchema._output,\n request: Request,\n): Promise<MultipartCompleteResponse> {\n const { key, bucket } = await resolveRequestTarget(config, config.multipart, {\n request,\n key: input.key,\n bucket: input.bucket,\n });\n const uploadId = input.uploadId;\n const parts = input.parts\n .map(({ partNumber }) => partNumber)\n .sort((a, b) => a - b);\n const partRefs = parts.map((partNumber) => ({ partNumber }));\n\n await runHook(config.multipart?.completeGuard, {\n request,\n key,\n bucket,\n uploadId,\n parts: partRefs,\n });\n\n const listed = await config.client.send(\n new ListPartsCommand({ Bucket: bucket, Key: key, UploadId: uploadId }),\n );\n const listedParts = listed.Parts ?? [];\n\n const completeParts = parts.map((partNumber) => {\n const found = listedParts.find((p) => p.PartNumber === partNumber);\n return { PartNumber: partNumber, ETag: found?.ETag ?? \"\" };\n });\n\n const completeResult = await config.client.send(\n new CompleteMultipartUploadCommand({\n Bucket: bucket,\n Key: key,\n UploadId: uploadId,\n MultipartUpload: { Parts: completeParts },\n }),\n );\n\n let head = await config.client.send(\n new HeadObjectCommand({ Bucket: bucket, Key: key }),\n );\n for (let attempt = 0; attempt < 4 && !head.ContentLength; attempt++) {\n await new Promise((r) => setTimeout(r, 250 * 2 ** attempt));\n head = await config.client.send(\n new HeadObjectCommand({ Bucket: bucket, Key: key }),\n );\n }\n const contentLength = head.ContentLength ?? 0;\n const contentType = head.ContentType;\n const eTag = (head.ETag ?? completeResult.ETag ?? \"\").replace(/\"/g, \"\");\n const metadata = head.Metadata ?? {};\n const versionId = head.VersionId;\n const lastModified = head.LastModified?.toISOString();\n\n const acl = config.resolveObjectAcl\n ? await resolveObjectAcl(config.client, bucket, key)\n : undefined;\n const fileName = parseFileName(head.ContentDisposition);\n\n await runLifecycleHook(config.multipart?.onComplete, {\n request,\n key,\n bucket,\n uploadId,\n contentLength,\n contentType,\n eTag,\n metadata,\n acl,\n fileName,\n versionId,\n lastModified,\n });\n\n return {\n bucket,\n key,\n uploadId,\n contentLength,\n contentType,\n eTag,\n metadata,\n acl,\n fileName,\n versionId,\n lastModified,\n };\n}\n\nexport const multipartComplete = createS3Endpoint(\n S3_API_ROUTES.multipartComplete,\n { method: \"POST\", body: multipartCompleteBodySchema },\n async (ctx) => {\n assertFeatureEnabled(ctx.context.config, \"multipart\");\n return handleComplete(ctx.context.config, ctx.body, ctx.context.request);\n },\n);\n","import { CreateMultipartUploadCommand } from \"@aws-sdk/client-s3\";\nimport {\n buildContentDisposition,\n multipartInitBodySchema,\n S3_API_ROUTES,\n type MultipartInitResponse,\n} from \"@dimah-s3/core\";\nimport { errors } from \"../../../errors\";\nimport { runHook, runLifecycleHook } from \"../../../internal-helpers\";\nimport type { ResolvedDimahS3Config } from \"../../../types\";\nimport { resolveRequestTarget } from \"../../../helpers/resolve-target\";\nimport { assertFeatureEnabled } from \"../../assert-feature-enabled\";\nimport { createS3Endpoint } from \"../../create-s3-endpoint\";\n\nasync function handleMultipartInit(\n config: ResolvedDimahS3Config,\n input: typeof multipartInitBodySchema._output,\n request: Request,\n): Promise<MultipartInitResponse> {\n const { key, bucket } = await resolveRequestTarget(config, config.multipart, {\n request,\n key: input.key,\n bucket: input.bucket,\n fileName: input.fileName,\n contentType: input.contentType,\n });\n const acl = input.acl === \"public-read\" ? \"public-read\" : \"private\";\n const fileSize =\n typeof input.fileSize === \"number\" && input.fileSize > 0\n ? Math.floor(input.fileSize)\n : undefined;\n\n if (config.multipart?.requireFileSize && fileSize === undefined) {\n throw errors.fileSizeRequiredMultipart();\n }\n\n await runHook(config.multipart?.initGuard, {\n request,\n key,\n bucket,\n fileSize,\n });\n\n const { UploadId } = await config.client.send(\n new CreateMultipartUploadCommand({\n Bucket: bucket,\n Key: key,\n ContentType: input.contentType,\n ContentDisposition: input.fileName\n ? buildContentDisposition(input.fileName)\n : undefined,\n Metadata: input.metadata,\n ACL: acl,\n }),\n );\n\n await runLifecycleHook(config.multipart?.onInit, {\n request,\n key,\n bucket,\n uploadId: UploadId!,\n contentType: input.contentType,\n fileSize,\n metadata: input.metadata,\n acl,\n fileName: input.fileName,\n });\n\n return { bucket, key, uploadId: UploadId! };\n}\n\nexport const multipartInit = createS3Endpoint(\n S3_API_ROUTES.multipartInit,\n { method: \"POST\", body: multipartInitBodySchema },\n async (ctx) => {\n assertFeatureEnabled(ctx.context.config, \"multipart\");\n ctx.setStatus(201);\n return handleMultipartInit(\n ctx.context.config,\n ctx.body,\n ctx.context.request,\n );\n },\n);\n","import { ListPartsCommand } from \"@aws-sdk/client-s3\";\nimport {\n multipartListPartsQuerySchema,\n S3_API_ROUTES,\n type MultipartListPartsResponse,\n} from \"@dimah-s3/core\";\nimport { runHook, runLifecycleHook } from \"../../../internal-helpers\";\nimport type { ResolvedDimahS3Config } from \"../../../types\";\nimport { resolveRequestTarget } from \"../../../helpers/resolve-target\";\nimport { assertFeatureEnabled } from \"../../assert-feature-enabled\";\nimport { createS3Endpoint } from \"../../create-s3-endpoint\";\n\nasync function handleListParts(\n config: ResolvedDimahS3Config,\n input: typeof multipartListPartsQuerySchema._output,\n request: Request,\n): Promise<MultipartListPartsResponse> {\n const { key, bucket } = await resolveRequestTarget(config, config.multipart, {\n request,\n key: input.key,\n bucket: input.bucket,\n });\n const uploadId = input.uploadId;\n\n await runHook(config.multipart?.listGuard, {\n request,\n key,\n bucket,\n uploadId,\n });\n\n const response = await config.client.send(\n new ListPartsCommand({\n Bucket: bucket,\n Key: key,\n UploadId: uploadId,\n }),\n );\n\n const parts = (response.Parts ?? []).map((p) => ({\n partNumber: p.PartNumber ?? 0,\n size: p.Size ?? 0,\n eTag: (p.ETag ?? \"\").replace(/\"/g, \"\"),\n }));\n\n await runLifecycleHook(config.multipart?.onList, {\n request,\n key,\n bucket,\n uploadId,\n parts,\n });\n\n return { parts };\n}\n\nexport const multipartListParts = createS3Endpoint(\n S3_API_ROUTES.multipartListParts,\n { method: \"GET\", query: multipartListPartsQuerySchema },\n async (ctx) => {\n assertFeatureEnabled(ctx.context.config, \"multipart\");\n return handleListParts(ctx.context.config, ctx.query, ctx.context.request);\n },\n);\n","import { UploadPartCommand } from \"@aws-sdk/client-s3\";\nimport { getSignedUrl } from \"@aws-sdk/s3-request-presigner\";\nimport {\n multipartSignPartBodySchema,\n S3_API_ROUTES,\n type MultipartPartResponse,\n} from \"@dimah-s3/core\";\nimport { normalizeExpiresIn, runHook } from \"../../../internal-helpers\";\nimport type { ResolvedDimahS3Config } from \"../../../types\";\nimport { resolveRequestTarget } from \"../../../helpers/resolve-target\";\nimport { assertFeatureEnabled } from \"../../assert-feature-enabled\";\nimport { createS3Endpoint } from \"../../create-s3-endpoint\";\n\nasync function handleSignPart(\n config: ResolvedDimahS3Config,\n input: typeof multipartSignPartBodySchema._output,\n request: Request,\n): Promise<MultipartPartResponse> {\n const { key, bucket } = await resolveRequestTarget(config, config.multipart, {\n request,\n key: input.key,\n bucket: input.bucket,\n });\n const uploadId = input.uploadId;\n const partNumber = input.partNumber;\n const expiresIn = normalizeExpiresIn(input.expiresIn);\n const partSize =\n typeof input.partSize === \"number\" && input.partSize > 0\n ? Math.floor(input.partSize)\n : null;\n\n await runHook(config.multipart?.partGuard, {\n request,\n key,\n bucket,\n uploadId,\n partNumber,\n partSize: partSize ?? undefined,\n });\n\n const presignedUrl = await getSignedUrl(\n config.client,\n new UploadPartCommand({\n Bucket: bucket,\n Key: key,\n UploadId: uploadId,\n PartNumber: partNumber,\n ...(partSize !== null ? { ContentLength: partSize } : {}),\n }),\n {\n expiresIn,\n ...(partSize !== null\n ? { signableHeaders: new Set([\"content-length\"]) }\n : {}),\n },\n );\n\n return {\n presignedUrl,\n partNumber,\n uploadId,\n bucket,\n expiresIn,\n ...(partSize !== null ? { partSize } : {}),\n };\n}\n\nexport const multipartPart = createS3Endpoint(\n S3_API_ROUTES.multipartPart,\n { method: \"POST\", body: multipartSignPartBodySchema },\n async (ctx) => {\n assertFeatureEnabled(ctx.context.config, \"multipart\");\n return handleSignPart(ctx.context.config, ctx.body, ctx.context.request);\n },\n);\n","import { createPresignedPost } from \"@aws-sdk/s3-presigned-post\";\nimport { getSignedUrl } from \"@aws-sdk/s3-request-presigner\";\nimport { PutObjectCommand } from \"@aws-sdk/client-s3\";\nimport {\n buildContentDisposition,\n S3_API_ROUTES,\n uploadBodySchema,\n type UploadPresignResponse,\n} from \"@dimah-s3/core\";\nimport { errors } from \"../../errors\";\nimport {\n normalizeExpiresIn,\n runHook,\n runLifecycleHook,\n} from \"../../internal-helpers\";\nimport type { ResolvedDimahS3Config } from \"../../types\";\nimport { resolveRequestTarget } from \"../../helpers/resolve-target\";\nimport { assertFeatureEnabled } from \"../assert-feature-enabled\";\nimport { createS3Endpoint } from \"../create-s3-endpoint\";\n\nasync function handleUpload(\n config: ResolvedDimahS3Config,\n input: typeof uploadBodySchema._output,\n request: Request,\n): Promise<UploadPresignResponse> {\n const { key, bucket } = await resolveRequestTarget(config, config.upload, {\n request,\n key: input.key,\n bucket: input.bucket,\n fileName: input.fileName,\n contentType: input.contentType,\n });\n const expiresIn = normalizeExpiresIn(input.expiresIn);\n const acl = input.acl === \"public-read\" ? \"public-read\" : \"private\";\n const contentType = input.contentType ?? \"application/octet-stream\";\n const fileSize =\n typeof input.fileSize === \"number\" && input.fileSize > 0\n ? Math.floor(input.fileSize)\n : null;\n\n await runHook(config.upload?.guard, {\n request,\n key,\n bucket,\n contentType: input.contentType,\n fileSize: fileSize ?? undefined,\n metadata: input.metadata,\n acl,\n fileName: input.fileName,\n });\n\n const method = config.upload?.method ?? \"POST\";\n\n if (method === \"PUT\" && config.upload?.requireFileSize && fileSize === null) {\n throw errors.fileSizeRequiredUpload();\n }\n\n if (method === \"PUT\") {\n const putHeaders: Record<string, string> = {\n \"Content-Type\": contentType,\n };\n if (input.fileName) {\n putHeaders[\"Content-Disposition\"] = buildContentDisposition(\n input.fileName,\n );\n }\n\n const url = await getSignedUrl(\n config.client,\n new PutObjectCommand({\n Bucket: bucket,\n Key: key,\n ContentType: contentType,\n ACL: acl,\n ...(input.fileName\n ? { ContentDisposition: buildContentDisposition(input.fileName) }\n : {}),\n ...(fileSize !== null ? { ContentLength: fileSize } : {}),\n }),\n {\n expiresIn,\n ...(fileSize !== null\n ? { signableHeaders: new Set([\"content-length\"]) }\n : {}),\n },\n );\n\n await runLifecycleHook(config.upload?.onPresigned, {\n request,\n key,\n bucket,\n contentType: input.contentType,\n fileSize: fileSize ?? undefined,\n metadata: input.metadata,\n acl,\n fileName: input.fileName,\n url,\n expiresIn,\n });\n\n return {\n bucket,\n key,\n url,\n headers: putHeaders,\n expiresIn,\n method: \"PUT\",\n };\n }\n\n const fields: Record<string, string> = { acl, \"Content-Type\": contentType };\n\n if (input.fileName) {\n fields[\"Content-Disposition\"] = buildContentDisposition(input.fileName);\n }\n\n if (input.metadata) {\n for (const [k, v] of Object.entries(input.metadata)) {\n fields[`x-amz-meta-${k}`] = v;\n }\n }\n\n const rangeMin = fileSize ?? 1;\n const rangeMax = fileSize ?? undefined;\n\n const { url, fields: signedFields } = await createPresignedPost(\n config.client,\n {\n Bucket: bucket,\n Key: key,\n Conditions:\n rangeMax !== undefined\n ? [[\"content-length-range\", rangeMin, rangeMax]]\n : [[\"content-length-range\", rangeMin, Number.MAX_SAFE_INTEGER]],\n Fields: fields,\n Expires: expiresIn,\n },\n );\n\n await runLifecycleHook(config.upload?.onPresigned, {\n request,\n key,\n bucket,\n contentType: input.contentType,\n fileSize: fileSize ?? undefined,\n metadata: input.metadata,\n acl,\n fileName: input.fileName,\n url,\n expiresIn,\n });\n\n return {\n bucket,\n key,\n url,\n fields: signedFields,\n expiresIn,\n method: \"POST\",\n };\n}\n\nexport const upload = createS3Endpoint(\n S3_API_ROUTES.upload,\n { method: \"POST\", body: uploadBodySchema },\n async (ctx) => {\n assertFeatureEnabled(ctx.context.config, \"upload\");\n return handleUpload(ctx.context.config, ctx.body, ctx.context.request);\n },\n);\n","import { confirm } from \"./confirm\";\nimport { deleteObject } from \"./delete\";\nimport { download } from \"./download\";\nimport { multipartAbort } from \"./multipart/abort\";\nimport { multipartComplete } from \"./multipart/complete\";\nimport { multipartInit } from \"./multipart/init\";\nimport { multipartListParts } from \"./multipart/list-parts\";\nimport { multipartPart } from \"./multipart/part\";\nimport { upload } from \"./upload\";\n\n/** Core better-call endpoints — keys become `s3.api.*`. */\nexport const coreEndpoints = {\n upload,\n confirm,\n download,\n delete: deleteObject,\n multipartInit,\n multipartPart,\n multipartListParts,\n multipartComplete,\n multipartAbort,\n};\n\nexport type CoreEndpoints = typeof coreEndpoints;\n\nexport const CORE_ENDPOINT_NAMES = Object.keys(\n coreEndpoints,\n) as (keyof CoreEndpoints)[];\n"]}
@@ -0,0 +1,14 @@
1
+ import { type UploadConfirmResponse } from "@dimah-s3/core";
2
+ export declare const confirm: import("better-call").StrictEndpoint<"/presign/upload/confirm", {
3
+ use: import("better-call").MiddlewareHandler[];
4
+ } & {
5
+ method: "POST";
6
+ body: import("better-call").StandardSchemaV1<{
7
+ key: string;
8
+ bucket?: string | undefined;
9
+ }, {
10
+ key: string;
11
+ bucket?: string | undefined;
12
+ }>;
13
+ }, UploadConfirmResponse>;
14
+ //# sourceMappingURL=confirm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm.d.ts","sourceRoot":"","sources":["../../../src/api/routes/confirm.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AAgExB,eAAO,MAAM,OAAO;;;;;;;;;;;yBAOnB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type DeleteResponse } from "@dimah-s3/core";
2
+ export declare const deleteObject: import("better-call").StrictEndpoint<"/delete", {
3
+ use: import("better-call").MiddlewareHandler[];
4
+ } & {
5
+ method: "DELETE";
6
+ body: import("better-call").StandardSchemaV1<unknown, unknown>;
7
+ } & {
8
+ query: import("better-call").StandardSchemaV1<{
9
+ key: string;
10
+ bucket?: string | undefined;
11
+ }, {
12
+ key: string;
13
+ bucket?: string | undefined;
14
+ }>;
15
+ }, DeleteResponse>;
16
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/api/routes/delete.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AA8CxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;kBAOxB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { type PresignResponse } from "@dimah-s3/core";
2
+ export declare const download: import("better-call").StrictEndpoint<"/presign/download", {
3
+ use: import("better-call").MiddlewareHandler[];
4
+ } & {
5
+ method: "GET";
6
+ } & {
7
+ query: import("better-call").StandardSchemaV1<{
8
+ key: string;
9
+ bucket?: string | undefined;
10
+ fileName?: string | undefined;
11
+ expiresIn?: unknown;
12
+ }, {
13
+ key: string;
14
+ bucket?: string | undefined;
15
+ fileName?: string | undefined;
16
+ expiresIn?: unknown;
17
+ }>;
18
+ }, PresignResponse>;
19
+ //# sourceMappingURL=download.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../../src/api/routes/download.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAqExB,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;mBAOpB,CAAC"}
@@ -0,0 +1,170 @@
1
+ /** Core better-call endpoints — keys become `s3.api.*`. */
2
+ export declare const coreEndpoints: {
3
+ upload: import("better-call").StrictEndpoint<"/presign/upload", {
4
+ use: import("better-call").MiddlewareHandler[];
5
+ } & {
6
+ method: "POST";
7
+ body: import("better-call").StandardSchemaV1<{
8
+ key: string;
9
+ contentType?: string | undefined;
10
+ fileSize?: number | undefined;
11
+ metadata?: Record<string, string> | undefined;
12
+ bucket?: string | undefined;
13
+ expiresIn?: number | undefined;
14
+ acl?: "private" | "public-read" | undefined;
15
+ fileName?: string | undefined;
16
+ }, {
17
+ key: string;
18
+ contentType?: string | undefined;
19
+ fileSize?: number | undefined;
20
+ metadata?: Record<string, string> | undefined;
21
+ bucket?: string | undefined;
22
+ expiresIn?: number | undefined;
23
+ acl?: "private" | "public-read" | undefined;
24
+ fileName?: string | undefined;
25
+ }>;
26
+ }, import("@dimah-s3/core").UploadPresignResponse>;
27
+ confirm: import("better-call").StrictEndpoint<"/presign/upload/confirm", {
28
+ use: import("better-call").MiddlewareHandler[];
29
+ } & {
30
+ method: "POST";
31
+ body: import("better-call").StandardSchemaV1<{
32
+ key: string;
33
+ bucket?: string | undefined;
34
+ }, {
35
+ key: string;
36
+ bucket?: string | undefined;
37
+ }>;
38
+ }, import("@dimah-s3/core").UploadConfirmResponse>;
39
+ download: import("better-call").StrictEndpoint<"/presign/download", {
40
+ use: import("better-call").MiddlewareHandler[];
41
+ } & {
42
+ method: "GET";
43
+ } & {
44
+ query: import("better-call").StandardSchemaV1<{
45
+ key: string;
46
+ bucket?: string | undefined;
47
+ fileName?: string | undefined;
48
+ expiresIn?: unknown;
49
+ }, {
50
+ key: string;
51
+ bucket?: string | undefined;
52
+ fileName?: string | undefined;
53
+ expiresIn?: unknown;
54
+ }>;
55
+ }, import("@dimah-s3/core").PresignResponse>;
56
+ delete: import("better-call").StrictEndpoint<"/delete", {
57
+ use: import("better-call").MiddlewareHandler[];
58
+ } & {
59
+ method: "DELETE";
60
+ body: import("better-call").StandardSchemaV1<unknown, unknown>;
61
+ } & {
62
+ query: import("better-call").StandardSchemaV1<{
63
+ key: string;
64
+ bucket?: string | undefined;
65
+ }, {
66
+ key: string;
67
+ bucket?: string | undefined;
68
+ }>;
69
+ }, import("@dimah-s3/core").DeleteResponse>;
70
+ multipartInit: import("better-call").StrictEndpoint<"/presign/multipart/init", {
71
+ use: import("better-call").MiddlewareHandler[];
72
+ } & {
73
+ method: "POST";
74
+ body: import("better-call").StandardSchemaV1<{
75
+ key: string;
76
+ contentType?: string | undefined;
77
+ fileSize?: number | undefined;
78
+ metadata?: Record<string, string> | undefined;
79
+ bucket?: string | undefined;
80
+ expiresIn?: number | undefined;
81
+ acl?: "private" | "public-read" | undefined;
82
+ fileName?: string | undefined;
83
+ }, {
84
+ key: string;
85
+ contentType?: string | undefined;
86
+ fileSize?: number | undefined;
87
+ metadata?: Record<string, string> | undefined;
88
+ bucket?: string | undefined;
89
+ expiresIn?: number | undefined;
90
+ acl?: "private" | "public-read" | undefined;
91
+ fileName?: string | undefined;
92
+ }>;
93
+ }, import("@dimah-s3/core").MultipartInitResponse>;
94
+ multipartPart: import("better-call").StrictEndpoint<"/presign/multipart/part", {
95
+ use: import("better-call").MiddlewareHandler[];
96
+ } & {
97
+ method: "POST";
98
+ body: import("better-call").StandardSchemaV1<{
99
+ key: string;
100
+ uploadId: string;
101
+ partNumber: number;
102
+ partSize?: number | undefined;
103
+ bucket?: string | undefined;
104
+ expiresIn?: number | undefined;
105
+ }, {
106
+ key: string;
107
+ uploadId: string;
108
+ partNumber: number;
109
+ partSize?: number | undefined;
110
+ bucket?: string | undefined;
111
+ expiresIn?: number | undefined;
112
+ }>;
113
+ }, import("@dimah-s3/core").MultipartPartResponse>;
114
+ multipartListParts: import("better-call").StrictEndpoint<"/presign/multipart/parts", {
115
+ use: import("better-call").MiddlewareHandler[];
116
+ } & {
117
+ method: "GET";
118
+ } & {
119
+ query: import("better-call").StandardSchemaV1<{
120
+ key: string;
121
+ uploadId: string;
122
+ bucket?: string | undefined;
123
+ }, {
124
+ key: string;
125
+ uploadId: string;
126
+ bucket?: string | undefined;
127
+ }>;
128
+ }, import("@dimah-s3/core").MultipartListPartsResponse>;
129
+ multipartComplete: import("better-call").StrictEndpoint<"/presign/multipart/complete", {
130
+ use: import("better-call").MiddlewareHandler[];
131
+ } & {
132
+ method: "POST";
133
+ body: import("better-call").StandardSchemaV1<{
134
+ key: string;
135
+ uploadId: string;
136
+ parts: {
137
+ partNumber: number;
138
+ }[];
139
+ bucket?: string | undefined;
140
+ }, {
141
+ key: string;
142
+ uploadId: string;
143
+ parts: {
144
+ partNumber: number;
145
+ }[];
146
+ bucket?: string | undefined;
147
+ }>;
148
+ }, import("@dimah-s3/core").MultipartCompleteResponse>;
149
+ multipartAbort: import("better-call").StrictEndpoint<"/presign/multipart/abort", {
150
+ use: import("better-call").MiddlewareHandler[];
151
+ } & {
152
+ method: "POST";
153
+ body: import("better-call").StandardSchemaV1<{
154
+ key: string;
155
+ uploadId: string;
156
+ bucket?: string | undefined;
157
+ }, {
158
+ key: string;
159
+ uploadId: string;
160
+ bucket?: string | undefined;
161
+ }>;
162
+ }, import("@dimah-s3/core").MultipartAbortResponse & {
163
+ bucket: string;
164
+ key: string;
165
+ uploadId: string;
166
+ }>;
167
+ };
168
+ export type CoreEndpoints = typeof coreEndpoints;
169
+ export declare const CORE_ENDPOINT_NAMES: (keyof CoreEndpoints)[];
170
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/routes/index.ts"],"names":[],"mappings":"AAUA,2DAA2D;AAC3D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAUzB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC;AAEjD,eAAO,MAAM,mBAAmB,EAE3B,CAAC,MAAM,aAAa,CAAC,EAAE,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type MultipartAbortResponse } from "@dimah-s3/core";
2
+ export declare const multipartAbort: import("better-call").StrictEndpoint<"/presign/multipart/abort", {
3
+ use: import("better-call").MiddlewareHandler[];
4
+ } & {
5
+ method: "POST";
6
+ body: import("better-call").StandardSchemaV1<{
7
+ key: string;
8
+ uploadId: string;
9
+ bucket?: string | undefined;
10
+ }, {
11
+ key: string;
12
+ uploadId: string;
13
+ bucket?: string | undefined;
14
+ }>;
15
+ }, MultipartAbortResponse & {
16
+ bucket: string;
17
+ key: string;
18
+ uploadId: string;
19
+ }>;
20
+ //# sourceMappingURL=abort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abort.d.ts","sourceRoot":"","sources":["../../../../src/api/routes/multipart/abort.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,gBAAgB,CAAC;AA8CxB,eAAO,MAAM,cAAc;;;;;;;;;;;;;;YAlCU,MAAM;SAAO,MAAM;cAAY,MAAM;EAyCzE,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { type MultipartCompleteResponse } from "@dimah-s3/core";
2
+ export declare const multipartComplete: import("better-call").StrictEndpoint<"/presign/multipart/complete", {
3
+ use: import("better-call").MiddlewareHandler[];
4
+ } & {
5
+ method: "POST";
6
+ body: import("better-call").StandardSchemaV1<{
7
+ key: string;
8
+ uploadId: string;
9
+ parts: {
10
+ partNumber: number;
11
+ }[];
12
+ bucket?: string | undefined;
13
+ }, {
14
+ key: string;
15
+ uploadId: string;
16
+ parts: {
17
+ partNumber: number;
18
+ }[];
19
+ bucket?: string | undefined;
20
+ }>;
21
+ }, MultipartCompleteResponse>;
22
+ //# sourceMappingURL=complete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../../../src/api/routes/multipart/complete.ts"],"names":[],"mappings":"AAKA,OAAO,EAIL,KAAK,yBAAyB,EAC/B,MAAM,gBAAgB,CAAC;AAsGxB,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;6BAO7B,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { type MultipartInitResponse } from "@dimah-s3/core";
2
+ export declare const multipartInit: import("better-call").StrictEndpoint<"/presign/multipart/init", {
3
+ use: import("better-call").MiddlewareHandler[];
4
+ } & {
5
+ method: "POST";
6
+ body: import("better-call").StandardSchemaV1<{
7
+ key: string;
8
+ contentType?: string | undefined;
9
+ fileSize?: number | undefined;
10
+ metadata?: Record<string, string> | undefined;
11
+ bucket?: string | undefined;
12
+ expiresIn?: number | undefined;
13
+ acl?: "private" | "public-read" | undefined;
14
+ fileName?: string | undefined;
15
+ }, {
16
+ key: string;
17
+ contentType?: string | undefined;
18
+ fileSize?: number | undefined;
19
+ metadata?: Record<string, string> | undefined;
20
+ bucket?: string | undefined;
21
+ expiresIn?: number | undefined;
22
+ acl?: "private" | "public-read" | undefined;
23
+ fileName?: string | undefined;
24
+ }>;
25
+ }, MultipartInitResponse>;
26
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../src/api/routes/multipart/init.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AAiExB,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;yBAYzB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type MultipartListPartsResponse } from "@dimah-s3/core";
2
+ export declare const multipartListParts: import("better-call").StrictEndpoint<"/presign/multipart/parts", {
3
+ use: import("better-call").MiddlewareHandler[];
4
+ } & {
5
+ method: "GET";
6
+ } & {
7
+ query: import("better-call").StandardSchemaV1<{
8
+ key: string;
9
+ uploadId: string;
10
+ bucket?: string | undefined;
11
+ }, {
12
+ key: string;
13
+ uploadId: string;
14
+ bucket?: string | undefined;
15
+ }>;
16
+ }, MultipartListPartsResponse>;
17
+ //# sourceMappingURL=list-parts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-parts.d.ts","sourceRoot":"","sources":["../../../../src/api/routes/multipart/list-parts.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,0BAA0B,EAChC,MAAM,gBAAgB,CAAC;AAmDxB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;8BAO9B,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { type MultipartPartResponse } from "@dimah-s3/core";
2
+ export declare const multipartPart: import("better-call").StrictEndpoint<"/presign/multipart/part", {
3
+ use: import("better-call").MiddlewareHandler[];
4
+ } & {
5
+ method: "POST";
6
+ body: import("better-call").StandardSchemaV1<{
7
+ key: string;
8
+ uploadId: string;
9
+ partNumber: number;
10
+ partSize?: number | undefined;
11
+ bucket?: string | undefined;
12
+ expiresIn?: number | undefined;
13
+ }, {
14
+ key: string;
15
+ uploadId: string;
16
+ partNumber: number;
17
+ partSize?: number | undefined;
18
+ bucket?: string | undefined;
19
+ expiresIn?: number | undefined;
20
+ }>;
21
+ }, MultipartPartResponse>;
22
+ //# sourceMappingURL=part.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"part.d.ts","sourceRoot":"","sources":["../../../../src/api/routes/multipart/part.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AA6DxB,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;yBAOzB,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { type UploadPresignResponse } from "@dimah-s3/core";
2
+ export declare const upload: import("better-call").StrictEndpoint<"/presign/upload", {
3
+ use: import("better-call").MiddlewareHandler[];
4
+ } & {
5
+ method: "POST";
6
+ body: import("better-call").StandardSchemaV1<{
7
+ key: string;
8
+ contentType?: string | undefined;
9
+ fileSize?: number | undefined;
10
+ metadata?: Record<string, string> | undefined;
11
+ bucket?: string | undefined;
12
+ expiresIn?: number | undefined;
13
+ acl?: "private" | "public-read" | undefined;
14
+ fileName?: string | undefined;
15
+ }, {
16
+ key: string;
17
+ contentType?: string | undefined;
18
+ fileSize?: number | undefined;
19
+ metadata?: Record<string, string> | undefined;
20
+ bucket?: string | undefined;
21
+ expiresIn?: number | undefined;
22
+ acl?: "private" | "public-read" | undefined;
23
+ fileName?: string | undefined;
24
+ }>;
25
+ }, UploadPresignResponse>;
26
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/api/routes/upload.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AA0JxB,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;yBAOlB,CAAC"}
@@ -1,15 +1,43 @@
1
- import type { S3Api } from "@dimah-s3/core";
2
- import { type DimahS3Plugin, type PluginContextMap } from "./plugin";
1
+ import { S3_ERROR_CODES } from "@dimah-s3/core";
2
+ import { type DimahS3Plugin, type PluginContextMap, type PluginEndpointMap } from "./plugin";
3
+ import { type CoreEndpoints } from "./api/routes";
3
4
  import type { DimahS3Config } from "./types";
4
- export type DimahS3<C extends Record<string, unknown> = Record<string, unknown>> = {
5
+ export type MultipartAliasApi = {
6
+ init: CoreEndpoints["multipartInit"];
7
+ signPart: CoreEndpoints["multipartPart"];
8
+ listParts: CoreEndpoints["multipartListParts"];
9
+ complete: CoreEndpoints["multipartComplete"];
10
+ abort: CoreEndpoints["multipartAbort"];
11
+ };
12
+ export type DimahS3Api<P extends readonly DimahS3Plugin[] = []> = CoreEndpoints & {
13
+ multipart: MultipartAliasApi;
14
+ } & PluginEndpointMap<P>;
15
+ export type DimahS3<P extends readonly DimahS3Plugin[] = [], C extends Record<string, unknown> = PluginContextMap<P>> = {
5
16
  /** Framework-agnostic HTTP handler (`Request` → `Response`). */
6
17
  handler: (request: Request) => Promise<Response>;
7
- /** Same `S3Api` as the browser client — call from Server Actions / RSC without HTTP. */
8
- api: S3Api;
18
+ /**
19
+ * better-call endpoints — invoke as functions from Server Actions / RSC.
20
+ *
21
+ * ```ts
22
+ * await s3.api.download({ query: { key }, headers: await headers() });
23
+ * await s3.api.multipart.init({ body: { key } });
24
+ * ```
25
+ */
26
+ api: DimahS3Api<P>;
9
27
  /** Plugin contexts keyed by plugin id. */
10
28
  context: C;
11
29
  /** Lookup a registered plugin by id. */
12
- getPlugin: (id: string) => DimahS3Plugin | undefined;
30
+ getPlugin: {
31
+ <Id extends P[number]["id"]>(id: Id): Extract<P[number], {
32
+ id: Id;
33
+ }> | undefined;
34
+ (id: string): DimahS3Plugin | undefined;
35
+ };
36
+ $ERROR_CODES: typeof S3_ERROR_CODES;
37
+ $Infer: {
38
+ api: DimahS3Api<P>;
39
+ context: C;
40
+ };
13
41
  } & C;
14
42
  /**
15
43
  * Create a dimah-s3 server instance.
@@ -19,18 +47,19 @@ export type DimahS3<C extends Record<string, unknown> = Record<string, unknown>>
19
47
  *
20
48
  * @example
21
49
  * ```ts
50
+ * export const awsS3 = new S3Client({ ... });
22
51
  * export const s3 = dimahS3({
23
- * s3: s3Client,
24
- * defaultBucket: "my-bucket",
25
- * upload: { enabled: true },
52
+ * client: awsS3,
53
+ * bucket: "my-bucket",
54
+ * upload: true,
26
55
  * });
27
56
  *
28
- * export const { GET, POST, DELETE } = toNextJsHandler(s3);
57
+ * export const { GET, POST, PUT, PATCH, DELETE } = toNextJsHandler(s3);
29
58
  *
30
- * await s3.api.download(key, { headers: await headers() });
59
+ * await s3.api.download({ query: { key }, headers: await headers() });
31
60
  * ```
32
61
  */
33
62
  export declare function dimahS3<const P extends readonly DimahS3Plugin[] = []>(config: DimahS3Config & {
34
63
  plugins?: P;
35
- }): DimahS3<PluginContextMap<P>>;
64
+ }): DimahS3<P>;
36
65
  //# sourceMappingURL=dimah-s3.d.ts.map