remove zod-validation-error from deps by merging. it started causing weird errors. OpenSource FTW
This commit is contained in:
parent
d0f56a3ec4
commit
866541ae03
|
@ -5,7 +5,7 @@ import type { UserConfig } from "./types";
|
||||||
import ghostSitemap from "./src/integrations/sitemap";
|
import ghostSitemap from "./src/integrations/sitemap";
|
||||||
import ghostRobots from "./src/integrations/robots-txt";
|
import ghostRobots from "./src/integrations/robots-txt";
|
||||||
import { loadEnv } from 'vite';
|
import { loadEnv } from 'vite';
|
||||||
import { fromZodError } from "zod-validation-error";
|
import { fromZodError } from "./src/utils/zod-validation/fromZodError.js";
|
||||||
import { addVirtualImport } from "./src/utils/add-virtual-import";
|
import { addVirtualImport } from "./src/utils/add-virtual-import";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
|
@ -104,7 +104,6 @@
|
||||||
"satori-html": "^0.3.2",
|
"satori-html": "^0.3.2",
|
||||||
"vite": "^5.0.12",
|
"vite": "^5.0.12",
|
||||||
"vite-tsconfig-paths": "^4.2.2",
|
"vite-tsconfig-paths": "^4.2.2",
|
||||||
"zod": "^3.22.4",
|
"zod": "^3.22.4"
|
||||||
"zod-validation-error": "^3.0.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import * as zod from 'zod';
|
||||||
|
export class ValidationError extends Error {
|
||||||
|
name;
|
||||||
|
details;
|
||||||
|
constructor(message, options) {
|
||||||
|
super(message, options);
|
||||||
|
this.name = 'ZodValidationError';
|
||||||
|
this.details = getIssuesFromErrorOptions(options);
|
||||||
|
}
|
||||||
|
toString() {
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getIssuesFromErrorOptions(options) {
|
||||||
|
if (options) {
|
||||||
|
const cause = options.cause;
|
||||||
|
if (cause instanceof zod.ZodError) {
|
||||||
|
return cause.issues;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
export const ISSUE_SEPARATOR = '; ';
|
||||||
|
export const MAX_ISSUES_IN_MESSAGE = 99;
|
||||||
|
export const PREFIX = 'Validation error';
|
||||||
|
export const PREFIX_SEPARATOR = ': ';
|
||||||
|
export const UNION_SEPARATOR = ', or ';
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { fromZodIssue } from './fromZodIssue';
|
||||||
|
export const errorMap = (issue, ctx) => {
|
||||||
|
const error = fromZodIssue({
|
||||||
|
...issue,
|
||||||
|
message: issue.message ?? ctx.defaultError,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
message: error.message,
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { ISSUE_SEPARATOR, MAX_ISSUES_IN_MESSAGE, PREFIX, PREFIX_SEPARATOR, UNION_SEPARATOR, } from './config';
|
||||||
|
import { getMessageFromZodIssue } from './fromZodIssue';
|
||||||
|
import { prefixMessage } from './prefixMessage';
|
||||||
|
import { ValidationError } from './ValidationError';
|
||||||
|
export function fromZodError(zodError, options = {}) {
|
||||||
|
const { maxIssuesInMessage = MAX_ISSUES_IN_MESSAGE, issueSeparator = ISSUE_SEPARATOR, unionSeparator = UNION_SEPARATOR, prefixSeparator = PREFIX_SEPARATOR, prefix = PREFIX, includePath = true, } = options;
|
||||||
|
const zodIssues = zodError.errors;
|
||||||
|
const reason = zodIssues.length === 0
|
||||||
|
? zodError.message
|
||||||
|
: zodIssues
|
||||||
|
.slice(0, maxIssuesInMessage)
|
||||||
|
.map((issue) => getMessageFromZodIssue({
|
||||||
|
issue,
|
||||||
|
issueSeparator,
|
||||||
|
unionSeparator,
|
||||||
|
includePath,
|
||||||
|
}))
|
||||||
|
.join(issueSeparator);
|
||||||
|
const message = prefixMessage(reason, prefix, prefixSeparator);
|
||||||
|
return new ValidationError(message, { cause: zodError });
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
import * as zod from 'zod';
|
||||||
|
import { ISSUE_SEPARATOR, PREFIX, PREFIX_SEPARATOR, UNION_SEPARATOR, } from './config';
|
||||||
|
import { prefixMessage } from './prefixMessage';
|
||||||
|
import { joinPath } from './utils/joinPath';
|
||||||
|
import { isNonEmptyArray } from './utils/NonEmptyArray';
|
||||||
|
import { ValidationError } from './ValidationError';
|
||||||
|
export function getMessageFromZodIssue(props) {
|
||||||
|
const { issue, issueSeparator, unionSeparator, includePath } = props;
|
||||||
|
if (issue.code === 'invalid_union') {
|
||||||
|
return issue.unionErrors
|
||||||
|
.reduce((acc, zodError) => {
|
||||||
|
const newIssues = zodError.issues
|
||||||
|
.map((issue) => getMessageFromZodIssue({
|
||||||
|
issue,
|
||||||
|
issueSeparator,
|
||||||
|
unionSeparator,
|
||||||
|
includePath,
|
||||||
|
}))
|
||||||
|
.join(issueSeparator);
|
||||||
|
if (!acc.includes(newIssues)) {
|
||||||
|
acc.push(newIssues);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, [])
|
||||||
|
.join(unionSeparator);
|
||||||
|
}
|
||||||
|
if (includePath && isNonEmptyArray(issue.path)) {
|
||||||
|
if (issue.path.length === 1) {
|
||||||
|
const identifier = issue.path[0];
|
||||||
|
if (typeof identifier === 'number') {
|
||||||
|
return `${issue.message} at index ${identifier}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return `${issue.message} at "${joinPath(issue.path)}"`;
|
||||||
|
}
|
||||||
|
return issue.message;
|
||||||
|
}
|
||||||
|
export function fromZodIssue(issue, options = {}) {
|
||||||
|
const { issueSeparator = ISSUE_SEPARATOR, unionSeparator = UNION_SEPARATOR, prefixSeparator = PREFIX_SEPARATOR, prefix = PREFIX, includePath = true, } = options;
|
||||||
|
const reason = getMessageFromZodIssue({
|
||||||
|
issue,
|
||||||
|
issueSeparator,
|
||||||
|
unionSeparator,
|
||||||
|
includePath,
|
||||||
|
});
|
||||||
|
const message = prefixMessage(reason, prefix, prefixSeparator);
|
||||||
|
return new ValidationError(message, { cause: new zod.ZodError([issue]) });
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
export { ValidationError } from './ValidationError';
|
||||||
|
export { isValidationError } from './isValidationError';
|
||||||
|
export { isValidationErrorLike } from './isValidationErrorLike';
|
||||||
|
export { errorMap } from './errorMap';
|
||||||
|
export { fromZodIssue, } from './fromZodIssue';
|
||||||
|
export { fromZodError, } from './fromZodError';
|
||||||
|
export { toValidationError } from './toValidationError';
|
|
@ -0,0 +1,4 @@
|
||||||
|
import { ValidationError } from './ValidationError';
|
||||||
|
export function isValidationError(err) {
|
||||||
|
return err instanceof ValidationError;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
export function isValidationErrorLike(err) {
|
||||||
|
return err instanceof Error && err.name === 'ZodValidationError';
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { PREFIX } from './config';
|
||||||
|
export function prefixMessage(message, prefix, prefixSeparator) {
|
||||||
|
if (prefix !== null) {
|
||||||
|
if (message.length > 0) {
|
||||||
|
return [prefix, message].join(prefixSeparator);
|
||||||
|
}
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
if (message.length > 0) {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
return PREFIX;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import * as zod from 'zod';
|
||||||
|
import { fromZodError } from './fromZodError';
|
||||||
|
import { ValidationError } from './ValidationError';
|
||||||
|
export const toValidationError = (options = {}) => (err) => {
|
||||||
|
if (err instanceof zod.ZodError) {
|
||||||
|
return fromZodError(err, options);
|
||||||
|
}
|
||||||
|
if (err instanceof Error) {
|
||||||
|
return new ValidationError(err.message, { cause: err });
|
||||||
|
}
|
||||||
|
return new ValidationError('Unknown error');
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
export function isNonEmptyArray(value) {
|
||||||
|
return value.length !== 0;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
const identifierRegex = /[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/u;
|
||||||
|
export function joinPath(path) {
|
||||||
|
if (path.length === 1) {
|
||||||
|
return path[0].toString();
|
||||||
|
}
|
||||||
|
return path.reduce((acc, item) => {
|
||||||
|
if (typeof item === 'number') {
|
||||||
|
return acc + '[' + item.toString() + ']';
|
||||||
|
}
|
||||||
|
if (item.includes('"')) {
|
||||||
|
return acc + '["' + escapeQuotes(item) + '"]';
|
||||||
|
}
|
||||||
|
if (!identifierRegex.test(item)) {
|
||||||
|
return acc + '["' + item + '"]';
|
||||||
|
}
|
||||||
|
const separator = acc.length === 0 ? '' : '.';
|
||||||
|
return acc + separator + item;
|
||||||
|
}, '');
|
||||||
|
}
|
||||||
|
function escapeQuotes(str) {
|
||||||
|
return str.replace(/"/g, '\\"');
|
||||||
|
}
|
Loading…
Reference in New Issue