Schema
One of the core features of varlock is its schema-driven approach to environment variables - which is best when shared with your team and committed to version control. We recommend creating a new .env.schema file to hold schema info set by config item decorators, non-sensitive default values, and root decorators to specify global settings that affect varlock itself.
This schema should include all of the environment variables that your application depends on, along with comments and documentation about them, and decorators which affect coercion, validation, and generated types / documentation.
The more complete your schema is, the more validation and coercion varlock can perform, and the more it can help you catch errors earlier in your development cycle.
Running
varlock initwill attempt to convert an existing.env.examplefile into a.env.schemafile. It must be reviewed, but it should be a good starting point.
Root Decorators
Section titled “Root Decorators”The header section of a .env file is a comment block at the beginning of the file that ends with a divider. Within this header, you can use root decorators to specify global settings and default behavior for all config items.
# This is the header, and may contain root decorators# @currentEnv=$APP_ENV# @defaultSensitive=false @defaultRequired=false# @generateTypes(lang=ts, path=env.d.ts)# ---
# This is a config item comment block and may contain decorators which affect only the item# @required @type=enum(dev, test, staging, prod)APP_ENV=devMore details:
Config Items
Section titled “Config Items”Config items are the environment variables that your application depends on. Like normal .env syntax, each item is a key-value pair of the form KEY=value. The key is the name of the environment variable, and a value may be specified or not.
While simply enumerating all of them in your .env.schema is useful (like a .env.example file), @env-spec allows us to attach additional comments and item decorators, making our schema much more powerful.
Item Values
Section titled “Item Values”Values may be static, or set using functions, which can facilitate loading values from external sources without exposing any sensitive values.
Quote rules:
- Static values can be wrapped in quotes or not — all quotes styles (
`,",') are supported - Values wrapped in single quotes do not support expansion
- Single line values may not contain newlines, but
\nwill be converted to an actual newline except in single quotes - Multiline values can be wrapped in
```,""". Also supported is"and'but not recommended. - Unquoted values will be parsed as a number/boolean/undefined where possible (
ITEM=foo->"foo", whileITEM=true->true), however data-types may further coerce values - No value (undefined) and empty string ("") are distinct
NO_VALUE= # will resolve to undefinedEMPTY_STRING_VALUE="" # will resolve to empty stringSTATIC_VALUE_UNQUOTED=quotes are optional # but are recommended!STATIC_VALUE_QUOTED="#hashtag" # and are necessary in some casesBOOLEAN_VALUE=trueNUMERIC_VALUE=123.456FUNCTION_VALUE=exec(`op read "op://api-config/item/credential"`)EXPANSION_VALUE=${OTHER_VAR}-suffixMULTILINE_VALUE="""multiplelines"""Item comments
Section titled “Item comments”Comments are used to attach additional documentation and metadata to config items using item decorators. This additional metadata is used by varlock to perform validation, coercion, and generate types / documentation.
Multiple comment lines directly preceeding an item will be attached to that item. A blank line or a divider (# ---) break a comment block, and detach it from the following config item.
Comment lines can either contain regular comments or item decorators. Note that if a line does not start with a decorator, it will be treated as a regular comment.
# description of item can be multiple lines# this @decorator will be ignored because the line does not start with @# @sensitive=false @required # decorator lines can end with a comment# @type=string(startsWith=pk-) # multiple lines of decorators are allowedSERVICE_X_PUBLISHABLE_KEY=pk-abc123More details:
Resolver Functions
Section titled “Resolver Functions”You may use resolver functions instead of static values within both config items and decorator values.
Functions may be composed together to create more complex value resolution logic.
# @required=forEnv(prod)API_DOMAIN=if(eq(ref(APP_ENV), prod), api.myapp.com, staging-api.myapp.com)Referencing other values
Section titled “Referencing other values”Within values and function args, you often need to reference other env vars within your schema.
You may use ref() but we support expansion syntax (like many other .env tools) for convenience.
Both $ITEM and ${ITEM} are equivalent to ref(ITEM).
We recommend using the bracket version only when used within a larger string.
WITH_BRACKETS=exec(`op read "op://${OP_VAULT_NAME}/service/api-key"`)NO_BRACKETS=fallback($OTHERVAR, foo)Read more about string expansion in the @env-spec reference.
Decorator details
Section titled “Decorator details”Functions vs single use
Section titled “Functions vs single use”Most decorators take a single value (e.g., @sensitive, @currentEnv) and may be used only once per item (or file in the case of a root decorator). Some decorators however, are function calls (e.g., @docs(), @import()) and may be called multiple times.
# @sensitive=true# @docs(https://xyzapi.com/docs/auth)# @docs(https://xyzapi.com/manage-api-keys)XYZ_API_KEY=Value resolution
Section titled “Value resolution”Values passed to decorators will be resolved, meaning if a decorator is expecting a boolean, either a static true/false or a resolver function that resolves to a boolean may be used.
# @required=falseNEVER_REQUIRED=
# @required=forEnv(prod) # resolves to true/false depending on the current environmentREQUIRED_FOR_PROD=