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

Add support for config.isStaging #227

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ env.ADMIN_EMAIL // -> '[email protected]'
// Envalid checks for NODE_ENV automatically, and provides the following
// shortcut (boolean) properties for checking its value:
env.isProduction // true if NODE_ENV === 'production'
env.isProd // true if NODE_ENV === 'production'
env.isStaging // true if NODE_ENV === 'staging'
env.isTest // true if NODE_ENV === 'test'
env.isDevelopment // true if NODE_ENV === 'development'
env.isDev // true if NODE_ENV === 'development'
```

Expand Down
4 changes: 3 additions & 1 deletion src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const strictProxyMiddleware = <T extends object>(
}

export const accessorMiddleware = <T>(envObj: T, rawEnv: unknown) => {
// Attach is{Prod/Dev/Test} properties for more readable NODE_ENV checks
// Attach is{Prod/Stage/Dev/Test} properties for more readable NODE_ENV checks
// Note that isDev and isProd are just aliases to isDevelopment and isProduction

// @ts-ignore attempt to read NODE_ENV even if it's not in the spec
Expand All @@ -76,6 +76,8 @@ export const accessorMiddleware = <T>(envObj: T, rawEnv: unknown) => {
Object.defineProperties(envObj, {
isDevelopment: { value: computedNodeEnv === 'development' },
isDev: { value: computedNodeEnv === 'development' },
isStaging: { value: computedNodeEnv === 'staging' },
isStage: { value: computedNodeEnv === 'staging' },
isProduction: { value: isProd },
isProd: { value: isProd },
isTest: { value: computedNodeEnv === 'test' },
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ export interface CleanedEnvAccessors {
/** true if NODE_ENV === 'test' */
readonly isTest: boolean

/** true if NODE_ENV === 'staging' */
readonly isStaging: boolean
readonly isStage: boolean

/** true if NODE_ENV === 'production' */
readonly isProduction: boolean
readonly isProd: boolean
Expand Down
16 changes: 14 additions & 2 deletions tests/basics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,11 @@ describe('NODE_ENV built-in support', () => {
// (this was changed in v7). You need to create your own NODE_ENV validation if you want this to
// happen.
//
// The isProduction/isTest/isDev properties are still supported out of the box for
// 'production'/'test'/'development', respectively
// The isProduction/isStaging/isTest/isDev properties are still supported out of the box for
// 'production'/'staging'/'test'/'development', respectively
test('no longer validates NODE_ENV by default', () => {
expect(cleanEnv({ NODE_ENV: 'production' }, {})).toEqual({})
expect(cleanEnv({ NODE_ENV: 'staging' }, {})).toEqual({})
expect(cleanEnv({ NODE_ENV: 'development' }, {})).toEqual({})
expect(cleanEnv({ NODE_ENV: 'test' }, {})).toEqual({})

Expand All @@ -193,13 +194,17 @@ describe('NODE_ENV built-in support', () => {
test('accessor helpers via middleware work as expected', () => {
expect(cleanEnv({ NODE_ENV: 'production' }, {}).isProduction).toEqual(true)
expect(cleanEnv({ NODE_ENV: 'production' }, {}).isProd).toEqual(true)
expect(cleanEnv({ NODE_ENV: 'staging' }, {}).isStaging).toEqual(true)
expect(cleanEnv({ NODE_ENV: 'staging' }, {}).isStage).toEqual(true)
expect(cleanEnv({ NODE_ENV: 'test' }, {}).isTest).toEqual(true)
expect(cleanEnv({ NODE_ENV: 'development' }, {}).isDev).toEqual(true)
expect(cleanEnv({ NODE_ENV: 'development' }, {}).isDevelopment).toEqual(true)

// assume production if NODE_ENV is not specified:
expect(cleanEnv({}, {}).isProduction).toEqual(true)
expect(cleanEnv({}, {}).isProd).toEqual(true)
expect(cleanEnv({}, {}).isStage).toEqual(false)
expect(cleanEnv({}, {}).isStaging).toEqual(false)
expect(cleanEnv({}, {}).isDev).toEqual(false)
expect(cleanEnv({}, {}).isDevelopment).toEqual(false)
expect(cleanEnv({}, {}).isTest).toEqual(false)
Expand All @@ -208,6 +213,8 @@ describe('NODE_ENV built-in support', () => {
const unsetEnv = cleanEnv({ NODE_ENV: '' }, {})
expect(unsetEnv.isProduction).toEqual(true)
expect(unsetEnv.isProd).toEqual(true)
expect(unsetEnv.isStaging).toEqual(false)
expect(unsetEnv.isStage).toEqual(false)
expect(unsetEnv.isDev).toEqual(false)
expect(unsetEnv.isDevelopment).toEqual(false)
})
Expand All @@ -219,6 +226,8 @@ describe('NODE_ENV built-in support', () => {
expect(cleanEnv({}, customSpec)).toEqual({ NODE_ENV: 'FOO' })
expect(cleanEnv({}, customSpec).isProduction).toEqual(false)
expect(cleanEnv({}, customSpec).isProd).toEqual(false)
expect(cleanEnv({}, customSpec).isStaging).toEqual(false)
expect(cleanEnv({}, customSpec).isStage).toEqual(false)
expect(cleanEnv({}, customSpec).isDev).toEqual(false)
expect(cleanEnv({}, customSpec).isDevelopment).toEqual(false)
})
Expand All @@ -242,6 +251,9 @@ test('testOnly', () => {
process.env.NODE_ENV = 'production'
expect(() => cleanEnv({ NODE_ENV: 'production' }, makeSpec(), makeSilent)).toThrow()

process.env.NODE_ENV = 'staging'
expect(() => cleanEnv({ NODE_ENV: 'staging' }, makeSpec(), makeSilent)).toThrow()

process.env.NODE_ENV = 'development'
expect(() => cleanEnv({ NODE_ENV: 'development' }, makeSpec(), makeSilent)).toThrow()
process.env.NODE_ENV = processEnv
Expand Down