Description
When a variable's "optionality" (probably not a word - sorry) depends on some other variable, like currentEnv, it would be really convenient if the generated types would reflect this.
In its simplest form, it would be something like this:
# @generateTypes(lang=ts, path=varlock.d.ts)
# @currentEnv=$APP_ENV
# ----------
# @type=enum(dev, staging, prod, building)
# @sensitive={preventLeaks=false}
APP_ENV=dev
# @optional=forEnv(building)
# @sensitive
DATABASE_PASSWORD=
Allowing the user to then make the following checks / assertions:
import { ENV } from 'varlock/env';
if (ENV.APP_ENV !== 'building') {
// in this scope, `ENV.DATABASE_PASSWORD` is of type `string`, and not `string | undefined`.
}
Motivation
The advantage of using varlock for us is not only that we can fetch secrets from one of the plugins before an application is initialized. It is also the fact that variables can depend on other variables, and generally the ability to script the the environment using the various resolver functions.
As we do not want to bake secrets into our docker containers, we have marked nearly every variable as @sensitive (with those that are actually public as @sensitive={preventLeaks=false} - a hack while waiting for #750 - although we cannot import this client-side, but that's outside the scope of this request).
A lot of our server side code needs to be initialized once the container is up and running, thus we a few checks like the one above in our codebase.
Since typescript solves this with discriminated unions, I would be very happy to see the implemented in varlock as well.
Proposed Solution
Generate the type declaration file along the following lines:
type CoercedEnvSchema
= | {
APP_ENV: 'dev' | 'staging' | 'prod';
DATABASE_PASSWORD: string;
} | {
APP_ENV: 'building';
DATABASE_PASSWORD?: string;
};
This is of course simplified - it would probably make sense to destructure the type definition into multiple types, as the complexity increases.
Alternatives
Using the "Non-null assertion" operator (!) on all the affected variables.
Creating a .env.building file, filled with mock variables has not really been a consideration - because that could lead misuse of the DATABASE_PASSWORD variable - trying to instantiate a database connection, when the variable is actually nonsense, making the application throw on build or similar.
With the non-null assertion check the developer manually checks that the environment is set properly.
Additional Information
I get that the complexity of this task quickly becomes huge, as the resolver functions can return more or less anything, so I would suggest limiting the functionality to begin with.
Like only supporting forEnv() in the @optional / @required decorators (and maybe other variables having @type=boolean @required decorators), when generating these type unions.
I would also be willing to assist in coming up with a proper algorithm for generating these types correctly.
Description
When a variable's "optionality" (probably not a word - sorry) depends on some other variable, like
currentEnv, it would be really convenient if the generated types would reflect this.In its simplest form, it would be something like this:
Allowing the user to then make the following checks / assertions:
Motivation
The advantage of using varlock for us is not only that we can fetch secrets from one of the plugins before an application is initialized. It is also the fact that variables can depend on other variables, and generally the ability to script the the environment using the various resolver functions.
As we do not want to bake secrets into our docker containers, we have marked nearly every variable as
@sensitive(with those that are actually public as@sensitive={preventLeaks=false}- a hack while waiting for #750 - although we cannot import this client-side, but that's outside the scope of this request).A lot of our server side code needs to be initialized once the container is up and running, thus we a few checks like the one above in our codebase.
Since typescript solves this with discriminated unions, I would be very happy to see the implemented in varlock as well.
Proposed Solution
Generate the type declaration file along the following lines:
This is of course simplified - it would probably make sense to destructure the type definition into multiple types, as the complexity increases.
Alternatives
Using the "Non-null assertion" operator (
!) on all the affected variables.Creating a
.env.buildingfile, filled with mock variables has not really been a consideration - because that could lead misuse of theDATABASE_PASSWORDvariable - trying to instantiate a database connection, when the variable is actually nonsense, making the application throw on build or similar.With the non-null assertion check the developer manually checks that the environment is set properly.
Additional Information
I get that the complexity of this task quickly becomes huge, as the resolver functions can return more or less anything, so I would suggest limiting the functionality to begin with.
Like only supporting
forEnv()in the@optional/@requireddecorators (and maybe other variables having@type=boolean @requireddecorators), when generating these type unions.I would also be willing to assist in coming up with a proper algorithm for generating these types correctly.