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

Custom validation extension/custom accessor before as check. #159

Open
PizzaPartyInc opened this issue Aug 15, 2022 · 2 comments
Open

Custom validation extension/custom accessor before as check. #159

PizzaPartyInc opened this issue Aug 15, 2022 · 2 comments

Comments

@PizzaPartyInc
Copy link

Hey!

I know there is already an option to add custom accessors, but those are only going at the end of the evaluation chaing. I'm interested in sort of a middleware approach.

An example scenario would be - We have a .env file like this:

CUSTOM_ENUM=<PLACEHOLDER{identifier}>

For app to be used, placeholder must be replaced with an actual value, which shall be evaluated as a specific enum. So, a custom check is needed in addition to .required() and .asEnum, e.g. something like this:

const placeholderCheck : ExtensionFn<VariableAccessors<unknown>> = (
  accessors: ExtensionFn<VariableAccessors<unknown>>,
  value: string,
): VariableAccessors<unknown> => {
  if (value.match(/^<PLACEHOLDER{.*}>$/)) {
    throw new Error(`placeholder must be replaced with a proper value.`);
  }
  return accessors;
};

const env = from(process.env, { placeholderCheck });
const value = env
      .get('CUSTOM_ENUM')
      .required()
      .placeholderCheck()
      .asEnum<CustomEnum>(['TEST_VALUE_1', 'TEST_VALUE_2']),

The idea is that you want to check the original value first, and then proceed to type assertion. After checking the examples and source code I was not able to find a way to achieve this with the current implementation. If this is indeed possible - it would be nice to update the readme/examples.

Thanks!

@evanshortiss
Copy link
Owner

@PizzaPartyInc (great username BTW), can you expand on why you need this feature?

I'm leaning towards thinking this isn't a problem for env-var to solve. I would generally expect variable names to be defined and known in advance, and env-var is purely used to read and coerce them.

@PizzaPartyInc
Copy link
Author

In our concrete case, we have .env file (not under source control) and .env.template file (under source control).

In the resulting .env file we can have sensitive values (usernames, passwords, connection strings, etc..), and we obviously do not want to store such values under source control. So, values in .env.template (which is used to create .env for local development) are defined as placeholders (e.g. DATABASE_PASSWORD=<SECURE_VALUT_{Vault Collection Name::password}>) with actual pointers to some vault/storage. We came up with a custom script that connects to a secure vault/storage for such values and populates .env with sensitive values.

The proposal to have a middleware checker is to make sure that when the app is launched - the placeholders are actually replaced with concrete values, and if not - throw an error, let the developer know that he needs to adjust the config. ExtensionFn would have been enough, but not all resulting replaced values are guaranteed to be strings. Another option can be an ENUM value or URL. Basically, a custom accessor would be potentially required for a lot of default variable accessors.

Yes, such things can be checked explicitly, before env-var calls, but it would look a bit... strange. E.g. in actual app code, we never call something like process.env.CUSTOM_ENUM, we only pass process.env to a generator function and get a nicely typed and validated object of config values. And in this case, we'd have to add additional validation checks outside of env-var context, while env-var validates everything else...

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

No branches or pull requests

2 participants