You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

zod-validation-error

Package Overview
Dependencies
Maintainers
0
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zod-validation-error - npm Package Compare versions

Comparing version

to
4.0.0

2

package.json
{
"name": "zod-validation-error",
"version": "4.0.0-beta.2",
"version": "4.0.0",
"description": "Wrap zod validation errors in user-friendly readable messages",

@@ -5,0 +5,0 @@ "keywords": [

@@ -11,6 +11,6 @@ # zod-validation-error

- Preserves original error details accessible via `error.details`;
- Provides a custom error map for automatic message formatting;
- Provides a custom error map for better user-friendly messages;
- Supports both Zod v3 and v4.
**_Note:_** This version of `zod-validation-error` works with zod v4. If you are looking for zod v3 support, please click [here](./README.v3.md)
**_Note:_** This version of `zod-validation-error` works with zod v4. If you are looking for zod v3 support, please refer to the [v3 documentation](./README.v3.md)

@@ -31,5 +31,13 @@ ## Installation

```typescript
import { z as zod } from 'zod/v4';
import { fromError } from 'zod-validation-error';
import { z as zod } from 'zod';
import { fromError, createErrorMap } from 'zod-validation-error';
// configure zod to use zod-validation-error's error map
// this is optional, you may also use your own custom error map or zod's native error map
// we recommend using zod-validation-error's error map for better user-friendly messages
// see https://zod.dev/error-customization for further details
zod.config({
customError: createErrorMap(),
});
// create zod schema

@@ -107,3 +115,3 @@ const zodSchema = zod.object({

Main `ValidationError` class, extending native JavaScript `Error`.
Main `ValidationError` class, extending JavaScript's native `Error`.

@@ -128,3 +136,3 @@ #### Arguments

```typescript
import { z as zod } from 'zod/v4';
import { z as zod } from 'zod';
import { ValidationError } from 'zod-validation-error';

@@ -153,5 +161,5 @@

Meant to be passed as an option to [fromError](#fromerror), [fromZodIssue](#fromzodissue), [fromZodError](#fromzoderror), [toValidationError](#tovalidationerror) or [MessageBuilder](#MessageBuilder).
We think that zod's native error map is not user-friendly enough, so we provide our own implementation that formats issues into human-readable messages.
Note: zod-validation-error's `errorMap` is an errorMap like all others and thus can also be used directly with `zod` (see https://zod.dev/error-customization for further details).
Note: zod-validation-error's `errorMap` is an errorMap like all others and thus can also be used directly with `zod` (see https://zod.dev/error-customization for further details), e.g.

@@ -164,19 +172,15 @@ #### Arguments

| Name | Type | Description |
| ------------------------------- | :-------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `includePath` | `boolean` | Indicates whether to include the erroneous property key in the error message (optional, defaults to `true`) |
| `displayInvalidFormatDetails` | `boolean` | Indicates whether to display invalid format details (e.g. regexp pattern) in the error message (optional, defaults to `false`) |
| `maxAllowedValuesToDisplay` | `number` | Max number of allowed values to display (optional, defaults to 10) |
| `allowedValuesSeparator` | `string` | Used to concatenate allowed values in the message (optional, defaults to `", "`) |
| `allowedValuesLastSeparator` | `string \| undefined` | Used to concatenate last allowed value in the message (optional, defaults to `" or "`). Set to `undefined` to disable last separator. |
| `wrapAllowedValuesInQuote` | `boolean` | Indicates whether to wrap allowed values in quotes (optional, defaults to `true`). Note that this only applies to string values. |
| `maxUnrecognizedKeysToDisplay` | `number` | Max number of unrecognized keys to display in the error message (optional, defaults to `5`) |
| `unrecognizedKeysSeparator` | `string` | Used to concatenate unrecognized keys in the message (optional, defaults to `", "`) |
| `unrecognizedKeysLastSeparator` | `string \| undefined` | Used to concatenate the last unrecognized key in message (optional, defaults to `" and "`). Set to `undefined` to disable last separator. |
| `wrapUnrecognizedKeysInQuote` | `boolean` | Indicates whether to wrap unrecognized keys in quotes (optional, defaults to `true`). Note that this only applies to string keys. |
| `issuesInTitleCase` | `boolean` | Indicates whether to convert issues to title case (optional, defaults to `true`). |
| `unionSeparator` | `string` | Used to concatenate union-issues in user-friendly message (optional, defaults to `" or "`) |
| `issueSeparator` | `string` | Used to concatenate issues in user-friendly message (optional, defaults to `";"`) |
| `dateLocalization` | `boolean \| Intl.LocalesArgument` | Indicates whether to localize date values in the error message (optional, defaults to `true`). If set to `true`, it will use the default locale of the environment. You can also pass an `Intl.LocalesArgument` to specify a custom locale. |
| `numberLocalization` | `boolean \| Intl.LocalesArgument` | Indicates whether to localize number values in the error message (optional, defaults to `true`). If set to `true`, it will use the default locale of the environment. You can also pass an `Intl.LocalesArgument` to specify a custom locale. |
| Name | Type | Description |
| ------------------------------- | :-------------------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `displayInvalidFormatDetails` | `boolean` | Indicates whether to display invalid format details (e.g. regexp pattern) in the error message (optional, defaults to `false`) |
| `maxAllowedValuesToDisplay` | `number` | Max number of allowed values to display (optional, defaults to `10`). Allowed values beyond this limit will be hidden. |
| `allowedValuesSeparator` | `string` | Used to concatenate allowed values in the message (optional, defaults to `", "`) |
| `allowedValuesLastSeparator` | `string \| undefined` | Used to concatenate last allowed value in the message (optional, defaults to `" or "`). Set to `undefined` to disable. |
| `wrapAllowedValuesInQuote` | `boolean` | Indicates whether to wrap allowed values in quotes (optional, defaults to `true`). Note that this only applies to string values. |
| `maxUnrecognizedKeysToDisplay` | `number` | Max number of unrecognized keys to display in the error message (optional, defaults to `5`) |
| `unrecognizedKeysSeparator` | `string` | Used to concatenate unrecognized keys in the message (optional, defaults to `", "`) |
| `unrecognizedKeysLastSeparator` | `string \| undefined` | Used to concatenate the last unrecognized key in message (optional, defaults to `" and "`). Set to `undefined` to disable. |
| `wrapUnrecognizedKeysInQuote` | `boolean` | Indicates whether to wrap unrecognized keys in quotes (optional, defaults to `true`). Note that this only applies to string keys. |
| `dateLocalization` | `boolean \| Intl.LocalesArgument` | Indicates whether to localize date values (optional, defaults to `true`). If set to `true`, it will use the default locale of the environment. You can also pass `Intl.LocalesArgument` to specify a custom locale. |
| `numberLocalization` | `boolean \| Intl.LocalesArgument` | Indicates whether to localize numeric values (optional, defaults to `true`). If set to `true`, it will use the default locale of the environment. You can also pass `Intl.LocalesArgument` to specify a custom locale. |

@@ -186,7 +190,10 @@ #### Example

```typescript
import { z as zod } from 'zod';
import { createErrorMap } from 'zod-validation-error';
const messageBuilder = createErrorMap({
includePath: false,
maxAllowedValuesToDisplay: 3,
zod.config({
customError: createErrorMap({
// default values are used when not specified
displayInvalidFormatDetails: true,
}),
});

@@ -207,9 +214,11 @@ ```

| Name | Type | Description |
| -------------------- | :-------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `maxIssuesInMessage` | `number` | Max issues to include in user-friendly message (optional, defaults to `99`) |
| `issueSeparator` | `string` | Used to concatenate issues in user-friendly message (optional, defaults to `";"`) |
| `prefix` | `string \| undefined` | Prefix to use in user-friendly message (optional, defaults to `"Validation error"`). Pass `undefined` to disable prefix completely. |
| `prefixSeparator` | `string` | Used to concatenate prefix with rest of the user-friendly message (optional, defaults to `": "`). Not used when `prefix` is `undefined`. |
| `error` | `ErrorMap \| false` | Accepts an `errorMap` to format individual issues into user-friendly error messages (optional). When set to `false` it will return the message as formatted by `zod`. Note that this is an optional property and if not provided, the default zod-validation-error error map will be used. You can use your own custom errorMap if you want. |
| Name | Type | Description |
| -------------------- | :-------------------: | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `maxIssuesInMessage` | `number` | Max issues to include in user-friendly message (optional, defaults to `99`) |
| `issueSeparator` | `string` | Used to concatenate issues in user-friendly message (optional, defaults to `";"`) |
| `unionSeparator` | `string` | Used to concatenate union-issues in user-friendly message (optional, defaults to `" or "`) |
| `prefix` | `string \| undefined` | Prefix to use in user-friendly message (optional, defaults to `"Validation error"`). Pass `undefined` to disable prefix completely. |
| `prefixSeparator` | `string` | Used to concatenate prefix with rest of the user-friendly message (optional, defaults to `": "`). Not used when `prefix` is `undefined`. |
| `includePath` | `boolean` | Indicates whether to include the erroneous property key in the error message (optional, defaults to `true`) |
| `forceTitleCase` | `boolean` | Indicates whether to convert individual issue messages to title case (optional, defaults to `true`). |

@@ -219,9 +228,7 @@ #### Example

```typescript
import { createErrorMap, createMessageBuilder } from 'zod-validation-error';
import { createMessageBuilder } from 'zod-validation-error';
const messageBuilder = createMessageBuilder({
maxIssuesInMessage: 3,
error: createErrorMap({
includePath: false,
}),
includePath: false,
});

@@ -241,3 +248,3 @@ ```

```typescript
import { z as zod } from 'zod/v4';
import { z as zod } from 'zod';
import { ValidationError, isValidationError } from 'zod-validation-error';

@@ -289,3 +296,3 @@

```typescript
import { z as zod } from 'zod/v4';
import { z as zod } from 'zod';
import { ValidationError, isZodErrorLike } from 'zod-validation-error';

@@ -327,3 +334,3 @@

Alternatively, you may pass [createMessageBuilder options](#createMessageBuilder) directly as `options`. These will be used as arguments to create the `MessageBuilder` instance internally.
Alternatively, you may pass [createMessageBuilder options](#createmessagebuilder-options) directly as `options`. These will be used as arguments to create the `MessageBuilder` instance internally.

@@ -342,3 +349,3 @@ ### fromZodIssue

Alternatively, you may pass [createMessageBuilder options](#createMessageBuilder) directly as `options`. These will be used as arguments to create the `MessageBuilder` instance internally.
Alternatively, you may pass [createMessageBuilder options](#createmessagebuilder-options) directly as `options`. These will be used as arguments to create the `MessageBuilder` instance internally.

@@ -359,3 +366,3 @@ ### fromZodError

Alternatively, you may pass [createMessageBuilder options](#createMessageBuilder) directly as `options`. These will be used as arguments to create the `MessageBuilder` instance internally.
Alternatively, you may pass [createMessageBuilder options](#createmessagebuilder-optionscreateMessageBuilder) directly as `options`. These will be used as arguments to create the `MessageBuilder` instance internally.

@@ -374,3 +381,3 @@ ### toValidationError

import * as Either from 'fp-ts/Either';
import { z as zod } from 'zod/v4';
import { z as zod } from 'zod';
import { toValidationError, ValidationError } from 'zod-validation-error';

@@ -401,3 +408,3 @@

1. **End-user focus**: zod-validation-error provides opinionated, user-friendly error messages designed to be displayed directly to end-users in forms or API responses, whereas Zod's native error handling seem more developer-focused.
1. **End-user focus**: zod-validation-error provides opinionated, user-friendly error messages designed to be displayed directly to end-users in forms or API responses.
1. **Customization options**: zod-validation-error offers extensive configuration for message formatting, such as controlling path inclusion, allowed values display, localization, and more.

@@ -409,2 +416,12 @@ 1. **Error handling**: zod-validation-error maintains the original error details while providing a clean, consistent interface through the ValidationError class.

### Do I need to use `zod-validation-error`'s error map?
No, you can use zod's native error map if you prefer. However, we recommend using `zod-validation-error`'s error map for better user-friendly messages.
You may also use your own custom error map if you have specific requirements, e.g. internationalization.
### Where can I see how `zod-validation-error`'s error map formatting works?
The easiest way to understand how `zod-validation-error`'s error map works is to look at the [tests](./lib/v4/errorMap/errorMap.test.ts). They cover various scenarios and demonstrate how the error map formats issues into user-friendly messages.
### How to distinguish between errors

@@ -472,4 +489,4 @@

```typescript
import { z as zod } from 'zod/v4';
import { fromError, createErrorMap } from 'zod-validation-error';
import { z as zod } from 'zod';
import { createErrorMap } from 'zod-validation-error';

@@ -492,3 +509,3 @@ zod.config({

```typescript
const { ValidationError } = require('zod-validation-error/v4');
const { ValidationError } = require('zod-validation-error');
```

@@ -495,0 +512,0 @@

@@ -29,3 +29,3 @@ # zod-validation-error

```typescript
import { z as zod } from 'zod';
import { z as zod } from 'zod/v3';
import { fromError } from 'zod-validation-error/v3';

@@ -123,3 +123,3 @@

```typescript
import { z as zod } from 'zod';
import { z as zod } from 'zod/v3';
const { ValidationError } = require('zod-validation-error');

@@ -177,3 +177,3 @@

```typescript
import { z as zod } from 'zod';
import { z as zod } from 'zod/v3';
import { errorMap } from 'zod-validation-error/v3';

@@ -195,3 +195,3 @@

```typescript
import { z as zod } from 'zod';
import { z as zod } from 'zod/v3';
import { ValidationError, isValidationError } from 'zod-validation-error/v3';

@@ -246,3 +246,3 @@

```typescript
import { z as zod } from 'zod';
import { z as zod } from 'zod/v3';
import { ValidationError, isZodErrorLike } from 'zod-validation-error/v3';

@@ -354,3 +354,3 @@

import * as Either from 'fp-ts/Either';
import { z as zod } from 'zod';
import { z as zod } from 'zod/v3';
import { toValidationError, ValidationError } from 'zod-validation-error/v3';

@@ -384,3 +384,3 @@

```typescript
import { z as zod } from 'zod';
import { z as zod } from 'zod/v3';
import { type MessageBuilder, fromError } from 'zod-validation-error/v3';

@@ -439,3 +439,3 @@ import chalk from 'chalk';

import * as Either from 'fp-ts/Either';
import { z as zod } from 'zod';
import { z as zod } from 'zod/v3';
import { isValidationErrorLike } from 'zod-validation-error/v3';

@@ -494,3 +494,3 @@

```typescript
import { z as zod } from 'zod';
import { z as zod } from 'zod/v3';
import { errorMap } from 'zod-validation-error/v3';

@@ -506,3 +506,3 @@

```typescript
import { z as zod } from 'zod';
import { z as zod } from 'zod/v3';
import { fromZodIssue } from 'zod-validation-error/v3';

@@ -509,0 +509,0 @@

@@ -21,8 +21,4 @@ import * as zod from 'zod/v4/core';

type ErrorMapOptions = {
includePath: boolean;
dateLocalization: boolean | Intl.LocalesArgument;
numberLocalization: boolean | Intl.LocalesArgument;
unionSeparator: string;
issueSeparator: string;
issuesInTitleCase: boolean;
displayInvalidFormatDetails: boolean;

@@ -50,3 +46,5 @@ allowedValuesSeparator: string;

issueSeparator: string;
error: zod.$ZodErrorMap<zod.$ZodIssue> | false;
unionSeparator: string;
includePath: boolean;
forceTitleCase: boolean;
};

@@ -53,0 +51,0 @@ declare function createMessageBuilder(partialOptions?: Partial<MessageBuilderOptions>): MessageBuilder;

@@ -85,87 +85,11 @@ "use strict";

// lib/utils/stringify.ts
function stringifySymbol(symbol) {
return symbol.description ?? "";
// lib/v4/errorMap/custom.ts
function parseCustomIssue(issue) {
return {
type: issue.code,
path: issue.path,
message: issue.message
};
}
function stringify(value, options = {}) {
switch (typeof value) {
case "symbol":
return stringifySymbol(value);
case "bigint":
case "number": {
switch (options.localization) {
case true:
return value.toLocaleString();
case false:
return value.toString();
default:
return value.toLocaleString(options.localization);
}
}
case "string": {
if (options.wrapStringValueInQuote) {
return `"${value}"`;
}
return value;
}
default: {
if (value instanceof Date) {
switch (options.localization) {
case true:
return value.toLocaleString();
case false:
return value.toISOString();
default:
return value.toLocaleString(options.localization);
}
}
return String(value);
}
}
}
// lib/utils/joinPath.ts
var identifierRegex = /[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/u;
function joinPath(path) {
if (path.length === 1) {
let propertyKey = path[0];
if (typeof propertyKey === "symbol") {
propertyKey = stringifySymbol(propertyKey);
}
return propertyKey.toString() || '""';
}
return path.reduce((acc, propertyKey) => {
if (typeof propertyKey === "number") {
return acc + "[" + propertyKey.toString() + "]";
}
if (typeof propertyKey === "symbol") {
propertyKey = stringifySymbol(propertyKey);
}
if (propertyKey.includes('"')) {
return acc + '["' + escapeQuotes(propertyKey) + '"]';
}
if (!identifierRegex.test(propertyKey)) {
return acc + '["' + propertyKey + '"]';
}
const separator = acc.length === 0 ? "" : ".";
return acc + separator + propertyKey;
}, "");
}
function escapeQuotes(str) {
return str.replace(/"/g, '\\"');
}
// lib/utils/NonEmptyArray.ts
function isNonEmptyArray(value) {
return value.length !== 0;
}
// lib/utils/titleCase.ts
function titleCase(value) {
if (value.length === 0) {
return value;
}
return value.charAt(0).toUpperCase() + value.slice(1);
}
// lib/v4/errorMap/invalidElement.ts

@@ -180,2 +104,11 @@ function parseInvalidElementIssue(issue) {

// lib/v4/errorMap/invalidKey.ts
function parseInvalidKeyIssue(issue) {
return {
type: issue.code,
path: issue.path,
message: `unexpected key in ${issue.origin}`
};
}
// lib/v4/errorMap/invalidStringFormat.ts

@@ -322,2 +255,52 @@ function parseInvalidStringFormatIssue(issue, options = {

// lib/v4/errorMap/invalidUnion.ts
function parseInvalidUnionIssue(issue) {
return {
type: issue.code,
path: issue.path,
message: issue.message
};
}
// lib/utils/stringify.ts
function stringifySymbol(symbol) {
return symbol.description ?? "";
}
function stringify(value, options = {}) {
switch (typeof value) {
case "symbol":
return stringifySymbol(value);
case "bigint":
case "number": {
switch (options.localization) {
case true:
return value.toLocaleString();
case false:
return value.toString();
default:
return value.toLocaleString(options.localization);
}
}
case "string": {
if (options.wrapStringValueInQuote) {
return `"${value}"`;
}
return value;
}
default: {
if (value instanceof Date) {
switch (options.localization) {
case true:
return value.toLocaleString();
case false:
return value.toISOString();
default:
return value.toLocaleString(options.localization);
}
}
return String(value);
}
}
}
// lib/utils/joinValues.ts

@@ -397,3 +380,3 @@ function joinValues(values, options) {

path: issue.path,
message: `number must be less ${issue.inclusive ? "or equal to" : "than"} ${maxValueStr}`
message: `number must be less than${issue.inclusive ? " or equal to" : ""} ${maxValueStr}`
};

@@ -440,3 +423,3 @@ }

path: issue.path,
message: `value must be less ${issue.inclusive ? "or equal to" : "than"} ${maxValueStr}`
message: `value must be less than${issue.inclusive ? " or equal to" : ""} ${maxValueStr}`
};

@@ -460,3 +443,3 @@ }

path: issue.path,
message: `number must be greater ${issue.inclusive ? "or equal to" : "than"} ${minValueStr}`
message: `number must be greater than${issue.inclusive ? " or equal to" : ""} ${minValueStr}`
};

@@ -503,3 +486,3 @@ }

path: issue.path,
message: `value must be greater ${issue.inclusive ? "or equal to" : "than"} ${minValueStr}`
message: `value must be greater than${issue.inclusive ? " or equal to" : ""} ${minValueStr}`
};

@@ -524,22 +507,3 @@ }

// lib/v4/errorMap/invalidKey.ts
function parseInvalidKeyIssue(issue) {
return {
type: issue.code,
path: issue.path,
message: `unexpected key in ${issue.origin}`
};
}
// lib/v4/errorMap/custom.ts
function parseCustomIssue(issue) {
return {
type: issue.code,
path: issue.path,
message: issue.message
};
}
// lib/v4/errorMap/errorMap.ts
var BRAND = Symbol.for("zod-validation-error-map");
var issueParsers = {

@@ -555,28 +519,6 @@ invalid_type: parseInvalidTypeIssue,

invalid_key: parseInvalidKeyIssue,
custom: parseCustomIssue,
invalid_union: parseInvalidUnionIssue
custom: parseInvalidUnionIssue,
invalid_union: parseCustomIssue
};
function parseInvalidUnionIssue(issue, options) {
const errorMap = createErrorMap(options);
const individualMessages = issue.errors.map(
(issues) => issues.map(
(subIssue) => errorMap({
...subIssue,
path: issue.path.concat(subIssue.path)
})
).join(options.issueSeparator)
);
const message = Array.from(new Set(individualMessages)).join(
options.unionSeparator
);
return {
type: issue.code,
path: [],
message
};
}
var defaultErrorMapOptions = {
includePath: true,
unionSeparator: " or ",
issueSeparator: "; ",
displayInvalidFormatDetails: false,

@@ -591,15 +533,10 @@ allowedValuesSeparator: ", ",

maxUnrecognizedKeysToDisplay: 5,
issuesInTitleCase: true,
dateLocalization: true,
numberLocalization: true
};
function equalsDefaultOptions(options) {
for (const key in options) {
if (options[key] !== defaultErrorMapOptions[key]) {
return false;
}
}
return true;
}
function makeErrorMap(options) {
function createErrorMap(partialOptions = {}) {
const options = {
...defaultErrorMapOptions,
...partialOptions
};
const errorMap = (issue) => {

@@ -611,51 +548,52 @@ if (issue.code === void 0) {

const ast = parseFunc(issue, options);
return toString(ast, options);
return ast.message;
};
Object.defineProperty(errorMap, "_brand", {
value: BRAND,
writable: false,
enumerable: false,
configurable: false
});
return errorMap;
}
var defaultErrorMap = makeErrorMap(defaultErrorMapOptions);
function createErrorMap(partialOptions = {}) {
const options = {
...defaultErrorMapOptions,
...partialOptions
};
if (equalsDefaultOptions(options)) {
return defaultErrorMap;
}
return makeErrorMap(options);
// lib/utils/NonEmptyArray.ts
function isNonEmptyArray(value) {
return value.length !== 0;
}
function toString(ast, options) {
const buf = [];
if (options.issuesInTitleCase) {
buf.push(titleCase(ast.message));
} else {
buf.push(ast.message);
// lib/utils/joinPath.ts
var identifierRegex = /[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/u;
function joinPath(path) {
if (path.length === 1) {
let propertyKey = path[0];
if (typeof propertyKey === "symbol") {
propertyKey = stringifySymbol(propertyKey);
}
return propertyKey.toString() || '""';
}
pathCondition: if (options.includePath && ast.path !== void 0 && isNonEmptyArray(ast.path)) {
if (ast.path.length === 1) {
const identifier = ast.path[0];
if (typeof identifier === "number") {
buf.push(` at index ${identifier}`);
break pathCondition;
}
return path.reduce((acc, propertyKey) => {
if (typeof propertyKey === "number") {
return acc + "[" + propertyKey.toString() + "]";
}
buf.push(` at "${joinPath(ast.path)}"`);
}
return buf.join("");
if (typeof propertyKey === "symbol") {
propertyKey = stringifySymbol(propertyKey);
}
if (propertyKey.includes('"')) {
return acc + '["' + escapeQuotes(propertyKey) + '"]';
}
if (!identifierRegex.test(propertyKey)) {
return acc + '["' + propertyKey + '"]';
}
const separator = acc.length === 0 ? "" : ".";
return acc + separator + propertyKey;
}, "");
}
function isZodValidationErrorMap(errorMap) {
return "_brand" in errorMap && errorMap._brand === BRAND;
function escapeQuotes(str) {
return str.replace(/"/g, '\\"');
}
// lib/utils/titleCase.ts
function titleCase(value) {
if (value.length === 0) {
return value;
}
return value.charAt(0).toUpperCase() + value.slice(1);
}
// lib/v4/MessageBuilder.ts
var zod = __toESM(require("zod/v4/core"));
var identityErrorMap = (issue) => {
return issue.message;
};
var defaultMessageBuilderOptions = {

@@ -666,4 +604,6 @@ prefix: "Validation error",

// I've got 99 problems but the b$tch ain't one
issueSeparator: defaultErrorMapOptions.issueSeparator,
error: defaultErrorMap
unionSeparator: " or ",
issueSeparator: "; ",
includePath: true,
forceTitleCase: true
};

@@ -675,14 +615,40 @@ function createMessageBuilder(partialOptions = {}) {

};
const errorMap = (
// user requested not to format errors by explicitly setting error to false
options.error === false || // we have already formatted errors with zod-validation-error
// using the zod.config() API
// thus we should not format them again for performance reasons
partialOptions.error === void 0 && zod.globalConfig.customError !== void 0 && isZodValidationErrorMap(zod.globalConfig.customError) ? identityErrorMap : options.error
);
return function messageBuilder(issues) {
const message = issues.slice(0, options.maxIssuesInMessage).map(errorMap).join(options.issueSeparator);
const message = issues.slice(0, options.maxIssuesInMessage).map((issue) => mapIssue(issue, options)).join(options.issueSeparator);
return conditionallyPrefixMessage(message, options);
};
}
function mapIssue(issue, options) {
if (issue.code === "invalid_union") {
const individualMessages = issue.errors.map(
(issues) => issues.map(
(subIssue) => mapIssue(
{
...subIssue,
path: issue.path.concat(subIssue.path)
},
options
)
).join(options.issueSeparator)
);
return Array.from(new Set(individualMessages)).join(options.unionSeparator);
}
const buf = [];
if (options.forceTitleCase) {
buf.push(titleCase(issue.message));
} else {
buf.push(issue.message);
}
pathCondition: if (options.includePath && issue.path !== void 0 && isNonEmptyArray(issue.path)) {
if (issue.path.length === 1) {
const identifier = issue.path[0];
if (typeof identifier === "number") {
buf.push(` at index ${identifier}`);
break pathCondition;
}
}
buf.push(` at "${joinPath(issue.path)}"`);
}
return buf.join("");
}
function conditionallyPrefixMessage(message, options) {

@@ -745,3 +711,3 @@ if (options.prefix != null) {

// lib/v4/fromZodIssue.ts
var zod2 = __toESM(require("zod/v4/core"));
var zod = __toESM(require("zod/v4/core"));
function fromZodIssue(issue, options = {}) {

@@ -751,3 +717,3 @@ const messageBuilder = createMessageBuilderFromOptions2(options);

return new ValidationError(message, {
cause: new zod2.$ZodRealError([issue])
cause: new zod.$ZodRealError([issue])
});

@@ -754,0 +720,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet