Skip to content

feat: add warning spec attribute - #257

Open
vergiLgood1 wants to merge 1 commit into
af:mainfrom
vergiLgood1:feat/warning-option
Open

vergiLgood1 wants to merge 1 commit into
af:mainfrom
vergiLgood1:feat/warning-option

Conversation

@vergiLgood1

Copy link
Copy Markdown

Summary

Adds an optional warning message to validator specs. When an env var is not set and a fallback value (default, devDefault, or testDefault) is used, the message is surfaced by the reporter without failing the program.

Closes #220

Design decision

The issue's example uses str({ warning: "..." }) with no default and implies the app should keep running ("App will run but it will not send any email"). However, making warning implicitly turn a required var into an optional one would conflict with the library's philosophy (a program should only run when its environment dependencies are met) and could silently weaken validation — e.g. someone adding a warning message to a required database password var.

So this PR keeps optionality explicit, consistent with how default: undefined already works:

const env = cleanEnv(process.env, {
  EMAIL_SMTP: str({
    default: undefined,
    warning: 'EMAIL_SMTP is not set. App will run but it will not send any email.',
  }),
})
// Program runs, value is undefined, and the warning is logged.

With a concrete fallback, the warning fires when that fallback is used:

const env = cleanEnv(process.env, {
  RETRIES: str({ default: '3', warning: 'RETRIES not set, using default 3' }),
})

I'm happy to adjust if a different behavior (e.g. warning implying optionality) is preferred.

Changes

  • src/types.ts — new warning?: string on Spec<T>; new optional warnings field on ReporterOptions<T>
  • src/core.ts — getSanitizedEnv records a warning whenever the env var was not set and a fallback (testDefault / devDefault / default) was used, and passes warnings to the reporter. With reporter: null the caller opts out of all reporting, including warnings (errors are still thrown, as before)
  • src/reporter.ts — defaultReporter prints a Warnings: section (same visual style as the error sections). Warnings never affect the exit behavior: with only warnings the process exits normally; with errors the existing error/exit flow is unchanged
  • README.md — documents the new attribute
  • tests/warning.test.ts — new: warning recorded for default / devDefault / testDefault fallbacks, no warning when the var is set, missing var without any fallback still errors, reporter: null behavior, and type-level assertions (optionality still driven by default: undefined, not by warning)
  • tests/reporter.test.ts — new: warnings printed without exiting, warnings + errors printed together with exit preserved, warnings sorted
  • tests/requiredWhen.test.ts — updated to match the new reporter call signature (warnings: {})

Verification

  • bun run ts ✅
  • bun run lint ✅
  • bun run test:ci ✅ (82 tests, 8 files)
  • bun run coverage ✅ (functions 100%, lines 98.89% — above the 98% thresholds)

Example output:

 =================================
  Warnings:
     EMAIL_SMTP: EMAIL_SMTP is not set. App will run but it will not send any email.
 =================================

Logs an optional warning message (without failing) whenever an env var
is not set and a fallback value (default/devDefault/testDefault) is used.
Closes af#220
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

Successfully merging this pull request may close these issues.

Add a warn option

1 participant