X Enterprises
fastify-xstorage

getSignedUrl / getSignedUploadUrl / getPublicUrl

Generate temporary signed download URLs, presigned direct-upload URLs, or compute a synchronous public URL.

getSignedUrl / getSignedUploadUrl / getPublicUrl

Three URL helpers covering the full access spectrum:

  • getSignedUrl — temporary pre-signed GetObject URL for private file downloads.
  • getSignedUploadUrl — temporary pre-signed PutObject URL so clients upload directly to storage without routing through your server.
  • getPublicUrl — synchronous helper that builds the public URL by concatenating publicUrl + key.

Signatures

fastify.xStorage.getSignedUrl(
  key: string,
  expiresIn?: number,   // seconds, default 3600
): Promise<string>

fastify.xStorage.getSignedUploadUrl(
  key: string,
  options?: SignedUploadOptions,
): Promise<SignedUploadResult>

fastify.xStorage.getPublicUrl(key: string): string  // synchronous

interface SignedUploadOptions {
  contentType?: string   // default "application/octet-stream"
  expiresIn?: number     // seconds, default 3600
  metadata?: Record<string, string>
}

interface SignedUploadResult {
  uploadUrl: string   // client PUTs to this URL
  key: string
  publicUrl: string   // final public URL once upload completes
}

Params

getSignedUrl

NameTypeRequiredDescription
keystringYesStorage key of the file
expiresInnumberNoExpiry in seconds (default 3600)

getSignedUploadUrl

NameTypeRequiredDescription
keystringYesDestination storage key for the upload
options.contentTypestringNoExpected MIME type (default "application/octet-stream")
options.expiresInnumberNoExpiry in seconds (default 3600)
options.metadataobjectNoCustom S3 metadata to attach on upload

getPublicUrl

NameTypeRequiredDescription
keystringYesStorage key to build URL for

Returns

  • getSignedUrlPromise<string> — signed download URL.
  • getSignedUploadUrlPromise<SignedUploadResult>{ uploadUrl, key, publicUrl }.
  • getPublicUrlstring — synchronous, no async.

Throws

ErrorWhen
[xStorage] key is required and must be a stringAny key arg missing or not a string
[xStorage] expiresIn must be a positive number (seconds)expiresIn ≤ 0 or not a number
[xStorage] Failed to generate signed URL for "<key>": <reason>Pre-signer error on download URL
[xStorage] Failed to generate signed upload URL for "<key>": <reason>Pre-signer error on upload URL

Examples

fastify.get("/documents/:id/download", { onRequest: [fastify.authenticate] }, async (request, reply) => {
  const doc = await fastify.prisma.document.findUnique({
    where: { id: request.params.id },
  });

  // 15-minute expiry
  const url = await fastify.xStorage.getSignedUrl(doc.storageKey, 900);

  return reply.redirect(url);
});

Client-side direct upload flow

// 1. Server: issue a presigned upload URL
fastify.post("/upload-token", async (request, reply) => {
  const { filename, contentType } = request.body;
  const key = `uploads/${request.user.id}/${Date.now()}-${filename}`;

  const { uploadUrl, publicUrl } = await fastify.xStorage.getSignedUploadUrl(key, {
    contentType,
    expiresIn: 300, // 5 minutes
  });

  return { uploadUrl, publicUrl, key };
});

// 2. Client: PUT directly to uploadUrl with the file body
// fetch(uploadUrl, { method: "PUT", body: file, headers: { "Content-Type": contentType } })

// 3. Server: confirm key is now accessible
fastify.post("/upload-confirm", async (request, reply) => {
  const { key } = request.body;
  const exists = await fastify.xStorage.exists(key);
  if (!exists) return reply.code(400).send({ error: "Upload not found" });

  const url = fastify.xStorage.getPublicUrl(key);
  return { url };
});

See Also

AI Context

package: "@xenterprises/fastify-xstorage"
methods: fastify.xStorage.getSignedUrl(key, expiresIn?) | fastify.xStorage.getSignedUploadUrl(key, options?) | fastify.xStorage.getPublicUrl(key)
use-when: getSignedUrl — temporary download URL (default 1h) | getSignedUploadUrl — presigned PUT URL for direct client-to-S3 uploads | getPublicUrl — synchronous public URL construction (no API call)
returns: getSignedUrl/getSignedUploadUrl → Promise<string> | getPublicUrl → string
Copyright © 2026