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 valueStringifier for reporting #9

Open
wants to merge 2 commits into
base: master
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,12 @@ pass a `DetailedSpec` object that has the following fields:
An object that maps from `NODE_ENV` values to values that will be passed as
input to the schema if this var isn't present in the environment. For example:

- `valueStringifier?: (value: string | TIn) => string`

A function that takes the received value (as a string) or the default value
(as `TIn`, the expected type after parsing) and returns the string that
should be displayed in the error report.

Comment on lines +233 to +238
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for adding documentation! looks like you inserted this in between the description of defaults and its example, so it should be moved downwards. could you also add the use-case of redacting values that you wrote up in the docstring?

```ts
const schemas = {
FRUIT: {
Expand Down
12 changes: 12 additions & 0 deletions src/parse-env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ export type DetailedSpec<
* (For example, `z.number().gte(20).default(50)`.)
*/
defaults?: Record<string, TIn | undefined>;

/**
* A function that takes the received value (as a string) or the default
* value (as `TIn`, the expected type after parsing) and returns the string
* that should be displayed in the error report.
*
* This can be used, for example, to redact sensitive values from error
* reports.
*
* For example, `(value: string) => value.replace(/./g, '*')`.
*/
valueStringifier?: (value: string | TIn) => string;
}
: never;

Expand Down
7 changes: 4 additions & 3 deletions src/reporter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ZodError, ZodErrorMap, ZodIssueCode } from "zod";
import { yellow, red, cyan, green } from "colorette";
import { Schemas } from "./parse-env.js";
import { DetailedSpec, Schemas } from "./parse-env.js";

// Even though we also have our own formatter, we pass a custom error map to
// Zod's `.parse()` for two reasons:
Expand Down Expand Up @@ -34,6 +34,7 @@ export function reportErrors(
const formattedErrors = errors.map(
({ key, receivedValue, error, defaultUsed, defaultValue }) => {
const message: string[] = [`[${yellow(key)}]:`];
const valueStringifier = (schemas[key] as DetailedSpec).valueStringifier ?? JSON.stringify;

if (error instanceof ZodError) {
const { formErrors, fieldErrors } = error.flatten();
Expand Down Expand Up @@ -61,7 +62,7 @@ export function reportErrors(
`(received ${cyan(
receivedValue === undefined
? "undefined"
: JSON.stringify(receivedValue),
: valueStringifier(receivedValue)
)})`,
2,
),
Expand All @@ -73,7 +74,7 @@ export function reportErrors(
`(used default of ${cyan(
defaultValue === undefined
? "undefined"
: JSON.stringify(defaultValue),
: valueStringifier(defaultValue)
)})`,
2,
),
Expand Down
Loading