@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.
- package/dist/cloudinary.d.ts +2 -1
- package/dist/cloudinary.d.ts.map +1 -1
- package/dist/cloudinary.js +173 -148
- package/dist/cloudinary.js.map +1 -1
- package/dist/{config-t-NVJICl.js → config-By5ib98s.js} +17 -9
- package/dist/config-By5ib98s.js.map +1 -0
- package/dist/{config-J6AdDh_c.d.ts → config-DGzEH-Zd.d.ts} +13 -10
- package/dist/config-DGzEH-Zd.d.ts.map +1 -0
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +83 -10
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/s3.d.ts +2 -1
- package/dist/s3.d.ts.map +1 -1
- package/dist/s3.js +67 -54
- package/dist/s3.js.map +1 -1
- package/package.json +5 -10
- package/dist/config-J6AdDh_c.d.ts.map +0 -1
- package/dist/config-t-NVJICl.js.map +0 -1
|
@@ -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 =
|
|
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 (
|
|
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-
|
|
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":"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"}
|
|
@@ -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
|
|
90
|
-
/** Number of files in folder */
|
|
91
|
-
fileCount
|
|
92
|
-
/** Last modified date */
|
|
93
|
-
lastModified
|
|
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:
|
|
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?:
|
|
123
|
-
data?:
|
|
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-
|
|
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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"}
|
package/dist/helpers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","names":[],"sources":["../src/helpers.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","names":[],"sources":["../src/helpers.ts"],"mappings":";;AA4GA;;;;AAAqE;AAgCrE;;;;AAA4C;AAuB5C;;;;;;;;;AAG0B;AAkC1B;iBA5FgB,eAAA,CAAgB,YAAA,UAAsB,MAAe;;;;;;;;AA+F3C;AA4C1B;;;;AAA4C;AA4B5C;;;;AAAiD;AAkCjD;;iBAzKgB,WAAA,CAAY,QAAgB;;AAyKK;AA2BjD;;;;AAE0B;AA6B1B;;;;;;;;AAA+D;AAoD/D;;iBAhQgB,gBAAA,CACd,QAAA,UACA,OAAA;EACG,KAAA;EAAgB,KAAA;AAAA;;;;AAiQD;AAuCpB;;;;;;;;AAAmE;AA8CnE;;;;;;;;;;;iBApTgB,gBAAA,CACd,QAAA,UACA,YAAA;EACG,KAAA;EAAgB,KAAA;AAAA;;;;;;;;;;;;AAoVD;AA6BpB;;;;;;;;iBArUgB,cAAA,CAAe,KAAa;AAiX5C;;;;;;;;;AAGQ;AA+DR;;;;;;;AAlEA,iBArVgB,gBAAA,CAAiB,QAAgB;;AAyZzC;AA0DR;;;;;;;;AAEO;AAiEP;;;;AAEqD;AAuBrD;;;;iBA7gBgB,gBAAA,CAAiB,QAAgB;AAmiBjD;;;;AAA4C;AAsB5C;;;;AAA4C;AAyB5C;;;;AAA+C;AAoC/C;;;;AAA0C;AA2B1C;AA9GA,iBAxgBgB,oBAAA,CACd,MAAA;AACA,QAAwB;;AAonBU;AA4BpC;;;;AAAyC;AA0BzC;;;;AAAuC;AA2BvC;;;;AAA0D;AAwC1D;;;;;;iBAhtBgB,UAAA,CAAW,GAAA;EAAgB,MAAA;EAAiB,GAAA;AAAA;AA0wB5D;;;;;;;;;AAGU;AAqDV;;;;AAAsE;AAiCtE;;;;AAzFA,iBAttBgB,cAAA,CACd,OAAA,UACA,MAAA,UACA,GAAA,UACA,QAAA;;;;;;;;;;;AAkzBiD;AA2EnD;;;;AAA4D;;iBAt1B5C,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqDM,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"}
|
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
|
|
29
|
-
const fileName = `${originalName.
|
|
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
|
|
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
|
|
196
|
-
|
|
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 = "
|
|
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);
|