envalid
envalid copied to clipboard
Conditional required env?
Is there a way to conditionally mark ENV vars as required based on the values of other ENV vars?
In my case, I have the following 4 vars:
USE_TLSTLS_CA_CERT_PATHTLS_CERT_PATHTLS_KEY_PATH
If USE_TLS is true, then I want the other three flagged as required. If it is false, then the other three should be optional.
Ooooh, I like that idea! That's not supported now, but I for one would love to see a PR for it π
What about this?
envalid.cleanEnv(process.env, {
USE_TLS: envalid.bool(),
TLS_CA_CERT_PATH: envalid.str({
requiredWhen: 'USE_TLS' // is true
}),
// ...
})
- Should the subject of
requiredWhenalways have to be aboolean? Or should this work for any truthy value? - Should
requiredWhenallow multiple requirements?
Great feature idea, I could see this being pretty useful. I worry that an approach like requiredWhen that takes a string would be a bit too restrictive though. Maybe requiredWhen could point to a function that takes the full raw env object? eg:
envalid.cleanEnv(process.env, {
USE_TLS: envalid.bool(),
TLS_CA_CERT_PATH: envalid.str({
requiredWhen: rawEnv => !!rawEnv.USE_TLS
}),
// ...
})
Maybe
requiredWhencould point to a function that takes the full raw env object?
Seems like it would probably be simpler to implement and answers both of my previous questions too, so that's a π .
Any news about this awesome feature? :)
@antoine-pous check https://github.com/af/envalid/pull/81 PR
@rainum that doesn't answer to my question, actually the feature is not merged and seem inactive from months. In a professional context i can't use a commit from a PR in progress :(
Seems to be a nice feature. I think we need to send a new PR on it.
This would be an awesome feature π
Something like the requiredWhen approach above could still be viable if we pass in the raw env. I'm not sure how we could do it in a type-safe way though.
Something like this is possible already though using TypeScript and the json validator, if you can deal with having the related env vars stored together in json:
import * as e from 'envalid'
// Read env vars from .env
require('dotenv').config()
type TlsJsonType = {
USE_TLS: false,
} | {
USE_TLS: true,
TLS_CA_CERT_PATH: string,
TLS_CERT_PATH: string,
TLS_KEY_PATH: string,
}
const env = e.cleanEnv(process.env, {
// TS type-checks that this default value works with the union type
TLS_CONFIG: e.json<TlsJsonType>({ default: { USE_TLS: false } }),
})
if (env.TLS_CONFIG.USE_TLS) {
// Within this guard clause, TS knows this is a string
console.log(env.TLS_CONFIG.TLS_KEY_PATH)
}
Of course, the json() validator won't validate that particular shape at runtime, but you could create a custom validator that does that work there as well
bumping this issue years later. Any progress?
Any update on this?
No updates, sorryβ I think the approach in this comment is still doable: https://github.com/af/envalid/issues/78#issuecomment-387282133
I haven't had the time to add this but I'd welcome a PR π
const requiredIfEnabledKds = makeValidator((x) => {
const isKdsEnabled = convertToBoolean(process.env. ENABLE_RAPTOR_SQL_LISTENER);
if (isKdsEnabled && !x) {
throw new Error("required when ENABLE_RAPTOR_SQL_LISTENER is enabled");
}
return x;
});
const schema = {
ENABLE_RAPTOR_SQL_LISTENER: bool({ default: false }),
RAPTOR_SQL_DB: requiredIfEnabledSqlQListener(),
RAPTOR_SQL_IS_SSL: requiredIfEnabledSqlQListener(),
};
This is how I did it, remember to either put all the env variables in .env file to trigger the validation or set these as empty otherwise the environment variables will be undefined and the custom validation will not run.