import { S3Client, PutObjectCommand, DeleteObjectCommand, HeadObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { fa as StorageProvider } from '../nitro/nitro.mjs';
import 'node:crypto';
import 'jsonwebtoken';
import 'node:fs';
import 'node:module';
import 'node:path';
import 'node:url';
import 'node:http';
import 'node:https';
import 'node:events';
import 'node:buffer';
import 'pino';
import 'drizzle-orm/better-sqlite3';
import 'drizzle-orm/node-postgres';
import 'drizzle-orm/mysql2';
import 'better-sqlite3';
import 'pg';
import 'mysql2/promise';
import 'drizzle-orm';
import 'fs';
import 'path';
import 'prom-client';
import 'bcryptjs';
import '@node-rs/argon2';
import 'node:async_hooks';
import 'crypto';
import 'node:dns';
import 'node:util';
import 'node:net';
import 'fs/promises';
import 'url';
import 'semver';

var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
class S3StorageProvider extends StorageProvider {
  constructor(config) {
    var _a;
    super(config);
    __publicField(this, "client");
    __publicField(this, "bucket");
    __publicField(this, "publicUrl");
    __publicField(this, "defaultSignedUrlExpiry");
    if (!config.bucket) {
      throw new Error('S3 storage provider requires a "bucket" configuration');
    }
    if (!config.accessKeyId || !config.secretAccessKey) {
      throw new Error('S3 storage provider requires "accessKeyId" and "secretAccessKey"');
    }
    this.bucket = config.bucket;
    this.publicUrl = config.publicUrl;
    this.defaultSignedUrlExpiry = config.signedUrlExpiry || 3600;
    this.client = new S3Client({
      region: config.region || "us-east-1",
      endpoint: config.endpoint || void 0,
      credentials: {
        accessKeyId: config.accessKeyId,
        secretAccessKey: config.secretAccessKey
      },
      forcePathStyle: (_a = config.forcePathStyle) != null ? _a : false
    });
  }
  async upload(fileData, options) {
    const buffer = typeof fileData === "string" ? Buffer.from(fileData, "base64") : fileData;
    const mimeType = this.resolveUploadMimeType(options);
    this.validateFile(buffer.length, mimeType, options);
    const filename = options.filename ? this.sanitizeFilename(options.filename) : this.generateUniqueFilename("file");
    const folder = this.applyTenantPrefix(options);
    const key = folder ? `${folder.replace(/\\/g, "/")}/${filename}` : filename;
    await this.client.send(
      new PutObjectCommand({
        Bucket: this.bucket,
        Key: key,
        Body: buffer,
        ContentType: mimeType,
        ContentLength: buffer.length
      })
    );
    return {
      filename,
      originalName: options.filename || filename,
      mimeType,
      size: buffer.length,
      path: key,
      url: this.getUrl(key)
    };
  }
  async delete(options) {
    try {
      await this.client.send(
        new DeleteObjectCommand({
          Bucket: this.bucket,
          Key: options.path
        })
      );
    } catch {
    }
  }
  async exists(path) {
    try {
      await this.client.send(
        new HeadObjectCommand({
          Bucket: this.bucket,
          Key: path
        })
      );
      return true;
    } catch (error) {
      const err = error;
      if (err.name === "NotFound" || err.name === "NoSuchKey") {
        return false;
      }
      return false;
    }
  }
  getUrl(path) {
    const normalizedPath = path.replace(/\\/g, "/");
    if (this.publicUrl) {
      return `${this.publicUrl.replace(/\/$/, "")}/${normalizedPath}`;
    }
    const cfg = this.config;
    if (cfg.endpoint) {
      const base = cfg.endpoint.replace(/\/$/, "");
      return cfg.forcePathStyle ? `${base}/${this.bucket}/${normalizedPath}` : `${base}/${normalizedPath}`;
    }
    return `https://${this.bucket}.s3.${cfg.region || "us-east-1"}.amazonaws.com/${normalizedPath}`;
  }
  async getFile(path) {
    const response = await this.client.send(
      new GetObjectCommand({
        Bucket: this.bucket,
        Key: path
      })
    );
    if (!response.Body) {
      throw new Error(`File not found in S3: ${path}`);
    }
    const bytes = await response.Body.transformToByteArray();
    return Buffer.from(bytes);
  }
  supportsSignedUrls() {
    return true;
  }
  getSignedUrl(path, options) {
    const expiresIn = this.normalizeSignedUrlExpiry(
      options == null ? void 0 : options.expiresIn,
      this.defaultSignedUrlExpiry
    );
    const command = new GetObjectCommand({
      Bucket: this.bucket,
      Key: path,
      ResponseContentDisposition: options == null ? void 0 : options.responseContentDisposition
    });
    return getSignedUrl(this.client, command, {
      expiresIn
    });
  }
  getSignedUploadUrl(key, contentType, expiresIn) {
    const normalizedExpiresIn = this.normalizeSignedUrlExpiry(
      expiresIn,
      this.defaultSignedUrlExpiry
    );
    const command = new PutObjectCommand({
      Bucket: this.bucket,
      Key: key,
      ContentType: contentType
    });
    return getSignedUrl(this.client, command, {
      expiresIn: normalizedExpiresIn
    });
  }
}

export { S3StorageProvider };
//# sourceMappingURL=S3StorageProvider.mjs.map
