Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional required env? #78

Open
neezer opened this issue May 5, 2018 · 14 comments
Open

Conditional required env? #78

neezer opened this issue May 5, 2018 · 14 comments

Comments

@neezer
Copy link
Contributor

neezer commented May 5, 2018

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.

@SimenB
Copy link
Collaborator

SimenB commented May 6, 2018

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

@neezer
Copy link
Contributor Author

neezer commented May 7, 2018

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?

@af
Copy link
Owner

af commented May 8, 2018

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

@neezer
Copy link
Contributor Author

neezer commented May 8, 2018

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 added a commit to neezer/envalid that referenced this issue May 8, 2018
neezer added a commit to neezer/envalid that referenced this issue May 8, 2018
@antoine-pous
Copy link
Contributor

Any news about this awesome feature? :)

@rainum
Copy link

rainum commented Sep 3, 2019

@antoine-pous check #81 PR

@antoine-pous
Copy link
Contributor

antoine-pous commented Sep 5, 2019

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

@veeramarni
Copy link

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

@clarkey
Copy link

clarkey commented Nov 17, 2020

This would be an awesome feature 👍

@af
Copy link
Owner

af commented Jan 28, 2021

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

@dbrenot-pelmorex
Copy link

bumping this issue years later. Any progress?

@gitSambhal
Copy link

Any update on this?

@af
Copy link
Owner

af commented Apr 7, 2024

No updates, sorry– I think the approach in this comment is still doable: #78 (comment)

I haven't had the time to add this but I'd welcome a PR 👍

@gitSambhal
Copy link

gitSambhal commented Apr 12, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants