X Enterprises
fastify-xstorage

copy / move

Copy a file to a new key within the bucket, or move it (copy then delete the source).

copy / move

Copy a file to a new key within the same bucket, or move it (copy followed by delete of the source). Both return { key, url } for the destination.

Signatures

fastify.xStorage.copy(
  sourceKey: string,
  destinationKey: string,
  options?: { acl?: string }
): Promise<{ key: string; url: string }>

fastify.xStorage.move(
  sourceKey: string,
  destinationKey: string,
  options?: { acl?: string }
): Promise<{ key: string; url: string }>

Params

NameTypeRequiredDescription
sourceKeystringYesKey of the existing file to copy or move.
destinationKeystringYesKey for the destination file.
options.aclstringNoACL for the destination file. Falls back to plugin-level acl.

Returns

FieldTypeDescription
keystringThe destination key.
urlstringFull public URL for the destination file.

Throws

  • [xStorage] sourceKey is required and must be a string — if sourceKey is missing.
  • [xStorage] destinationKey is required and must be a string — if destinationKey is missing.
  • [xStorage] Failed to copy "<sourceKey>" to "<destinationKey>": <message> — if the S3 CopyObject fails.
  • Any error from delete() will propagate from move() if the copy succeeds but the source delete fails.

Examples

copy — duplicate a file to a new location

const result = await fastify.xStorage.copy(
  "templates/contract-v1.pdf",
  "contracts/user-123-contract.pdf"
);

console.log(result.url); // https://cdn.example.com/contracts/user-123-contract.pdf

move — rename/relocate a file

const result = await fastify.xStorage.move(
  "temp/upload-abc123.jpg",
  "avatars/user-456.jpg",
  { acl: "public-read" }
);

console.log(result.key); // avatars/user-456.jpg

Realistic — promote a temporary upload to permanent storage

fastify.post("/profile/avatar", async (request, reply) => {
  // Client already uploaded to temp/ via getSignedUploadUrl
  const { tempKey } = request.body;

  if (!tempKey.startsWith("temp/")) {
    return reply.code(400).send({ error: "Invalid temp key" });
  }

  const permanentKey = `avatars/${request.user.id}.jpg`;

  const result = await fastify.xStorage.move(tempKey, permanentKey, {
    acl: "public-read",
  });

  await db.users.update(request.user.id, { avatarUrl: result.url });

  return reply.send({ avatarUrl: result.url });
});

See also

AI Context

package: "@xenterprises/fastify-xstorage"
methods: fastify.xStorage.copy(sourceKey, destinationKey, options?) | fastify.xStorage.move(sourceKey, destinationKey, options?)
use-when: Copy or move files within the same S3 bucket — move() is copy-then-delete
returns: { key, url, contentType, bucket }
Copyright © 2026