@qlover/env-loader
Version:
A package for managing environment variables
193 lines (192 loc) • 5.59 kB
JavaScript
// src/Env.ts
import { config } from "dotenv";
import { existsSync } from "fs";
import { resolve, dirname } from "path";
var Env = class _Env {
/**
* Creates an Env instance
* @param options - Environment configuration options
* @description
* Significance: Initializes environment management
* Core idea: Setup environment configuration
* Main function: Create environment handler
* Main purpose: Prepare for environment operations
* Example:
* ```typescript
* const env = new Env({
* rootPath: './project',
* logger: new Logger()
* });
* ```
*/
constructor(options) {
this.options = options;
}
get rootPath() {
return this.options.rootPath;
}
get logger() {
return this.options.logger;
}
/**
* from current directory to root directory, search and load .env file
* @param {object} options
* @param {string} [options.cwd] start search directory, default is process.cwd()
* @param {string[]} [options.preloadList] search file name list, default is ['.env.local', '.env']
* @param {Logger} [options.logger] logger
* @param {number} [options.maxDepth=5] maximum search depth
* @returns {Env} environment variable loader instance
*/
static searchEnv({
cwd = process.cwd(),
preloadList = [".env.local", ".env"],
logger,
maxDepth = 5
} = {}) {
maxDepth = Math.min(maxDepth, 8);
const env = new _Env({ rootPath: cwd, logger });
let currentDir = cwd;
let lastDir = "";
let found = false;
let searchCount = 0;
while (currentDir !== lastDir) {
found = preloadList.some((file) => existsSync(resolve(currentDir, file)));
if (found) {
env.load({
preloadList,
rootPath: currentDir
});
break;
}
searchCount++;
if (searchCount >= maxDepth) {
logger?.warn(
`Search depth exceeded ${maxDepth} levels, stopping search at ${currentDir}`
);
break;
}
lastDir = currentDir;
currentDir = dirname(currentDir);
if (currentDir === lastDir) {
logger?.warn("Reached root directory, stopping search");
break;
}
}
if (!found && logger) {
logger.warn(
`No environment files (${preloadList.join(", ")}) found in directory tree from ${cwd} to ${currentDir}`
);
}
return env;
}
/**
* Load environment variables from files
* @param options - Load configuration options
* @returns void
* @description
* Significance: Loads environment variables from files
* Core idea: Sequential environment file loading
* Main function: Process and load environment files
* Main purpose: Initialize environment variables
* Example:
* ```typescript
* env.load({
* preloadList: ['.env.local', '.env'],
* rootPath: './config'
* });
* ```
*/
load(options = { preloadList: [] }) {
const { preloadList, rootPath } = options;
if (!preloadList.length) {
this.logger?.warn?.("Env load preloadList is empty!");
return;
}
const resolvedRootPath = rootPath || this.rootPath || resolve("./");
for (const file of preloadList) {
const envLocalPath = resolve(resolvedRootPath, file);
if (existsSync(envLocalPath)) {
config({ path: envLocalPath });
this.logger?.debug?.(`Loaded \`${envLocalPath}\` file`);
return;
}
}
this.logger?.warn?.("No .env file found");
}
/**
* Remove environment variable
* @param variable - Environment variable name
* @returns void
* @description
* Significance: Removes specific environment variable
* Core idea: Safe environment variable deletion
* Main function: Delete environment variable
* Main purpose: Clean up environment state
* Example:
* ```typescript
* env.remove('API_KEY');
* ```
*/
remove(variable) {
if (process.env[variable]) {
delete process.env[variable];
}
}
/**
* Get environment variable value
* @param variable - Environment variable name
* @returns Environment variable value or undefined
* @description
* Significance: Retrieves environment variable value
* Core idea: Safe environment variable access
* Main function: Get environment variable
* Main purpose: Access environment state
* Example:
* ```typescript
* const apiKey = env.get('API_KEY');
* ```
*/
get(variable) {
return process.env[variable];
}
/**
* Set environment variable
* @param variable - Environment variable name
* @param value - Value to set
* @returns void
* @description
* Significance: Sets environment variable value
* Core idea: Safe environment variable modification
* Main function: Update environment variable
* Main purpose: Modify environment state
* Example:
* ```typescript
* env.set('DEBUG', 'true');
* ```
*/
set(variable, value) {
process.env[variable] = value;
}
/**
* Get and remove environment variable
* @param variable - Environment variable name
* @returns Environment variable value or undefined
* @description
* Significance: Retrieves and removes environment variable
* Core idea: Atomic get and delete operation
* Main function: Access and clean up variable
* Main purpose: One-time environment variable access
* Example:
* ```typescript
* const tempKey = env.getDestroy('TEMP_API_KEY');
* ```
*/
getDestroy(variable) {
const value = process.env[variable];
this.remove(variable);
return value;
}
};
export {
Env
};