Repository: mastra-ai/mastra
File: workspaces/s3/src/filesystem/index.ts (TypeScript)

Code before:
/**
 * Get MIME type from file path extension.
 */
function getMimeType(path: string): string {
  const ext = path.toLowerCase().match(/\.[^.]+$/)?.[0];
  return ext ? (MIME_TYPES[ext] ?? 'application/octet-stream') : 'application/octet-stream';
}

/** Check if an error is a "not found" error from the S3 SDK. */
function isNotFoundError(error: unknown): boolean {
  if (!error || typeof error !== 'object' || !('name' in error)) return false;
  const name = (error as { name: string }).name;
  return name === 'NotFound' || name === 'NoSuchKey' || name === '404';
}

/** Check if an error is an access denied error from the S3 SDK. */
function isAccessDeniedError(error: unknown): boolean {
  if (!error || typeof error !== 'object') return false;
  const err = error as { name?: string; $metadata?: { httpStatusCode?: number } };
  return err.name === 'AccessDenied' || err.$metadata?.httpStatusCode === 403;
}

/**
 * S3 filesystem provider configuration.
 */
export interface S3FilesystemOptions extends Omit<MastraFilesystemOptions, 'name'> {
  /** Unique identifier for this filesystem instance */
  id?: string;
  /** S3 bucket name */
  bucket: string;
  /** Human-friendly display name for the UI */
  displayName?: string;
  /** Icon identifier for the UI (defaults to 's3') */
  icon?: FilesystemIcon;
  /** Description shown in tooltips */
  description?: string;
  /** AWS region (use 'auto' for R2) */
  region: string;
  /**
   * AWS access key ID.
   * Optional - omit for public buckets (read-only access).
   */
  accessKeyId?: string;
  /**
   * AWS secret access key.
   * Optional - omit for public buckets (read-only access).
   */
  secretAccessKey?: string;
  /**
   * Custom endpoint URL for S3-compatible storage.
   * Examples:

Review comment (suggestion):
```suggestion
export interface S3FilesystemOptions extends MastraFilesystemOptions {
```

Code after:
/**
 * Get MIME type from file path extension.
 */
function getMimeType(path: string): string {
  const ext = path.toLowerCase().match(/\.[^.]+$/)?.[0];
  return ext ? (MIME_TYPES[ext] ?? 'application/octet-stream') : 'application/octet-stream';
}

/** Check if an error is a "not found" error from the S3 SDK. */
function isNotFoundError(error: unknown): boolean {
  if (!error || typeof error !== 'object' || !('name' in error)) return false;
  const name = (error as { name: string }).name;
  return name === 'NotFound' || name === 'NoSuchKey' || name === '404';
}

/** Check if an error is an access denied error from the S3 SDK. */
function isAccessDeniedError(error: unknown): boolean {
  if (!error || typeof error !== 'object') return false;
  const err = error as { name?: string; $metadata?: { httpStatusCode?: number } };
  return err.name === 'AccessDenied' || err.$metadata?.httpStatusCode === 403;
}

/**
 * S3 filesystem provider configuration.
 */
export interface S3FilesystemOptions extends MastraFilesystemOptions {
  /** Unique identifier for this filesystem instance */
  id?: string;
  /** S3 bucket name */
  bucket: string;
  /** Human-friendly display name for the UI */
  displayName?: string;
  /** Icon identifier for the UI (defaults to 's3') */
  icon?: FilesystemIcon;
  /** Description shown in tooltips */
  description?: string;
  /** AWS region (use 'auto' for R2) */
  region: string;
  /**
   * AWS access key ID.
   * Optional - omit for public buckets (read-only access).
   */
  accessKeyId?: string;
  /**
   * AWS secret access key.
   * Optional - omit for public buckets (read-only access).
   */
  secretAccessKey?: string;
  /**
   * Custom endpoint URL for S3-compatible storage.
   * Examples: