Skip to content

feat: add file and folder duplicate/copy operation#152

Merged
G4brym merged 1 commit intomainfrom
feature/duplicate-copy-operation
Mar 10, 2026
Merged

feat: add file and folder duplicate/copy operation#152
G4brym merged 1 commit intomainfrom
feature/duplicate-copy-operation

Conversation

@G4brym
Copy link
Copy Markdown
Owner

@G4brym G4brym commented Mar 10, 2026

Summary

  • Adds a "Duplicate" option to the file/folder context menu that creates a copy with a " (copy)" suffix, preserving all metadata
  • New CopyObject backend endpoint (POST /api/buckets/:bucket/copy) that gets the source object and puts it at the destination without deleting the original
  • Frontend handles both single file duplication (instant) and folder duplication (iterates contents with progress indicator)

Related Issue

Prodboard issue: bcb8905b3911e595 — [I] [R2-Explorer] Add file and folder duplicate/copy operation

Changes

  • New file: packages/worker/src/modules/buckets/copyObject.ts — CopyObject endpoint following MoveObject pattern (without delete)
  • Modified: packages/worker/src/index.ts — Register /api/buckets/:bucket/copy route
  • Modified: packages/dashboard/src/appUtils.js — Add copyObject API handler method
  • Modified: packages/dashboard/src/pages/files/FileContextMenu.vue — Add "Duplicate" menu item
  • Modified: packages/dashboard/src/components/files/FileOptions.vue — Add duplicateObject and generateCopyName methods
  • Modified: packages/dashboard/src/pages/files/FilesFolderPage.vue — Wire up duplicateObject event
  • New file: packages/worker/tests/integration/copy.test.ts — 6 backend integration tests
  • Modified: packages/dashboard/e2e/file-operations.spec.ts — E2E test for file duplication via context menu

Test Plan

  • All 88 worker integration tests pass (including 6 new copy tests)
  • All 110 dashboard component tests pass
  • Lint passes cleanly
  • E2E tests for file duplication via context menu
  • Manual test: right-click file → Duplicate → verify copy appears with " (copy)" suffix
  • Manual test: right-click folder → Duplicate → verify folder and contents are copied
  • Verify readonly mode blocks the copy endpoint (POST is blocked by readonly middleware)

🤖 Generated with Claude Code

Add a "Duplicate" context menu option that copies files and folders within
the same bucket, appending " (copy)" to the name while preserving all metadata.

- New CopyObject backend endpoint (POST /api/buckets/:bucket/copy)
- Frontend duplicate logic with progress tracking for folder duplication
- Backend integration tests (6 tests) and E2E test for file duplication

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
r2-explorer-docs 8b6656a Commit Preview URL

Branch Preview URL
Mar 10 2026, 12:06 AM

Copy link
Copy Markdown
Owner Author

@G4brym G4brym left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review — APPROVED ✅

Review Scores: 5/5 reviewers approved
CI Status: All checks passed ✅

Summary

Clean, well-implemented feature that adds file/folder duplication to R2-Explorer. The implementation closely follows established codebase patterns (mirrors MoveObject endpoint and folder delete iteration). Backend endpoint correctly implements copy semantics (get + put without delete), preserving all metadata. Frontend adds context menu integration with progress feedback for folder operations. Test coverage is solid with 6 backend integration tests and an E2E test.

Review Perspectives

  1. Correctness: ✅ Copy semantics correct (no source deletion), name generation handles files/folders/extensions properly, events wired correctly through component hierarchy
  2. Security: ✅ Follows existing auth/middleware patterns, POST blocked by readonly middleware, no injection surfaces, base64 encoding matches existing patterns
  3. Performance: ✅ Single-file copy streams via R2 get/put (no memory buffering), folder copy matches existing sequential pattern
  4. Code Quality: ✅ Mirrors existing codebase patterns closely, clean and readable, well-structured
  5. Testing: ✅ 6 backend integration tests covering happy path, metadata preservation, error cases, and source integrity; E2E test covers primary user flow

Minor Notes (non-blocking)

  • Number.parseInt((i * 100) / folderContents.length) works but Math.floor() would be semantically more appropriate for truncating a number
  • generateCopyName uses arrow function syntax while sibling methods use function() — inconsistent but harmless since it doesn't reference this
  • Silent overwrite if filename (copy).ext already exists is a documented, acceptable trade-off for MVP

🤖 Automated review by prodboard

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant