@incanta/config
Advanced tools
Comparing version 0.4.4 to 0.5.0
@@ -11,2 +11,5 @@ export interface IConfigOptions { | ||
private envVarConfig; | ||
private secretsToken; | ||
private secretsCache; | ||
private secretsCacheExpiration; | ||
constructor(options?: IConfigOptions); | ||
@@ -18,2 +21,5 @@ init(options?: IConfigOptions): void; | ||
getWithParts<T>(keyParts: string[]): T; | ||
refreshSecrets(): Promise<void>; | ||
getWithSecrets<T>(key: string): Promise<T>; | ||
private processSecrets; | ||
normalizeString(value: string, currentPath: string[]): string; | ||
@@ -20,0 +26,0 @@ normalizeArray(arr: any[], currentPath: string[]): any[]; |
@@ -10,2 +10,3 @@ "use strict"; | ||
const loader_1 = require("./loader"); | ||
const provider_1 = require("./secrets/provider"); | ||
class Config { | ||
@@ -17,2 +18,5 @@ configDir = ""; | ||
envVarConfig; | ||
secretsToken = null; | ||
secretsCache = {}; | ||
secretsCacheExpiration = null; | ||
constructor(options) { | ||
@@ -25,2 +29,5 @@ this.init(options); | ||
this.customValues = {}; | ||
this.secretsToken = null; | ||
this.secretsCache = {}; | ||
this.secretsCacheExpiration = null; | ||
let defaultConfigDir = "config"; | ||
@@ -107,2 +114,57 @@ let defaultConfigEnv = "default"; | ||
} | ||
async refreshSecrets() { | ||
const provider = (0, provider_1.GetSecretsProvider)(this.normalizedValues.secrets.provider); | ||
if (this.secretsToken === null || | ||
this.secretsToken.expires.getTime() < Date.now() + 500) { | ||
this.secretsToken = await provider.getAuthToken(); | ||
} | ||
this.secretsCache = await provider.getSecrets(this, this.secretsToken.value); | ||
this.secretsCacheExpiration = new Date(Date.now() + this.get("secrets.cache-duration-seconds") * 1000); | ||
} | ||
async getWithSecrets(key) { | ||
let value = this.get(key); | ||
const provider = this.normalizedValues.secrets?.provider; | ||
if (typeof provider === "string" && provider !== provider_1.SecretsProviderType.None) { | ||
value = await this.processSecrets(value); | ||
} | ||
return value; | ||
} | ||
async processSecrets(v) { | ||
if (typeof v === "string" && v.startsWith("secret|")) { | ||
const secretKey = v.slice(7); | ||
const provider = (0, provider_1.GetSecretsProvider)(this.normalizedValues.secrets.provider); | ||
if (this.secretsToken === null || | ||
this.secretsToken.expires.getTime() < Date.now() + 500) { | ||
this.secretsToken = await provider.getAuthToken(); | ||
} | ||
if (this.secretsCacheExpiration === null || | ||
this.secretsCacheExpiration < new Date() || | ||
this.secretsCache[secretKey] === undefined) { | ||
this.secretsCache = await provider.getSecrets(this, this.secretsToken.value); | ||
this.secretsCacheExpiration = new Date(Date.now() + this.get("secrets.cache-duration-seconds") * 1000); | ||
} | ||
if (this.secretsCache[secretKey] === undefined) { | ||
throw new Error(`Secret ${secretKey} not found`); | ||
} | ||
return this.secretsCache[secretKey]; | ||
} | ||
else if (typeof v === "object" && v !== null) { | ||
if (Array.isArray(v)) { | ||
const newObjs = []; | ||
for (const value of v) { | ||
newObjs.push(await this.processSecrets(value)); | ||
} | ||
return newObjs; | ||
} | ||
else { | ||
const newObj = {}; | ||
for (const key of Object.keys(v)) { | ||
const value = v[key]; | ||
newObj[key] = await this.processSecrets(value); | ||
} | ||
return newObj; | ||
} | ||
} | ||
return v; | ||
} | ||
normalizeString(value, currentPath) { | ||
@@ -109,0 +171,0 @@ let result = value; |
{ | ||
"name": "@incanta/config", | ||
"version": "0.4.4", | ||
"version": "0.5.0", | ||
"main": "lib/index.js", | ||
@@ -21,2 +21,3 @@ "exports": { | ||
"dependencies": { | ||
"axios": "^1.7.2", | ||
"js-yaml": "^4.1.0", | ||
@@ -23,0 +24,0 @@ "json5": "^2.2.3", |
@@ -5,2 +5,3 @@ import merge from "lodash.merge"; | ||
import { Loader } from "./loader"; | ||
import { GetSecretsProvider, SecretsProviderType } from "./secrets/provider"; | ||
@@ -21,2 +22,9 @@ export interface IConfigOptions { | ||
private secretsToken: { | ||
value: string; | ||
expires: Date; | ||
} | null = null; | ||
private secretsCache: Record<string, any> = {}; | ||
private secretsCacheExpiration: Date | null = null; | ||
public constructor(options?: IConfigOptions) { | ||
@@ -30,2 +38,5 @@ this.init(options); | ||
this.customValues = {}; | ||
this.secretsToken = null; | ||
this.secretsCache = {}; | ||
this.secretsCacheExpiration = null; | ||
@@ -161,2 +172,86 @@ let defaultConfigDir = "config"; | ||
public async refreshSecrets(): Promise<void> { | ||
const provider = GetSecretsProvider(this.normalizedValues.secrets.provider); | ||
if ( | ||
this.secretsToken === null || | ||
this.secretsToken.expires.getTime() < Date.now() + 500 | ||
) { | ||
this.secretsToken = await provider.getAuthToken(); | ||
} | ||
this.secretsCache = await provider.getSecrets( | ||
this, | ||
this.secretsToken.value | ||
); | ||
this.secretsCacheExpiration = new Date( | ||
Date.now() + this.get<number>("secrets.cache-duration-seconds") * 1000 | ||
); | ||
} | ||
public async getWithSecrets<T>(key: string): Promise<T> { | ||
let value = this.get<T>(key); | ||
const provider = this.normalizedValues.secrets?.provider; | ||
if (typeof provider === "string" && provider !== SecretsProviderType.None) { | ||
value = await this.processSecrets(value); | ||
} | ||
return value; | ||
} | ||
private async processSecrets<T>(v: T): Promise<T> { | ||
if (typeof v === "string" && v.startsWith("secret|")) { | ||
const secretKey = v.slice(7); | ||
const provider = GetSecretsProvider( | ||
this.normalizedValues.secrets.provider | ||
); | ||
if ( | ||
this.secretsToken === null || | ||
this.secretsToken.expires.getTime() < Date.now() + 500 | ||
) { | ||
this.secretsToken = await provider.getAuthToken(); | ||
} | ||
if ( | ||
this.secretsCacheExpiration === null || | ||
this.secretsCacheExpiration < new Date() || | ||
this.secretsCache[secretKey] === undefined | ||
) { | ||
this.secretsCache = await provider.getSecrets( | ||
this, | ||
this.secretsToken.value | ||
); | ||
this.secretsCacheExpiration = new Date( | ||
Date.now() + this.get<number>("secrets.cache-duration-seconds") * 1000 | ||
); | ||
} | ||
if (this.secretsCache[secretKey] === undefined) { | ||
throw new Error(`Secret ${secretKey} not found`); | ||
} | ||
return this.secretsCache[secretKey] as T; | ||
} else if (typeof v === "object" && v !== null) { | ||
if (Array.isArray(v)) { | ||
const newObjs: any[] = []; | ||
for (const value of v) { | ||
newObjs.push(await this.processSecrets(value)); | ||
} | ||
return newObjs as T; | ||
} else { | ||
const newObj: any = {}; | ||
for (const key of Object.keys(v)) { | ||
const value = (v as any)[key]; | ||
newObj[key] = await this.processSecrets(value); | ||
} | ||
return newObj as T; | ||
} | ||
} | ||
return v; | ||
} | ||
public normalizeString(value: string, currentPath: string[]): string { | ||
@@ -163,0 +258,0 @@ let result = value; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
72686
32
1319
5
10
+ Addedaxios@^1.7.2
+ Addedasynckit@0.4.0(transitive)
+ Addedaxios@1.7.9(transitive)
+ Addedcombined-stream@1.0.8(transitive)
+ Addeddelayed-stream@1.0.0(transitive)
+ Addedfollow-redirects@1.15.9(transitive)
+ Addedform-data@4.0.1(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
+ Addedproxy-from-env@1.1.0(transitive)