keithmorris / node-dotenv-extended

A module for loading .env files and optionally loading defaults and a schema for validating all values are present.
MIT License
111 stars 24 forks source link

Only return vars present in schema / filter out vars not in schema from (`load`) result? #49

Open emme1444 opened 3 years ago

emme1444 commented 3 years ago

How would I go about filtering out all variables coming from the system, that is not present in the .schema file. i.e. those I do not need in my app, pretty much.

Thanks!

keithmorris commented 3 years ago

@emme1444 you should be able to do something like this:

const myConfig = require('dotenv-extended').load();

in this example, myConfig should now only contain the data within the .env file and not from process.env which will contain both the .env and system variables.

Let me know if that helps.

emme1444 commented 3 years ago

@keithmorris I sincerely apologize for my lack of specificity on the subject. My options object looks more like the following:

dotenvExtended.load({
  encoding: "utf-8",
  path: ".env",
  defaults: ".env.defaults",
  schema: ".env.schema",
  errorOnExtra: true,
  errorOnMissing: true,
  errorOnRegex: true,
  assignToProcessEnv: false,
  includeProcessEnv: true,
});

So if I may rephrase my question; how would I go about doing what is discussed with the above options? (namely includeProcessEnv: true)

If I understand correcly, setting includeProcessEnv to true seems to be what causes this. However, I still need it set to true since, correct me if I'm wrong, this is what tells dotenv-extended to check for missing and/or incorrect keys (according to regex in schema).

Again, I apologize for not being specific enough, and thank you for your time!

keithmorris commented 3 years ago

@emme1444 I'm not sure I fully understand your question. It sounds like when using the library as you describe above, you want process.env to contain only the variables that are defined within the .env.schema file. This is not possible becuase process.env is populated from system environment variables and this library can (optionally) add to the properties in process.env by setting the assignToProcessEnv to true.

The only way you can get just the items in your .env file is to capture the call to the library into a variable like this:

const myEnvVariables = dotenvExtended.load({
  encoding: "utf-8",
  path: ".env",
  defaults: ".env.defaults",
  schema: ".env.schema",
  errorOnExtra: true,
  errorOnMissing: true,
  errorOnRegex: true,
  assignToProcessEnv: false,
  includeProcessEnv: true,
});

Now you should be able to use the variables from the .env file by referencing them from the myEnvVariables constant. e.g. myEnvVariables.mySetting1 instead of process.env.mySetting1

The includeProcessEnv is only for error checking against the schema. It checks if the variable required in the schema is in either the .env file or exists on process.env.

Let me know if that helps.

emme1444 commented 3 years ago

Hey @keithmorris! I apologize again! I'll do my best to describe my problem. This time with sufficient examples.

It sounds like when using the library as you describe above, you want process.env to contain only the variables that are defined within the .env.schema file.

Actually, what I'd like is for the return value of dotenvExtended.load to only include those keys defined in the .env.schema file.

You say:

The includeProcessEnv is only for error checking against the schema. It checks if the variable required in the schema is in either the .env file or exists on process.env.

The problem is that when setting includeProcessEnv to true, not only is process.env included when validating (like you say), but is also merged and returned by the dotenvExtended.load function. This is somewhat annoying as it populates the object returned by the function with a bunch of variables I do not care for within my application. For context, I'd like to minimize the object, as I'm using functionality to replace a global object with these variables within a client-side application. Thus the smaller the object; the better.

Here is a simple example of the above statement:

const dotenvExtended = require("dotenv-extended");

const parsedEnv = dotenvExtended.load({
  errorOnExtra: true,
  errorOnMissing: true,
  errorOnRegex: true,
  assignToProcessEnv: false,
  includeProcessEnv: false,
});

parsedEnv === { 
  API_URL: 'hello'
};

The only problem with the above example is that includeProcessEnv is set to false. Which means variables overriden using process.env won't be included when validating. Which is something I'd like. Well, includeProcessEnv seems to be what I'm looking for! Okay? So let's set includeProcessEnv to true:

const dotenvExtended = require("dotenv-extended");

const parsedEnv = dotenvExtended.load({
  errorOnExtra: true,
  errorOnMissing: true,
  errorOnRegex: true,
  assignToProcessEnv: false,
  includeProcessEnv: true,
});

parsedEnv === {
  API_URL: 'hello',
  PATH: '...',
  PS1: '\\e[0;36m\\w\\e[0;32m \\e[0;35m$\\e[m ',
  TMP: 'C:\\Users\\user\\AppData\\Local\\Temp',
  USERNAME: 'user',
  // etc...
};

Hmm...? Now the returned object contains all the variables present in the .env.schema file, merged with those present in process.env. Not something I'd prefer.

My question then is: How would I go about filtering out these variables (PATH, PS1 etc...)? Or really: Is this intentional or not? Would it make sense for the library to automatically filter out the variables from this returned object, even if includeProcessEnv is set to true? I think so. What do you think?

I hope this helps illustrate my problem. And I again apologize for taking your time. Thank you so much!

.env.schema ``` API_URL= ```
.env.defaults ```ini API_URL=hello ```