@kumix/storage 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,6 +24,7 @@ const ENV_VARS = {
24
24
  KUMIX_S3_BUCKET: "KUMIX_S3_BUCKET",
25
25
  KUMIX_S3_ACCESS_KEY_ID: "KUMIX_S3_ACCESS_KEY_ID",
26
26
  KUMIX_S3_SECRET_ACCESS_KEY: "KUMIX_S3_SECRET_ACCESS_KEY",
27
+ KUMIX_S3_SESSION_TOKEN: "KUMIX_S3_SESSION_TOKEN",
27
28
  KUMIX_S3_ENDPOINT: "KUMIX_S3_ENDPOINT",
28
29
  KUMIX_S3_FORCE_PATH_STYLE: "KUMIX_S3_FORCE_PATH_STYLE",
29
30
  KUMIX_S3_PUBLIC_URL: "KUMIX_S3_PUBLIC_URL",
@@ -101,7 +102,7 @@ function getBooleanEnvVar(key, defaultValue = false, env) {
101
102
  * ```
102
103
  */
103
104
  function loadS3Config(env) {
104
- const provider = getRequiredEnvVar(ENV_VARS.KUMIX_S3_PROVIDER, env);
105
+ const provider = getEnvVar(ENV_VARS.KUMIX_S3_PROVIDER, env) || "aws";
105
106
  const validProviders = [
106
107
  "aws",
107
108
  "cloudflare-r2",
@@ -117,6 +118,7 @@ function loadS3Config(env) {
117
118
  bucket: getRequiredEnvVar(ENV_VARS.KUMIX_S3_BUCKET, env),
118
119
  accessKeyId: getRequiredEnvVar(ENV_VARS.KUMIX_S3_ACCESS_KEY_ID, env),
119
120
  secretAccessKey: getRequiredEnvVar(ENV_VARS.KUMIX_S3_SECRET_ACCESS_KEY, env),
121
+ sessionToken: getEnvVar(ENV_VARS.KUMIX_S3_SESSION_TOKEN, env),
120
122
  endpoint: getEnvVar(ENV_VARS.KUMIX_S3_ENDPOINT, env),
121
123
  forcePathStyle: getBooleanEnvVar(ENV_VARS.KUMIX_S3_FORCE_PATH_STYLE, false, env),
122
124
  publicUrl: getEnvVar(ENV_VARS.KUMIX_S3_PUBLIC_URL, env)
@@ -204,11 +206,7 @@ function loadStorageConfig(env) {
204
206
  const hasCloudinaryVars = getEnvVar(ENV_VARS.KUMIX_CLOUDINARY_CLOUD_NAME, env) && getEnvVar(ENV_VARS.KUMIX_CLOUDINARY_API_KEY, env) && getEnvVar(ENV_VARS.KUMIX_CLOUDINARY_API_SECRET, env);
205
207
  const hasS3Vars = getEnvVar(ENV_VARS.KUMIX_S3_BUCKET, env) && getEnvVar(ENV_VARS.KUMIX_S3_ACCESS_KEY_ID, env) && getEnvVar(ENV_VARS.KUMIX_S3_SECRET_ACCESS_KEY, env);
206
208
  if (hasCloudinaryVars) return loadCloudinaryConfig(env);
207
- if (hasS3Vars) {
208
- const config = loadS3Config(env);
209
- if (!config.provider) config.provider = "aws";
210
- return config;
211
- }
209
+ if (hasS3Vars) return loadS3Config(env);
212
210
  throw new Error("No storage configuration found. Please set either:\n- S3: KUMIX_S3_PROVIDER, KUMIX_S3_REGION, KUMIX_S3_BUCKET, KUMIX_S3_ACCESS_KEY_ID, KUMIX_S3_SECRET_ACCESS_KEY\n- Cloudinary: KUMIX_CLOUDINARY_CLOUD_NAME, KUMIX_CLOUDINARY_API_KEY, KUMIX_CLOUDINARY_API_SECRET");
213
211
  }
214
212
  /**
@@ -333,7 +331,6 @@ function getStorageProvider(env) {
333
331
  */
334
332
  function validateS3EnvVars(env) {
335
333
  const missing = [
336
- ENV_VARS.KUMIX_S3_PROVIDER,
337
334
  ENV_VARS.KUMIX_S3_REGION,
338
335
  ENV_VARS.KUMIX_S3_BUCKET,
339
336
  ENV_VARS.KUMIX_S3_ACCESS_KEY_ID,
@@ -397,9 +394,20 @@ function validateCloudinaryEnvVars(env) {
397
394
  */
398
395
  function getStorageEnvVars(env) {
399
396
  const result = {};
397
+ const SENSITIVE_PATTERNS = [
398
+ /SECRET/i,
399
+ /API_SECRET/i,
400
+ /API_KEY/i,
401
+ /ACCESS_KEY_ID/i,
402
+ /SECRET_ACCESS_KEY/i,
403
+ /_KEY_ID$/i,
404
+ /TOKEN/i,
405
+ /PASSWORD/i
406
+ ];
407
+ const isSensitive = (key) => SENSITIVE_PATTERNS.some((p) => p.test(key));
400
408
  Object.values(ENV_VARS).forEach((key) => {
401
409
  const value = getEnvVar(key, env);
402
- if (value) if (key.includes("SECRET") || key.includes("API_SECRET")) result[key] = `${value.substring(0, 4)}***`;
410
+ if (value) if (isSensitive(key)) result[key] = "****";
403
411
  else result[key] = value;
404
412
  });
405
413
  return result;
@@ -407,4 +415,4 @@ function getStorageEnvVars(env) {
407
415
  //#endregion
408
416
  export { isStorageConfigured as a, loadStorageConfig as c, hasStorageConfig as i, validateCloudinaryEnvVars as l, getStorageEnvVars as n, loadCloudinaryConfig as o, getStorageProvider as r, loadS3Config as s, ENV_VARS as t, validateS3EnvVars as u };
409
417
 
410
- //# sourceMappingURL=config-t-NVJICl.js.map
418
+ //# sourceMappingURL=config-By5ib98s.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-By5ib98s.js","names":[],"sources":["../src/config.ts"],"sourcesContent":["/**\n * Storage configuration from environment variables\n * Provides automatic configuration loading from environment variables\n */\n\nimport type { CloudinaryConfig, S3Config, StorageConfig } from \"./types\";\n\n/**\n * Cross-runtime environment record.\n * Pass `process.env` on Node.js, `ctx.env` on Cloudflare Workers,\n * `Deno.env.toObject()` on Deno, or a plain object in the browser.\n */\nexport type EnvRecord = Record<string, string | undefined>;\n\nfunction getDefaultEnv(): EnvRecord | undefined {\n if (typeof process !== \"undefined\" && process?.env) {\n return process.env as EnvRecord;\n }\n return undefined;\n}\n\nfunction resolveEnv(env?: EnvRecord): EnvRecord | undefined {\n return env ?? getDefaultEnv();\n}\n\n/**\n * Environment variable names for storage configuration\n * @public\n *\n * @example\n * ```typescript\n * import { ENV_VARS } from '@kumix/storage';\n *\n * // Check if specific env vars are set\n * console.log(process.env[ENV_VARS.KUMIX_S3_BUCKET]);\n * console.log(process.env[ENV_VARS.KUMIX_CLOUDINARY_CLOUD_NAME]);\n * ```\n */\nexport const ENV_VARS = {\n // S3 Configuration\n KUMIX_S3_PROVIDER: \"KUMIX_S3_PROVIDER\",\n KUMIX_S3_REGION: \"KUMIX_S3_REGION\",\n KUMIX_S3_BUCKET: \"KUMIX_S3_BUCKET\",\n KUMIX_S3_ACCESS_KEY_ID: \"KUMIX_S3_ACCESS_KEY_ID\",\n KUMIX_S3_SECRET_ACCESS_KEY: \"KUMIX_S3_SECRET_ACCESS_KEY\",\n KUMIX_S3_SESSION_TOKEN: \"KUMIX_S3_SESSION_TOKEN\",\n KUMIX_S3_ENDPOINT: \"KUMIX_S3_ENDPOINT\",\n KUMIX_S3_FORCE_PATH_STYLE: \"KUMIX_S3_FORCE_PATH_STYLE\",\n KUMIX_S3_PUBLIC_URL: \"KUMIX_S3_PUBLIC_URL\",\n\n // Cloudinary Configuration\n KUMIX_CLOUDINARY_CLOUD_NAME: \"KUMIX_CLOUDINARY_CLOUD_NAME\",\n KUMIX_CLOUDINARY_API_KEY: \"KUMIX_CLOUDINARY_API_KEY\",\n KUMIX_CLOUDINARY_API_SECRET: \"KUMIX_CLOUDINARY_API_SECRET\",\n KUMIX_CLOUDINARY_SECURE: \"KUMIX_CLOUDINARY_SECURE\",\n KUMIX_CLOUDINARY_FOLDER: \"KUMIX_CLOUDINARY_FOLDER\",\n} as const;\n\n/**\n * Get environment variable value\n * @param key - Environment variable name\n * @param env - Optional environment record\n * @internal\n */\nfunction getEnvVar(key: string, env?: EnvRecord): string | undefined {\n const e = resolveEnv(env);\n if (!e) return undefined;\n return e[key];\n}\n\n/**\n * Get required environment variable value\n * @param key - Environment variable name\n * @param env - Optional environment record\n * @internal\n */\nfunction getRequiredEnvVar(key: string, env?: EnvRecord): string {\n const value = getEnvVar(key, env);\n if (!value) {\n throw new Error(`Missing required environment variable: ${key}`);\n }\n return value;\n}\n\n/**\n * Get boolean environment variable value\n * @param key - Environment variable name\n * @param defaultValue - Default boolean value if not set\n * @param env - Optional environment record\n * @internal\n */\nfunction getBooleanEnvVar(key: string, defaultValue = false, env?: EnvRecord): boolean {\n const value = getEnvVar(key, env);\n if (!value) return defaultValue;\n return value.toLowerCase() === \"true\" || value === \"1\";\n}\n\n/**\n * Load S3 configuration from environment variables\n * @param env - Optional environment record\n * @returns S3 configuration object\n * @throws Error if required environment variables are missing\n * @public\n *\n * @example\n * ```typescript\n * import { loadS3Config } from '@kumix/storage';\n *\n * // Set environment variables first:\n * // KUMIX_S3_PROVIDER=aws\n * // KUMIX_S3_REGION=us-east-1\n * // KUMIX_S3_BUCKET=my-bucket\n * // KUMIX_S3_ACCESS_KEY_ID=AKIA...\n * // KUMIX_S3_SECRET_ACCESS_KEY=secret...\n *\n * try {\n * const config = loadS3Config();\n * console.log(config);\n * // Returns: {\n * // provider: 'aws',\n * // region: 'us-east-1',\n * // bucket: 'my-bucket',\n * // accessKeyId: 'AKIA...',\n * // secretAccessKey: 'secret...'\n * // }\n * } catch (error) {\n * console.error('Missing S3 configuration:', error.message);\n * }\n * ```\n */\nexport function loadS3Config(env?: EnvRecord): S3Config {\n const provider = (getEnvVar(ENV_VARS.KUMIX_S3_PROVIDER, env) || \"aws\") as S3Config[\"provider\"];\n\n // Validate provider\n const validProviders: S3Config[\"provider\"][] = [\n \"aws\",\n \"cloudflare-r2\",\n \"minio\",\n \"digitalocean\",\n \"supabase\",\n \"custom\",\n ];\n if (!validProviders.includes(provider)) {\n throw new Error(\n `Invalid S3 provider: ${provider}. Must be one of: ${validProviders.join(\", \")}`,\n );\n }\n\n return {\n provider,\n region: getRequiredEnvVar(ENV_VARS.KUMIX_S3_REGION, env),\n bucket: getRequiredEnvVar(ENV_VARS.KUMIX_S3_BUCKET, env),\n accessKeyId: getRequiredEnvVar(ENV_VARS.KUMIX_S3_ACCESS_KEY_ID, env),\n secretAccessKey: getRequiredEnvVar(ENV_VARS.KUMIX_S3_SECRET_ACCESS_KEY, env),\n sessionToken: getEnvVar(ENV_VARS.KUMIX_S3_SESSION_TOKEN, env),\n endpoint: getEnvVar(ENV_VARS.KUMIX_S3_ENDPOINT, env),\n forcePathStyle: getBooleanEnvVar(ENV_VARS.KUMIX_S3_FORCE_PATH_STYLE, false, env),\n publicUrl: getEnvVar(ENV_VARS.KUMIX_S3_PUBLIC_URL, env),\n };\n}\n\n/**\n * Load Cloudinary configuration from environment variables\n * @param env - Optional environment record\n * @returns Cloudinary configuration object\n * @throws Error if required environment variables are missing\n * @public\n *\n * @example\n * ```typescript\n * import { loadCloudinaryConfig } from '@kumix/storage';\n *\n * // Set environment variables first:\n * // KUMIX_CLOUDINARY_CLOUD_NAME=my-cloud\n * // KUMIX_CLOUDINARY_API_KEY=123456789\n * // KUMIX_CLOUDINARY_API_SECRET=secret...\n * // KUMIX_CLOUDINARY_SECURE=true (optional)\n * // KUMIX_CLOUDINARY_FOLDER=uploads (optional)\n *\n * try {\n * const config = loadCloudinaryConfig();\n * console.log(config);\n * // Returns: {\n * // provider: 'cloudinary',\n * // cloudName: 'my-cloud',\n * // apiKey: '123456789',\n * // apiSecret: 'secret...',\n * // secure: true,\n * // folder: 'uploads'\n * // }\n * } catch (error) {\n * console.error('Missing Cloudinary configuration:', error.message);\n * }\n * ```\n */\nexport function loadCloudinaryConfig(env?: EnvRecord): CloudinaryConfig {\n return {\n provider: \"cloudinary\",\n cloudName: getRequiredEnvVar(ENV_VARS.KUMIX_CLOUDINARY_CLOUD_NAME, env),\n apiKey: getRequiredEnvVar(ENV_VARS.KUMIX_CLOUDINARY_API_KEY, env),\n apiSecret: getRequiredEnvVar(ENV_VARS.KUMIX_CLOUDINARY_API_SECRET, env),\n secure: getBooleanEnvVar(ENV_VARS.KUMIX_CLOUDINARY_SECURE, true, env),\n folder: getEnvVar(ENV_VARS.KUMIX_CLOUDINARY_FOLDER, env),\n };\n}\n\n/**\n * Auto-detect and load storage configuration from environment variables\n * Determines the provider based on available environment variables\n * @param env - Optional environment record\n * @returns Storage configuration object (S3 or Cloudinary)\n * @throws Error if no valid configuration is found\n * @public\n *\n * @example\n * ```typescript\n * import { loadStorageConfig } from '@kumix/storage';\n *\n * // Auto-detection based on available env vars\n * try {\n * const config = loadStorageConfig();\n *\n * if (config.provider === 'cloudinary') {\n * console.log('Using Cloudinary:', config.cloudName);\n * } else {\n * console.log('Using S3:', config.provider, config.bucket);\n * }\n * } catch (error) {\n * console.error('No storage configuration found:', error.message);\n * }\n *\n * // Explicit provider (set KUMIX_S3_PROVIDER=cloudinary)\n * // Will load Cloudinary config even if S3 vars are also present\n * ```\n */\nexport function loadStorageConfig(env?: EnvRecord): StorageConfig {\n const provider = getEnvVar(ENV_VARS.KUMIX_S3_PROVIDER, env);\n\n // If provider is explicitly set, use it\n if (provider) {\n if (provider === \"cloudinary\") {\n return loadCloudinaryConfig(env);\n }\n return loadS3Config(env);\n }\n\n // Auto-detect based on available environment variables\n const hasCloudinaryVars =\n getEnvVar(ENV_VARS.KUMIX_CLOUDINARY_CLOUD_NAME, env) &&\n getEnvVar(ENV_VARS.KUMIX_CLOUDINARY_API_KEY, env) &&\n getEnvVar(ENV_VARS.KUMIX_CLOUDINARY_API_SECRET, env);\n\n const hasS3Vars =\n getEnvVar(ENV_VARS.KUMIX_S3_BUCKET, env) &&\n getEnvVar(ENV_VARS.KUMIX_S3_ACCESS_KEY_ID, env) &&\n getEnvVar(ENV_VARS.KUMIX_S3_SECRET_ACCESS_KEY, env);\n\n if (hasCloudinaryVars) {\n return loadCloudinaryConfig(env);\n }\n if (hasS3Vars) {\n // Default to AWS if no provider specified\n return loadS3Config(env);\n }\n\n throw new Error(\n \"No storage configuration found. Please set either:\\n\" +\n \"- S3: KUMIX_S3_PROVIDER, KUMIX_S3_REGION, KUMIX_S3_BUCKET, KUMIX_S3_ACCESS_KEY_ID, KUMIX_S3_SECRET_ACCESS_KEY\\n\" +\n \"- Cloudinary: KUMIX_CLOUDINARY_CLOUD_NAME, KUMIX_CLOUDINARY_API_KEY, KUMIX_CLOUDINARY_API_SECRET\",\n );\n}\n\n/**\n * Check if storage configuration is available in environment variables\n * @param env - Optional environment record\n * @returns True if valid storage configuration is found\n * @public\n *\n * @example\n * ```typescript\n * import { hasStorageConfig, loadStorageConfig } from '@kumix/storage';\n *\n * if (hasStorageConfig()) {\n * const config = loadStorageConfig();\n * console.log('Storage configured:', config.provider);\n * } else {\n * console.log('Please set storage environment variables');\n * }\n *\n * // Use in conditional initialization\n * const storage = hasStorageConfig() ? createStorage() : null;\n * ```\n */\nexport function hasStorageConfig(env?: EnvRecord): boolean {\n try {\n loadStorageConfig(env);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if storage configuration is available in environment variables\n * @param env - Optional environment record\n * @returns True if either S3 or Cloudinary configuration is available\n * @public\n *\n * @example\n * ```typescript\n * import { isStorageConfigured, createS3, createCloudinary } from '@kumix/storage';\n *\n * if (isStorageConfigured()) {\n * // Choose your preferred provider\n * const s3 = createS3();\n * // OR\n * const cloudinary = createCloudinary();\n *\n * await s3.uploadFile('test.txt', 'Hello World');\n * } else {\n * console.log('Storage not configured. Please set environment variables.');\n * }\n *\n * // Use in conditional initialization\n * const storage = isStorageConfigured() ? createS3() : null;\n * if (storage) {\n * await storage.uploadFile('file.txt', content);\n * }\n * ```\n */\nexport function isStorageConfigured(env?: EnvRecord): boolean {\n return hasStorageConfig(env);\n}\n\n/**\n * Get storage provider name from environment variables without loading full config\n * @param env - Optional environment record\n * @returns Provider name or undefined if not configured\n * @public\n *\n * @example\n * ```typescript\n * import { getStorageProvider } from '@kumix/storage';\n *\n * const provider = getStorageProvider();\n *\n * switch (provider) {\n * case 'aws':\n * console.log('Using AWS S3');\n * break;\n * case 'cloudinary':\n * console.log('Using Cloudinary');\n * break;\n * case 'cloudflare-r2':\n * console.log('Using Cloudflare R2');\n * break;\n * default:\n * console.log('No storage provider configured');\n * }\n *\n * // Quick check without throwing errors\n * if (getStorageProvider()) {\n * // Storage is configured\n * }\n * ```\n */\nexport function getStorageProvider(env?: EnvRecord): string | undefined {\n const provider = getEnvVar(ENV_VARS.KUMIX_S3_PROVIDER, env);\n if (provider) return provider;\n\n // Auto-detect\n const hasCloudinaryVars = getEnvVar(ENV_VARS.KUMIX_CLOUDINARY_CLOUD_NAME, env);\n const hasS3Vars = getEnvVar(ENV_VARS.KUMIX_S3_BUCKET, env);\n\n if (hasCloudinaryVars) return \"cloudinary\";\n if (hasS3Vars) return \"aws\"; // Default S3 provider\n\n return undefined;\n}\n\n/**\n * Validate if all required environment variables are set for S3\n * @param env - Optional environment record\n * @returns Validation result with missing variables\n * @public\n *\n * @example\n * ```typescript\n * import { validateS3EnvVars } from '@kumix/storage';\n *\n * const validation = validateS3EnvVars();\n *\n * if (validation.valid) {\n * console.log('S3 configuration is complete');\n * } else {\n * console.log('Missing S3 variables:', validation.missing);\n * // Returns: [\"KUMIX_S3_REGION\", \"KUMIX_S3_BUCKET\"]\n * }\n * ```\n */\nexport function validateS3EnvVars(env?: EnvRecord): {\n valid: boolean;\n missing: string[];\n} {\n const required = [\n ENV_VARS.KUMIX_S3_REGION,\n ENV_VARS.KUMIX_S3_BUCKET,\n ENV_VARS.KUMIX_S3_ACCESS_KEY_ID,\n ENV_VARS.KUMIX_S3_SECRET_ACCESS_KEY,\n ];\n\n const missing = required.filter((key) => !getEnvVar(key, env));\n\n return {\n valid: missing.length === 0,\n missing,\n };\n}\n\n/**\n * Validate if all required environment variables are set for Cloudinary\n * @param env - Optional environment record\n * @returns Validation result with missing variables\n * @public\n *\n * @example\n * ```typescript\n * import { validateCloudinaryEnvVars } from '@kumix/storage';\n *\n * const validation = validateCloudinaryEnvVars();\n *\n * if (validation.valid) {\n * console.log('Cloudinary configuration is complete');\n * } else {\n * console.log('Missing Cloudinary variables:', validation.missing);\n * // Returns: [\"KUMIX_CLOUDINARY_API_KEY\"]\n * }\n * ```\n */\nexport function validateCloudinaryEnvVars(env?: EnvRecord): {\n valid: boolean;\n missing: string[];\n} {\n const required = [\n ENV_VARS.KUMIX_CLOUDINARY_CLOUD_NAME,\n ENV_VARS.KUMIX_CLOUDINARY_API_KEY,\n ENV_VARS.KUMIX_CLOUDINARY_API_SECRET,\n ];\n\n const missing = required.filter((key) => !getEnvVar(key, env));\n\n return {\n valid: missing.length === 0,\n missing,\n };\n}\n\n/**\n * Get all available environment variables for debugging\n * @param env - Optional environment record\n * @returns Object containing all storage-related env vars\n * @public\n *\n * @example\n * ```typescript\n * import { getStorageEnvVars } from '@kumix/storage';\n *\n * const envVars = getStorageEnvVars();\n * console.log('Storage environment variables:', envVars);\n * // Returns: {\n * // KUMIX_S3_PROVIDER: 'aws',\n * // KUMIX_S3_REGION: 'us-east-1',\n * // KUMIX_S3_BUCKET: 'my-bucket',\n * // // ... other set variables (secrets are masked)\n * // }\n * ```\n */\nexport function getStorageEnvVars(env?: EnvRecord): Record<string, string | undefined> {\n const result: Record<string, string | undefined> = {};\n\n // Mask any value whose key looks like a credential. Previously only\n // SECRET/​API_SECRET values were masked, leaking the S3 access key ID and the\n // Cloudinary API key in plaintext. We now also redact *_KEY_ID, *_API_KEY,\n // *ACCESS_KEY_ID, *SECRET_ACCESS_KEY, *TOKEN, and *PASSWORD.\n const SENSITIVE_PATTERNS = [\n /SECRET/i,\n /API_SECRET/i,\n /API_KEY/i,\n /ACCESS_KEY_ID/i,\n /SECRET_ACCESS_KEY/i,\n /_KEY_ID$/i,\n /TOKEN/i,\n /PASSWORD/i,\n ];\n const isSensitive = (key: string) => SENSITIVE_PATTERNS.some((p) => p.test(key));\n\n Object.values(ENV_VARS).forEach((key) => {\n const value = getEnvVar(key, env);\n if (value) {\n // Mask sensitive values. Indicate presence only — even partial prefixes\n // leak meaningful information about short secrets.\n if (isSensitive(key)) {\n result[key] = \"****\";\n } else {\n result[key] = value;\n }\n }\n });\n\n return result;\n}\n"],"mappings":";AAcA,SAAS,gBAAuC;CAC9C,IAAI,OAAO,YAAY,eAAe,SAAS,KAC7C,OAAO,QAAQ;AAGnB;AAEA,SAAS,WAAW,KAAwC;CAC1D,OAAO,OAAO,cAAc;AAC9B;;;;;;;;;;;;;;AAeA,MAAa,WAAW;CAEtB,mBAAmB;CACnB,iBAAiB;CACjB,iBAAiB;CACjB,wBAAwB;CACxB,4BAA4B;CAC5B,wBAAwB;CACxB,mBAAmB;CACnB,2BAA2B;CAC3B,qBAAqB;CAGrB,6BAA6B;CAC7B,0BAA0B;CAC1B,6BAA6B;CAC7B,yBAAyB;CACzB,yBAAyB;AAC3B;;;;;;;AAQA,SAAS,UAAU,KAAa,KAAqC;CACnE,MAAM,IAAI,WAAW,GAAG;CACxB,IAAI,CAAC,GAAG,OAAO,KAAA;CACf,OAAO,EAAE;AACX;;;;;;;AAQA,SAAS,kBAAkB,KAAa,KAAyB;CAC/D,MAAM,QAAQ,UAAU,KAAK,GAAG;CAChC,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,0CAA0C,KAAK;CAEjE,OAAO;AACT;;;;;;;;AASA,SAAS,iBAAiB,KAAa,eAAe,OAAO,KAA0B;CACrF,MAAM,QAAQ,UAAU,KAAK,GAAG;CAChC,IAAI,CAAC,OAAO,OAAO;CACnB,OAAO,MAAM,YAAY,MAAM,UAAU,UAAU;AACrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAgB,aAAa,KAA2B;CACtD,MAAM,WAAY,UAAU,SAAS,mBAAmB,GAAG,KAAK;CAGhE,MAAM,iBAAyC;EAC7C;EACA;EACA;EACA;EACA;EACA;CACF;CACA,IAAI,CAAC,eAAe,SAAS,QAAQ,GACnC,MAAM,IAAI,MACR,wBAAwB,SAAS,oBAAoB,eAAe,KAAK,IAAI,GAC/E;CAGF,OAAO;EACL;EACA,QAAQ,kBAAkB,SAAS,iBAAiB,GAAG;EACvD,QAAQ,kBAAkB,SAAS,iBAAiB,GAAG;EACvD,aAAa,kBAAkB,SAAS,wBAAwB,GAAG;EACnE,iBAAiB,kBAAkB,SAAS,4BAA4B,GAAG;EAC3E,cAAc,UAAU,SAAS,wBAAwB,GAAG;EAC5D,UAAU,UAAU,SAAS,mBAAmB,GAAG;EACnD,gBAAgB,iBAAiB,SAAS,2BAA2B,OAAO,GAAG;EAC/E,WAAW,UAAU,SAAS,qBAAqB,GAAG;CACxD;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SAAgB,qBAAqB,KAAmC;CACtE,OAAO;EACL,UAAU;EACV,WAAW,kBAAkB,SAAS,6BAA6B,GAAG;EACtE,QAAQ,kBAAkB,SAAS,0BAA0B,GAAG;EAChE,WAAW,kBAAkB,SAAS,6BAA6B,GAAG;EACtE,QAAQ,iBAAiB,SAAS,yBAAyB,MAAM,GAAG;EACpE,QAAQ,UAAU,SAAS,yBAAyB,GAAG;CACzD;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,SAAgB,kBAAkB,KAAgC;CAChE,MAAM,WAAW,UAAU,SAAS,mBAAmB,GAAG;CAG1D,IAAI,UAAU;EACZ,IAAI,aAAa,cACf,OAAO,qBAAqB,GAAG;EAEjC,OAAO,aAAa,GAAG;CACzB;CAGA,MAAM,oBACJ,UAAU,SAAS,6BAA6B,GAAG,KACnD,UAAU,SAAS,0BAA0B,GAAG,KAChD,UAAU,SAAS,6BAA6B,GAAG;CAErD,MAAM,YACJ,UAAU,SAAS,iBAAiB,GAAG,KACvC,UAAU,SAAS,wBAAwB,GAAG,KAC9C,UAAU,SAAS,4BAA4B,GAAG;CAEpD,IAAI,mBACF,OAAO,qBAAqB,GAAG;CAEjC,IAAI,WAEF,OAAO,aAAa,GAAG;CAGzB,MAAM,IAAI,MACR,qQAGF;AACF;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,iBAAiB,KAA0B;CACzD,IAAI;EACF,kBAAkB,GAAG;EACrB,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,oBAAoB,KAA0B;CAC5D,OAAO,iBAAiB,GAAG;AAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,SAAgB,mBAAmB,KAAqC;CACtE,MAAM,WAAW,UAAU,SAAS,mBAAmB,GAAG;CAC1D,IAAI,UAAU,OAAO;CAGrB,MAAM,oBAAoB,UAAU,SAAS,6BAA6B,GAAG;CAC7E,MAAM,YAAY,UAAU,SAAS,iBAAiB,GAAG;CAEzD,IAAI,mBAAmB,OAAO;CAC9B,IAAI,WAAW,OAAO;AAGxB;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,kBAAkB,KAGhC;CAQA,MAAM,UAAU;EANd,SAAS;EACT,SAAS;EACT,SAAS;EACT,SAAS;CAGY,CAAC,CAAC,QAAQ,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC;CAE7D,OAAO;EACL,OAAO,QAAQ,WAAW;EAC1B;CACF;AACF;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,0BAA0B,KAGxC;CAOA,MAAM,UAAU;EALd,SAAS;EACT,SAAS;EACT,SAAS;CAGY,CAAC,CAAC,QAAQ,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC;CAE7D,OAAO;EACL,OAAO,QAAQ,WAAW;EAC1B;CACF;AACF;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,kBAAkB,KAAqD;CACrF,MAAM,SAA6C,CAAC;CAMpD,MAAM,qBAAqB;EACzB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,MAAM,eAAe,QAAgB,mBAAmB,MAAM,MAAM,EAAE,KAAK,GAAG,CAAC;CAE/E,OAAO,OAAO,QAAQ,CAAC,CAAC,SAAS,QAAQ;EACvC,MAAM,QAAQ,UAAU,KAAK,GAAG;EAChC,IAAI,OAGF,IAAI,YAAY,GAAG,GACjB,OAAO,OAAO;OAEd,OAAO,OAAO;CAGpB,CAAC;CAED,OAAO;AACT"}
@@ -33,6 +33,8 @@ interface S3Config {
33
33
  accessKeyId: string;
34
34
  /** Secret access key for authentication */
35
35
  secretAccessKey: string;
36
+ /** Optional session token for AWS STS / SSO / role-chain temporary credentials */
37
+ sessionToken?: string;
36
38
  /** Custom endpoint for S3-compatible services (MinIO, R2, etc.) */
37
39
  endpoint?: string;
38
40
  /** Force path style for services like MinIO */
@@ -85,18 +87,18 @@ interface FolderInfo {
85
87
  name: string;
86
88
  /** Full folder path */
87
89
  path: string;
88
- /** Total size of all files in folder */
89
- size: number;
90
- /** Number of files in folder */
91
- fileCount: number;
92
- /** Last modified date */
93
- lastModified: Date;
90
+ /** Total size of all files in folder (requires aggregation; often omitted) */
91
+ size?: number;
92
+ /** Number of files in folder (requires aggregation; often omitted) */
93
+ fileCount?: number;
94
+ /** Last modified date (requires aggregation; often omitted) */
95
+ lastModified?: Date;
94
96
  }
95
97
  //#endregion
96
98
  //#region src/types/file-operations.d.ts
97
99
  interface UploadOptions {
98
100
  key: string;
99
- file: Buffer | Uint8Array | string;
101
+ file: Uint8Array | string;
100
102
  contentType?: string;
101
103
  metadata?: Record<string, string>;
102
104
  cacheControl?: string;
@@ -119,8 +121,8 @@ interface DownloadOptions {
119
121
  }
120
122
  interface DownloadResult {
121
123
  success: boolean;
122
- content?: Buffer;
123
- data?: Buffer;
124
+ content?: Uint8Array;
125
+ data?: Uint8Array;
124
126
  contentType?: string;
125
127
  contentLength?: number;
126
128
  lastModified?: Date;
@@ -328,6 +330,7 @@ declare const ENV_VARS: {
328
330
  readonly KUMIX_S3_BUCKET: "KUMIX_S3_BUCKET";
329
331
  readonly KUMIX_S3_ACCESS_KEY_ID: "KUMIX_S3_ACCESS_KEY_ID";
330
332
  readonly KUMIX_S3_SECRET_ACCESS_KEY: "KUMIX_S3_SECRET_ACCESS_KEY";
333
+ readonly KUMIX_S3_SESSION_TOKEN: "KUMIX_S3_SESSION_TOKEN";
331
334
  readonly KUMIX_S3_ENDPOINT: "KUMIX_S3_ENDPOINT";
332
335
  readonly KUMIX_S3_FORCE_PATH_STYLE: "KUMIX_S3_FORCE_PATH_STYLE";
333
336
  readonly KUMIX_S3_PUBLIC_URL: "KUMIX_S3_PUBLIC_URL";
@@ -591,4 +594,4 @@ declare function validateCloudinaryEnvVars(env?: EnvRecord): {
591
594
  declare function getStorageEnvVars(env?: EnvRecord): Record<string, string | undefined>;
592
595
  //#endregion
593
596
  export { DownloadOptions as A, PresignedUrlResult as B, RenameFolderResult as C, CopyResult as D, CopyOptions as E, ListOptions as F, FolderInfo as G, UploadResult as H, ListResult as I, StorageConfig as J, S3Config as K, MoveOptions as L, DuplicateOptions as M, DuplicateResult as N, DeleteOptions as O, ExistsResult as P, MoveResult as R, RenameFolderOptions as S, BatchDeleteResult as T, CloudinaryConfig as U, UploadOptions as V, FileInfo as W, StorageProvider as Y, DeleteFolderOptions as _, hasStorageConfig as a, ListFoldersOptions as b, loadS3Config as c, validateS3EnvVars as d, StorageInterface as f, CreateFolderResult as g, CreateFolderOptions as h, getStorageProvider as i, DownloadResult as j, DeleteResult as k, loadStorageConfig as l, CopyFolderResult as m, EnvRecord as n, isStorageConfigured as o, CopyFolderOptions as p, S3ProviderType as q, getStorageEnvVars as r, loadCloudinaryConfig as s, ENV_VARS as t, validateCloudinaryEnvVars as u, DeleteFolderResult as v, BatchDeleteOptions as w, ListFoldersResult as x, FolderExistsResult as y, PresignedUrlOptions as z };
594
- //# sourceMappingURL=config-J6AdDh_c.d.ts.map
597
+ //# sourceMappingURL=config-DGzEH-Zd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-DGzEH-Zd.d.ts","names":[],"sources":["../src/types/base.ts","../src/types/file-operations.ts","../src/types/folder-operations.ts","../src/types/storage-interface.ts","../src/config.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","names":[],"sources":["../src/helpers.ts"],"mappings":";;AAyBA;;;;AAAqE;AA+BrE;;;;AAA4C;AAuB5C;;;;;;;;;AAG0B;AAkC1B;iBA3FgB,eAAA,CAAgB,YAAA,UAAsB,MAAe;;;;;;;;AA8F3C;AA4C1B;;;;AAA4C;AA2B5C;;;;AAAiD;AA4BjD;;iBAlKgB,WAAA,CAAY,QAAgB;;AAkKK;AA0BjD;;;;AAE0B;AA6B1B;;;;;;;;AAA+D;AAoD/D;;iBAxPgB,gBAAA,CACd,QAAA,UACA,OAAA;EACG,KAAA;EAAgB,KAAA;AAAA;;;;AAyPD;AAmCpB;;;;;;;;AAAmE;AA8CnE;;;;;;;;;;;iBAxSgB,gBAAA,CACd,QAAA,UACA,YAAA;EACG,KAAA;EAAgB,KAAA;AAAA;;;;;;;;;;;;AAwUD;AA6BpB;;;;;;;;iBAzTgB,cAAA,CAAe,KAAa;AAqW5C;;;;;;;;;AAGQ;AA+DR;;;;;;;AAlEA,iBA1UgB,gBAAA,CAAiB,QAAgB;;AA8YzC;AA0DR;;;;;;;;AAEO;AAiEP;;;;AAEqD;AAuBrD;;;;iBAxgBgB,gBAAA,CAAiB,QAAgB;AA8hBjD;;;;AAA4C;AAsB5C;;;;AAA4C;AAyB5C;;;;AAA+C;AAoC/C;;;;AAA0C;AA2B1C;AA9GA,iBApgBgB,oBAAA,CACd,MAAA;AACA,QAAwB;;AAgnBU;AA4BpC;;;;AAAyC;AA0BzC;;;;AAAuC;AA2BvC;;;;AAA0D;AAwC1D;;;;;;iBA5sBgB,UAAA,CAAW,GAAA;EAAgB,MAAA;EAAiB,GAAA;AAAA;AAswB5D;;;;;;;;;AAGU;AAgDV;;;;AAAsE;AAiCtE;;;;AApFA,iBAltBgB,cAAA,CACd,OAAA,UACA,MAAA,UACA,GAAA,UACA,QAAA;;;;;;;;;;;AAyyBiD;AA2EnD;;;;AAA4D;;iBAj1B5C,aAAA,CAAc,GAAA;EAAgB,KAAA;EAAgB,KAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;iBA8CxC,YAAA,CAAa,IAAA,EAAM,IAAA,GAAO,OAAA,CAAQ,UAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+BxC,WAAA,CAAY,IAAA,EAAM,IAAA;EAChC,IAAA;EACA,IAAA;EACA,IAAA;EACA,YAAA,EAAc,IAAI;AAAA;;;;;;;;;;;;;;;;;;;;iBA6BJ,iBAAA,CACd,QAAA,UACA,MAAA,WACA,gBAAA;;;;;;;;;;;;;;;;;;;;;;;;iBAyCc,aAAA,CAAc,GAAA;EAC5B,MAAA;EACA,GAAA;EACA,MAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+Dc,gBAAA,CAAiB,MAAA,EAAQ,MAAM;EAC7C,KAAA;EACA,MAAA;AAAA;;;;;;;;;;;;;;;;;;;;;iBA0Dc,kBAAA,CAAmB,UAAA;EACjC,KAAA;EACA,KAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;iBAiEc,qBAAA,CACd,QAAA,UACA,WAAmD;;;;;;;;;;;;;;;;;;iBAuBrC,WAAA,CAAY,QAAgB;;;;;;;;;;;;;;;;;;iBAsB5B,WAAA,CAAY,QAAgB;;;;;;;;;;;;;;;;;;iBAsB5B,WAAA,CAAY,QAAgB;;;;;;;;;;;;;;;;;;;;;iBAyB5B,cAAA,CAAe,QAAgB;;;;;;;;;;;;;;;;;;;;;iBAoC/B,aAAA,CAAc,IAAY;;;;;;;;;;;;;;;;;;;;;iBA2B1B,QAAA,IAAY,QAAQ;;;;;;;;;;;;;;;;;;;;;iBA4BpB,aAAA,CAAc,GAAW;;;;;;;;;;;;;;;;;;;;;iBA0BzB,WAAA,CAAY,GAAW;;;;;;;;;;;;;;;;;;;;;;iBA2BvB,cAAA,CAAe,MAAA,WAAiB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwC1C,cAAA,CACd,MAAA,EAAQ,UAAU,EAClB,cAAA,YACA,QAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuDoB,gBAAA,CACpB,OAAA,EAAS,UAAA,WACT,SAAA,+BACC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgDM,iBAAA,CAAkB,SAAA,YAAqB,MAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiCtD,kBAAA,CACd,KAAA,EAAO,IAAA,IACP,OAAA;EACE,OAAA;EACA,YAAA;EACA,QAAA;AAAA,IAED,KAAK;EAAG,KAAA;EAAgB,QAAA;EAAkB,MAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2E7B,yBAAA,CAA0B,MAAkB,EAAV,UAAU"}
1
+ {"version":3,"file":"helpers.d.ts","names":[],"sources":["../src/helpers.ts"],"mappings":"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"}
package/dist/helpers.js CHANGED
@@ -1,9 +1,80 @@
1
- import { lookup } from "mime-types";
2
1
  //#region src/helpers.ts
3
2
  /**
4
3
  * Storage helper utilities
5
4
  * Provides utility functions for file operations, MIME type detection, and path manipulation
6
5
  */
6
+ const MIME_BY_EXTENSION = {
7
+ jpg: "image/jpeg",
8
+ jpeg: "image/jpeg",
9
+ png: "image/png",
10
+ gif: "image/gif",
11
+ webp: "image/webp",
12
+ avif: "image/avif",
13
+ bmp: "image/bmp",
14
+ svg: "image/svg+xml",
15
+ ico: "image/x-icon",
16
+ tiff: "image/tiff",
17
+ tif: "image/tiff",
18
+ heic: "image/heic",
19
+ heif: "image/heif",
20
+ mp4: "video/mp4",
21
+ webm: "video/webm",
22
+ mov: "video/quicktime",
23
+ avi: "video/x-msvideo",
24
+ mkv: "video/x-matroska",
25
+ m4v: "video/x-m4v",
26
+ wmv: "video/x-ms-wmv",
27
+ flv: "video/x-flv",
28
+ mp3: "audio/mpeg",
29
+ wav: "audio/wav",
30
+ ogg: "audio/ogg",
31
+ flac: "audio/flac",
32
+ aac: "audio/aac",
33
+ m4a: "audio/x-m4a",
34
+ opus: "audio/opus",
35
+ pdf: "application/pdf",
36
+ doc: "application/msword",
37
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
38
+ xls: "application/vnd.ms-excel",
39
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
40
+ ppt: "application/vnd.ms-powerpoint",
41
+ pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
42
+ txt: "text/plain",
43
+ md: "text/markdown",
44
+ html: "text/html",
45
+ htm: "text/html",
46
+ css: "text/css",
47
+ csv: "text/csv",
48
+ ics: "text/calendar",
49
+ json: "application/json",
50
+ xml: "application/xml",
51
+ yaml: "application/x-yaml",
52
+ yml: "application/x-yaml",
53
+ js: "text/javascript",
54
+ mjs: "text/javascript",
55
+ ts: "text/typescript",
56
+ jsx: "text/jsx",
57
+ tsx: "text/tsx",
58
+ zip: "application/zip",
59
+ gz: "application/gzip",
60
+ tar: "application/x-tar",
61
+ rar: "application/vnd.rar",
62
+ "7z": "application/x-7z-compressed",
63
+ bz2: "application/x-bzip2",
64
+ woff: "font/woff",
65
+ woff2: "font/woff2",
66
+ ttf: "font/ttf",
67
+ otf: "font/otf",
68
+ eot: "application/vnd.ms-fontobject",
69
+ bin: "application/octet-stream",
70
+ exe: "application/octet-stream"
71
+ };
72
+ const lookupMimeByExtension = (fileName) => {
73
+ const dot = fileName.lastIndexOf(".");
74
+ if (dot < 0 || dot === fileName.length - 1) return void 0;
75
+ const ext = fileName.slice(dot + 1).toLowerCase();
76
+ return MIME_BY_EXTENSION[ext];
77
+ };
7
78
  /**
8
79
  * Generate a unique file key with timestamp and random string
9
80
  * @param originalName Original file name
@@ -25,8 +96,8 @@ import { lookup } from "mime-types";
25
96
  function generateFileKey(originalName, prefix) {
26
97
  const timestamp = Date.now();
27
98
  const random = Math.random().toString(36).substring(2, 8);
28
- const extension = originalName.split(".").pop();
29
- const fileName = `${originalName.split(".").slice(0, -1).join(".")}-${timestamp}-${random}${extension ? `.${extension}` : ""}`;
99
+ const lastDot = originalName.lastIndexOf(".");
100
+ const fileName = `${lastDot > 0 ? originalName.slice(0, lastDot) : originalName}-${timestamp}-${random}${lastDot > 0 ? originalName.slice(lastDot) : ""}`;
30
101
  return prefix ? `${prefix}/${fileName}` : fileName;
31
102
  }
32
103
  /**
@@ -50,7 +121,7 @@ function generateFileKey(originalName, prefix) {
50
121
  * ```
51
122
  */
52
123
  function getMimeType(fileName) {
53
- return lookup(fileName) || "application/octet-stream";
124
+ return lookupMimeByExtension(fileName) || "application/octet-stream";
54
125
  }
55
126
  /**
56
127
  * Validate file size against maximum allowed size
@@ -140,6 +211,7 @@ function validateFileType(fileName, allowedTypes) {
140
211
  */
141
212
  function formatFileSize(bytes) {
142
213
  if (bytes === 0) return "0 Bytes";
214
+ if (bytes < 0) return `-${formatFileSize(-bytes)}`;
143
215
  const k = 1024;
144
216
  const sizes = [
145
217
  "Bytes",
@@ -148,7 +220,7 @@ function formatFileSize(bytes) {
148
220
  "GB",
149
221
  "TB"
150
222
  ];
151
- const i = Math.floor(Math.log(bytes) / Math.log(k));
223
+ const i = Math.min(Math.floor(Math.log(bytes) / Math.log(k)), sizes.length - 1);
152
224
  return `${parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`;
153
225
  }
154
226
  /**
@@ -169,7 +241,7 @@ function formatFileSize(bytes) {
169
241
  * ```
170
242
  */
171
243
  function sanitizeFileName(fileName) {
172
- return fileName.replace(/[^a-zA-Z0-9.-]/g, "_").replace(/_{2,}/g, "_").replace(/^_|_$/g, "").toLowerCase();
244
+ return fileName.replace(/[^a-zA-Z0-9.-]/g, "_").replace(/_{2,}/g, "_").replace(/^_|_$/g, "").replace(/_+(\.[a-zA-Z0-9]+)$/, "$1").toLowerCase();
173
245
  }
174
246
  /**
175
247
  * Extract file extension from file name
@@ -192,8 +264,9 @@ function sanitizeFileName(fileName) {
192
264
  * ```
193
265
  */
194
266
  function getFileExtension(fileName) {
195
- const extension = fileName.split(".").pop();
196
- return extension ? `.${extension.toLowerCase()}` : "";
267
+ const lastDot = fileName.lastIndexOf(".");
268
+ if (lastDot <= 0) return "";
269
+ return `.${fileName.slice(lastDot + 1).toLowerCase()}`;
197
270
  }
198
271
  /**
199
272
  * Generate cache control header for HTTP responses
@@ -288,7 +361,7 @@ function buildPublicUrl(baseUrl, bucket, key, supabase) {
288
361
  cleanBaseUrl = baseUrl.replace(/\/$/, "");
289
362
  const cleanKey = key.replace(/^\//, "");
290
363
  if (supabase) {
291
- cleanBaseUrl = cleanBaseUrl.replace(/\.storage/, "").replace(/\/storage\/v1\/s3$/, "");
364
+ cleanBaseUrl = cleanBaseUrl.replace(/\.storage(?=\.supabase\.(?:co|in|net))/, "").replace(/\/storage\/v1\/s3$/, "");
292
365
  cleanBaseUrl = `${cleanBaseUrl}/storage/v1/object/public`;
293
366
  }
294
367
  return `${cleanBaseUrl}/${bucket === "" ? "" : `${bucket}/`}${cleanKey}`;
@@ -871,7 +944,7 @@ function bufferToBase64(buffer, includeDataUrl = false, mimeType) {
871
944
  * }
872
945
  * ```
873
946
  */
874
- async function generateFileHash(content, algorithm = "md5") {
947
+ async function generateFileHash(content, algorithm = "sha256") {
875
948
  if (algorithm !== "md5" && typeof crypto !== "undefined" && crypto.subtle) {
876
949
  const rawData = typeof content === "string" ? new TextEncoder().encode(content) : content;
877
950
  const hashBuffer = await crypto.subtle.digest(algorithm === "sha1" ? "SHA-1" : "SHA-256", rawData);