envalid icon indicating copy to clipboard operation
envalid copied to clipboard

Conditional required env?

Open neezer opened this issue 7 years ago β€’ 16 comments

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_TLS
  • TLS_CA_CERT_PATH
  • TLS_CERT_PATH
  • TLS_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.

neezer avatar May 05 '18 17:05 neezer

Ooooh, I like that idea! That's not supported now, but I for one would love to see a PR for it πŸ™‚

SimenB avatar May 06 '18 09:05 SimenB

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 requiredWhen always have to be a boolean? Or should this work for any truthy value?
  • Should requiredWhen allow multiple requirements?

neezer avatar May 07 '18 02:05 neezer

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
  }),
  // ...
})

af avatar May 08 '18 04:05 af

Maybe requiredWhen could 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 πŸ‘ .

neezer avatar May 08 '18 06:05 neezer

Any news about this awesome feature? :)

antoine-pous avatar Aug 06 '19 09:08 antoine-pous

@antoine-pous check https://github.com/af/envalid/pull/81 PR

rainum avatar Sep 03 '19 09:09 rainum

@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 :(

antoine-pous avatar Sep 05 '19 15:09 antoine-pous

Seems to be a nice feature. I think we need to send a new PR on it.

veeramarni avatar Jan 25 '20 23:01 veeramarni

This would be an awesome feature πŸ‘

clarkey avatar Nov 17 '20 19:11 clarkey

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

af avatar Jan 28 '21 05:01 af

bumping this issue years later. Any progress?

dbrenot-pelmorex avatar Jun 14 '23 20:06 dbrenot-pelmorex

Any update on this?

gitSambhal avatar Apr 04 '24 10:04 gitSambhal

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 πŸ‘

af avatar Apr 07 '24 21:04 af

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.

gitSambhal avatar Apr 12 '24 06:04 gitSambhal