New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@athenna/config

Package Overview
Dependencies
Maintainers
1
Versions
76
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@athenna/config - npm Package Compare versions

Comparing version 1.1.6 to 1.1.7

src/Env/Env.js

5

package.json
{
"name": "@athenna/config",
"version": "1.1.6",
"version": "1.1.7",
"description": "Cache and handle environment variables and config files of Athenna.",

@@ -13,2 +13,3 @@ "license": "MIT",

"esm",
"nodejs",
"config",

@@ -40,3 +41,3 @@ "dotenv",

"dependencies": {
"@secjs/utils": "2.0.1",
"@athenna/common": "1.0.0",
"dotenv": "16.0.0"

@@ -43,0 +44,0 @@ },

17

src/Helpers/EnvHelper.js

@@ -11,3 +11,3 @@ /**

import dotenv from 'dotenv'
import { Debug, Is, Path } from '@secjs/utils'
import { Is, Path } from '@athenna/common'

@@ -28,2 +28,6 @@ import { Env } from '#src/index'

static setEnvInEnv(environment, autoCast) {
if (!environment) {
return undefined
}
if (!Is.String(environment)) {

@@ -97,14 +101,5 @@ return environment

configurations.path = Path.pwd(`.env.${environment}`)
Debug.log(
`Environment variables set using .env.${environment} file.`,
'api:environments',
)
}
const result = dotenv.config(configurations)
if (result.error) {
Debug.log('Any environment variable file found.', 'api:environments')
}
dotenv.config(configurations)
}

@@ -111,0 +106,0 @@

@@ -44,2 +44,9 @@ export class EnvHelper {

/**
* Map structure to save all configuration files.
*
* @type {Map<string, any>}
*/
static configs: Map<string, any>
/**
* Get the value from config file by key. If not

@@ -52,11 +59,30 @@ * found, defaultValue will be used.

*/
static get(key: string, defaultValue?: any): any
static get(key: string, defaultValue?: any): Promise<void>
/**
* Load all the files that are inside the path.
* Load all configuration files in path.
*
* @param {string} configPath
* @param {string} path
* @return {Promise<void>}
*/
static load(configPath?: string): Promise<void>
static loadAll(path?: string): Promise<void>
/**
* Load the configuration file only if it has
* not been loaded yet.
*
* @param {string} path
* @param {number?} callNumber
* @return {Promise<void>}
*/
static safeLoad(path, callNumber?: number): Promise<void>
/**
* Load the configuration file.
*
* @param {string} path
* @param {number?} callNumber
* @return {Promise<void>}
*/
static load(path: string, callNumber?: number): Promise<void>
}

@@ -63,0 +89,0 @@

@@ -10,33 +10,21 @@ /**

import { Config as SecConfig, Debug, Folder, Path } from '@secjs/utils'
import { parse } from 'node:path'
import { File, Folder, Json, Module, Path } from '@athenna/common'
import { EnvHelper } from '#src/Helpers/EnvHelper'
import { Env } from '#src/Env/Env'
import { RecursiveConfigException } from '#src/Exceptions/RecursiveConfigException'
import { ConfigNotNormalizedException } from '#src/Exceptions/ConfigNotNormalizedException'
export * from './Env/Env.js'
export * from './Helpers/EnvHelper.js'
/**
* Return the env value if found or the fallback defaultValue.
*
* @param {string} env
* @param {any} [defaultValue]
* @param {boolean} [autoCast]
*/
export function Env(env, defaultValue, autoCast = true) {
const environment = EnvHelper.setEnvInEnv(process.env[env], autoCast)
if (!environment) {
Debug.log(`Variable ${env} not found.`, 'api:environments')
return EnvHelper.setEnvInEnv(defaultValue, autoCast)
}
if (autoCast) {
return EnvHelper.castEnv(environment)
}
return environment
}
export class Config {
/**
* Map structure to save all configuration files.
*
* @type {Map<string, any>}
*/
static configs = new Map()
/**
* Get the value from config file by key. If not

@@ -50,18 +38,92 @@ * found, defaultValue will be used.

static get(key, defaultValue = undefined) {
return SecConfig.get(key, defaultValue)
const [mainKey, ...keys] = key.split('.')
const config = this.configs.get(mainKey)
return Json.get(config, keys.join('.'), defaultValue)
}
/**
* Load all the files that are inside the path.
* Load all configuration files in path.
*
* @param {string} configPath
* @param {string} path
* @return {Promise<void>}
*/
static async load(configPath = Path.config()) {
const { files } = await new Folder(configPath).load()
static async loadAll(path = Path.config()) {
const { files } = await new Folder(path).load()
const promises = files.map(f => new SecConfig().safeLoad(f.path))
const promises = files.map(file => this.safeLoad(file.path))
await Promise.all(promises)
}
/**
* Load the configuration file only if it has
* not been loaded yet.
*
* @param {string} path
* @param {number?} callNumber
* @return {Promise<void>}
*/
static async safeLoad(path, callNumber) {
const { name } = parse(path)
if (this.configs.has(name)) {
return
}
return this.load(path, callNumber)
}
/**
* Load the configuration file.
*
* @param {string} path
* @param {number?} callNumber
* @return {Promise<void>}
*/
static async load(path, callNumber = 0) {
const { dir, name, base, ext } = parse(path)
if (callNumber > 500) {
throw new RecursiveConfigException(path, name)
}
if (base.includes('.js.map') || base.includes('.d.ts')) {
return
}
const file = new File(path).loadSync()
const fileContent = file.getContentSync().toString()
if (
!fileContent.includes('export default') &&
!fileContent.includes('module.exports') &&
!fileContent.includes('exports.default')
) {
throw new ConfigNotNormalizedException(path)
}
if (fileContent.includes('Config.get')) {
const matches = fileContent.match(/Config.get\(([^)]+)\)/g)
for (let match of matches) {
match = match.replace('Config.get', '').replace(/[(^)']/g, '')
const fileName = `${match.split('.')[0]}`
const fileBase = `${fileName}${ext}`
const filePath = `${dir}/${fileBase}`
await this.safeLoad(filePath, callNumber + 1)
}
}
/**
* Add random number to file import path so
* Node.js will not cache the imported file.
*/
const versionedPath = `${file.href}?version=${Math.random()}`
this.configs.set(name, await Module.get(import(versionedPath)))
}
}

@@ -68,0 +130,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc