Skip to content

fix(file-s3): preserve directory structure from filename in object key#16030

Closed
adem-loghmari wants to merge 1 commit into
medusajs:developfrom
adem-loghmari:fix/s3-preserve-filename-directory
Closed

fix(file-s3): preserve directory structure from filename in object key#16030
adem-loghmari wants to merge 1 commit into
medusajs:developfrom
adem-loghmari:fix/s3-preserve-filename-directory

Conversation

@adem-loghmari

Copy link
Copy Markdown
Contributor

What

Preserve any directory structure supplied in the filename when the S3 file provider generates an object key.

Closes #16008

Why

The provider parsed the incoming filename with path.parse but only used parsedFilename.name and parsedFilename.ext, dropping the directory portion. A filename like vendor_123/logo.png was flattened to logo-<ulid>.png, losing the caller-supplied structure.

How

Prepend parsedFilename.dir (with a trailing /) to the object key when present. Filenames without a directory are unaffected. Applied to both upload() and getUploadStream(), which shared the same logic.

Example:

Input filename Before After
vendor_123/logo.png logo-<ulid>.png vendor_123/logo-<ulid>.png
logo.png logo-<ulid>.png logo-<ulid>.png (unchanged)

Tests

Added unit tests covering directory preservation for both upload() and getUploadStream(), plus the no-directory case.

The S3 file provider parsed the incoming filename but only used
`parsedFilename.name` and `parsedFilename.ext`, so any directory
portion (e.g. "vendor_123/logo.png") was dropped from the generated
object key, flattening it to "logo-<ulid>.png".

Preserve `parsedFilename.dir` when present so a filename such as
"vendor_123/logo.png" yields "vendor_123/logo-<ulid>.png", while
filenames without a directory are unaffected. Applied to both
`upload()` and `getUploadStream()`.

Fixes medusajs#16008

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@adem-loghmari
adem-loghmari requested a review from a team as a code owner July 14, 2026 09:37
@changeset-bot

changeset-bot Bot commented Jul 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a5f269b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 80 packages
Name Type
@medusajs/file-s3 Patch
@medusajs/medusa Patch
@medusajs/test-utils Patch
@medusajs/loyalty-plugin Patch
@medusajs/medusa-oas-cli Patch
integration-tests-http Patch
@medusajs/analytics Patch
@medusajs/api-key Patch
@medusajs/auth Patch
@medusajs/caching Patch
@medusajs/cart Patch
@medusajs/currency Patch
@medusajs/customer Patch
@medusajs/file Patch
@medusajs/fulfillment Patch
@medusajs/index Patch
@medusajs/inventory Patch
@medusajs/link-modules Patch
@medusajs/locking Patch
@medusajs/notification Patch
@medusajs/order Patch
@medusajs/payment Patch
@medusajs/pricing Patch
@medusajs/product Patch
@medusajs/promotion Patch
@medusajs/rbac Patch
@medusajs/region Patch
@medusajs/sales-channel Patch
@medusajs/settings Patch
@medusajs/stock-location Patch
@medusajs/store Patch
@medusajs/tax Patch
@medusajs/translation Patch
@medusajs/user Patch
@medusajs/workflow-engine-inmemory Patch
@medusajs/workflow-engine-redis Patch
@medusajs/draft-order Patch
@medusajs/oas-github-ci Patch
@medusajs/cache-inmemory Patch
@medusajs/cache-redis Patch
@medusajs/event-bus-local Patch
@medusajs/event-bus-redis Patch
@medusajs/analytics-local Patch
@medusajs/analytics-posthog Patch
@medusajs/auth-emailpass Patch
@medusajs/auth-github Patch
@medusajs/auth-google Patch
@medusajs/caching-redis Patch
@medusajs/file-local Patch
@medusajs/fulfillment-manual Patch
@medusajs/locking-postgres Patch
@medusajs/locking-redis Patch
@medusajs/notification-local Patch
@medusajs/notification-sendgrid Patch
@medusajs/payment-stripe Patch
@medusajs/core-flows Patch
@medusajs/framework Patch
@medusajs/js-sdk Patch
@medusajs/modules-sdk Patch
@medusajs/orchestration Patch
@medusajs/query Patch
@medusajs/types Patch
@medusajs/utils Patch
@medusajs/workflows-sdk Patch
@medusajs/http-types-generator Patch
@medusajs/cli Patch
@medusajs/deps Patch
@medusajs/eslint-plugin Patch
@medusajs/telemetry Patch
@medusajs/admin-bundler Patch
@medusajs/admin-sdk Patch
@medusajs/admin-shared Patch
@medusajs/admin-vite-plugin Patch
@medusajs/dashboard Patch
@medusajs/icons Patch
@medusajs/toolbox Patch
@medusajs/ui-preset Patch
create-medusa-app Patch
medusa-dev-cli Patch
@medusajs/ui Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@medusa-os-bot

medusa-os-bot Bot commented Jul 14, 2026

Copy link
Copy Markdown

Thanks for the contribution! Initial automated review looks good.

Small, focused fix for accepted issue #16008 (type: bug / good first issue). Preserves directory structure from the supplied filename in the S3 object key, applied symmetrically to upload() and getUploadStream(); no-directory case is unchanged. PR template complete, changeset included, and unit tests cover both the directory and no-directory cases. Note for maintainers: the object key now includes caller-supplied directory segments — this is contained within the config prefix (S3 keys are literal, so '..' does not traverse), and only affects file-s3. Minor cosmetic edge: an absolute-path filen

Triggered by: new PR opened

@github-actions

Copy link
Copy Markdown
Contributor

Closing this PR because #16008 was fixed by #16010, which has now been merged. Thank you for your contribution! If you believe this PR is still needed, feel free to reopen it.

@github-actions github-actions Bot closed this Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Preserve directory structure from filename when generating S3 object key

1 participant