Merge branch 'main' of https://repos.hackathon.bz.it/2025-summer/team-1
This commit is contained in:
commit
e22ad91601
640 changed files with 101753 additions and 31 deletions
|
@ -2,7 +2,7 @@ FROM python:3.13.5-alpine
|
|||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk update && apk add git
|
||||
RUN apk update && apk add git ffmpeg
|
||||
|
||||
RUN git clone --depth 1 'https://github.com/yt-dlp/yt-dlp.git' /yt-dlp
|
||||
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import dotenv
|
||||
from flask import Flask, Response, jsonify, request
|
||||
from flask_cors import CORS
|
||||
|
||||
import dotenv
|
||||
from .room import Room
|
||||
from .song import init_db
|
||||
|
||||
from . import song_fetch
|
||||
|
||||
dotenv.load_dotenv()
|
||||
|
||||
|
||||
|
|
|
@ -21,9 +21,7 @@ def lastfm_search(query: str) -> tuple[str, str]:
|
|||
return track_info["name"], track_info["artist"]
|
||||
|
||||
|
||||
def lastfm_getinfo(
|
||||
name: str, artist: str
|
||||
) -> tuple[str, str, str, str, list[str]]: # ( id, image_id, tags )
|
||||
def lastfm_getinfo(name: str, artist: str) -> tuple[str, str, str, str, list[str]]: # ( id, image_id, tags )
|
||||
response = requests.get(
|
||||
url="https://ws.audioscrobbler.com/2.0/?method=track.getInfo&format=json",
|
||||
params={
|
||||
|
@ -44,20 +42,23 @@ def lastfm_getinfo(
|
|||
)
|
||||
|
||||
|
||||
print(yt_dlp, flush=True)
|
||||
def download_song_mp3(name: str, artist: str) -> tuple[str, str] | None: # ( id, audio )
|
||||
ydl_opts = {
|
||||
"format": "bestaudio",
|
||||
"default_search": "ytsearch1",
|
||||
"outtmpl": "%(title)s.%(ext)s",
|
||||
"skip_download": True,
|
||||
}
|
||||
|
||||
# # def get_yt_mp3link(name: str, artist: str) -> str: ...
|
||||
# # os.popen("/yt-dlp ")
|
||||
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
||||
info = ydl.extract_info(f"{name!r} - {artist!r}", download=False)
|
||||
|
||||
# # /yt-dlp/yt-dlp.sh "ytsearch1:Never gonna give you up" --get-url -f "ba"
|
||||
first_entry = info["entries"][0]
|
||||
|
||||
# import json
|
||||
video_id = first_entry["id"]
|
||||
|
||||
# print(json.dumps(lastfm_getinfo(*lastfm_search("money")), indent=2))
|
||||
# exit(1)
|
||||
for fmt in first_entry["formats"]:
|
||||
if "acodec" in fmt and fmt["acodec"] != "none":
|
||||
return video_id, fmt["url"]
|
||||
|
||||
|
||||
# # def
|
||||
|
||||
|
||||
# ## query ==> lastfm ==> list of songs ==> take first ==> request song info ==> get YT link ==> save in DB ==>
|
||||
return None
|
||||
|
|
29
frontend/src/lib/components/QueueSlider.svelte
Normal file
29
frontend/src/lib/components/QueueSlider.svelte
Normal file
|
@ -0,0 +1,29 @@
|
|||
<script lang="ts">
|
||||
let { songs, playing } = $props()
|
||||
|
||||
let displaySongs = $derived([
|
||||
playing > 0 && playing < songs.length ? songs[playing - 1] : { name: "", image: "" },
|
||||
songs[playing],
|
||||
playing == songs.length - 1 ? { name: "", image: "" } : songs[playing + 1],
|
||||
])
|
||||
</script>
|
||||
|
||||
<div class="relative flex w-full justify-center overflow-hidden">
|
||||
<div class="flex w-fit flex-row gap-4">
|
||||
{#each displaySongs as song, i}
|
||||
{#if song.name != ""}
|
||||
<div class={`relative flex flex-col items-center transition-all duration-300 ${i === 1 ? "z-10 mx-2 scale-100" : "z-0 opacity-70"}`}>
|
||||
<img
|
||||
class="h-[60vw] max-h-[250px] w-[60vw]
|
||||
max-w-[250px] rounded object-cover transition-all duration-300"
|
||||
src={song.image}
|
||||
alt="Song cover"
|
||||
/>
|
||||
{#if i === 1}
|
||||
<h1 class="mt-2">{song.name}</h1>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
7
frontend/src/lib/components/SuggestionInput.svelte
Normal file
7
frontend/src/lib/components/SuggestionInput.svelte
Normal file
|
@ -0,0 +1,7 @@
|
|||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<div class="flex h-full w-full flex-row items-center gap-2 rounded border-2 border-black p-4">
|
||||
<input type="text" placeholder="Song & Artist" class="h-full w-3/4 rounded" />
|
||||
<button class="w-1/4 rounded">Send</button>
|
||||
</div>
|
2
frontend/src/lib/components/SuggestionList.svelte
Normal file
2
frontend/src/lib/components/SuggestionList.svelte
Normal file
|
@ -0,0 +1,2 @@
|
|||
<script lang="ts">
|
||||
</script>
|
|
@ -1 +0,0 @@
|
|||
// place files you want to import through the `$lib` alias in this folder.
|
8
frontend/src/lib/types.ts
Normal file
8
frontend/src/lib/types.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import * as z from "zod"
|
||||
|
||||
export const SongSchema = z.object({
|
||||
name: z.string(),
|
||||
image: z.string(),
|
||||
})
|
||||
|
||||
export type Song = z.infer<typeof SongSchema>
|
|
@ -4,6 +4,4 @@
|
|||
let { children } = $props()
|
||||
</script>
|
||||
|
||||
<div class="bg-red-500 w-full h-max">
|
||||
{@render children()}
|
||||
</div>
|
||||
{@render children()}
|
||||
|
|
|
@ -1,12 +1,36 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from "svelte"
|
||||
import QueueSlider from "$lib/components/QueueSlider.svelte"
|
||||
import SuggestionInput from "$lib/components/SuggestionInput.svelte"
|
||||
|
||||
let text = $state("...")
|
||||
onMount(async () => {
|
||||
let res = await fetch("/api")
|
||||
text = await res.text()
|
||||
})
|
||||
let songs = $state([
|
||||
{
|
||||
name: "Prima",
|
||||
image: "https://s2.qwant.com/thumbr/474x474/5/9/bcbd0c0aeb1838f6916bf452c557251d7be985a13449e49fccb567a3374d4e/OIP.pmqEiKWv47zViDGgPgbbQAHaHa.jpg?u=https%3A%2F%2Ftse.mm.bing.net%2Fth%2Fid%2FOIP.pmqEiKWv47zViDGgPgbbQAHaHa%3Fr%3D0%26pid%3DApi&q=0&b=1&p=0&a=0",
|
||||
},
|
||||
{
|
||||
name: "Io e i miei banchi - Paul Ham",
|
||||
image: "https://i.prcdn.co/img?regionKey=RbtvKb5E1Cv4j1VWm2uGrw%3D%3D",
|
||||
},
|
||||
{
|
||||
name: "Terza",
|
||||
image: "https://s2.qwant.com/thumbr/474x474/5/9/bcbd0c0aeb1838f6916bf452c557251d7be985a13449e49fccb567a3374d4e/OIP.pmqEiKWv47zViDGgPgbbQAHaHa.jpg?u=https%3A%2F%2Ftse.mm.bing.net%2Fth%2Fid%2FOIP.pmqEiKWv47zViDGgPgbbQAHaHa%3Fr%3D0%26pid%3DApi&q=0&b=1&p=0&a=0",
|
||||
},
|
||||
{
|
||||
name: "Quarta",
|
||||
image: "https://s2.qwant.com/thumbr/474x474/5/9/bcbd0c0aeb1838f6916bf452c557251d7be985a13449e49fccb567a3374d4e/OIP.pmqEiKWv47zViDGgPgbbQAHaHa.jpg?u=https%3A%2F%2Ftse.mm.bing.net%2Fth%2Fid%2FOIP.pmqEiKWv47zViDGgPgbbQAHaHa%3Fr%3D0%26pid%3DApi&q=0&b=1&p=0&a=0",
|
||||
},
|
||||
{
|
||||
name: "Quinta",
|
||||
image: "https://s2.qwant.com/thumbr/474x474/5/9/bcbd0c0aeb1838f6916bf452c557251d7be985a13449e49fccb567a3374d4e/OIP.pmqEiKWv47zViDGgPgbbQAHaHa.jpg?u=https%3A%2F%2Ftse.mm.bing.net%2Fth%2Fid%2FOIP.pmqEiKWv47zViDGgPgbbQAHaHa%3Fr%3D0%26pid%3DApi&q=0&b=1&p=0&a=0",
|
||||
},
|
||||
])
|
||||
|
||||
let playing = $state(1)
|
||||
</script>
|
||||
|
||||
<h1>Welcome to SvelteKit</h1>
|
||||
<p class="text-2xl text-red-500">{text}</p>
|
||||
<div class="flex w-full flex-col items-center justify-center p-4 lg:p-10">
|
||||
<QueueSlider {songs} {playing} />
|
||||
<div class="w-full py-6">
|
||||
<SuggestionInput />
|
||||
</div>
|
||||
</div>
|
||||
|
|
16
node_modules/.package-lock.json
generated
vendored
Normal file
16
node_modules/.package-lock.json
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "team-1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/zod": {
|
||||
"version": "4.0.14",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-4.0.14.tgz",
|
||||
"integrity": "sha512-nGFJTnJN6cM2v9kXL+SOBq3AtjQby3Mv5ySGFof5UGRHrRioSJ5iG680cYNjE/yWk671nROcpPj4hAS8nyLhSw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
node_modules/zod/LICENSE
generated
vendored
Normal file
21
node_modules/zod/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2025 Colin McDonnell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
208
node_modules/zod/README.md
generated
vendored
Normal file
208
node_modules/zod/README.md
generated
vendored
Normal file
|
@ -0,0 +1,208 @@
|
|||
<p align="center">
|
||||
<img src="logo.svg" width="200px" align="center" alt="Zod logo" />
|
||||
<h1 align="center">Zod</h1>
|
||||
<p align="center">
|
||||
TypeScript-first schema validation with static type inference
|
||||
<br/>
|
||||
by <a href="https://x.com/colinhacks">@colinhacks</a>
|
||||
</p>
|
||||
</p>
|
||||
<br/>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/colinhacks/zod/actions?query=branch%3Amain"><img src="https://github.com/colinhacks/zod/actions/workflows/test.yml/badge.svg?event=push&branch=main" alt="Zod CI status" /></a>
|
||||
<a href="https://opensource.org/licenses/MIT" rel="nofollow"><img src="https://img.shields.io/github/license/colinhacks/zod" alt="License"></a>
|
||||
<a href="https://www.npmjs.com/package/zod" rel="nofollow"><img src="https://img.shields.io/npm/dw/zod.svg" alt="npm"></a>
|
||||
<a href="https://discord.gg/KaSRdyX2vc" rel="nofollow"><img src="https://img.shields.io/discord/893487829802418277?label=Discord&logo=discord&logoColor=white" alt="discord server"></a>
|
||||
<a href="https://github.com/colinhacks/zod" rel="nofollow"><img src="https://img.shields.io/github/stars/colinhacks/zod" alt="stars"></a>
|
||||
</p>
|
||||
|
||||
<div align="center">
|
||||
<a href="https://zod.dev/api">Docs</a>
|
||||
<span> • </span>
|
||||
<a href="https://discord.gg/RcG33DQJdf">Discord</a>
|
||||
<span> • </span>
|
||||
<a href="https://twitter.com/colinhacks">𝕏</a>
|
||||
<span> • </span>
|
||||
<a href="https://bsky.app/profile/zod.dev">Bluesky</a>
|
||||
<br />
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<h2 align="center">Featured sponsor: Jazz</h2>
|
||||
|
||||
<div align="center">
|
||||
<a href="https://jazz.tools/?utm_source=zod">
|
||||
<picture width="85%" >
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/garden-co/jazz/938f6767e46cdfded60e50d99bf3b533f4809c68/homepage/homepage/public/Zod%20sponsor%20message.png">
|
||||
<img alt="jazz logo" src="https://raw.githubusercontent.com/garden-co/jazz/938f6767e46cdfded60e50d99bf3b533f4809c68/homepage/homepage/public/Zod%20sponsor%20message.png" width="85%">
|
||||
</picture>
|
||||
</a>
|
||||
<br/>
|
||||
<p><sub>Learn more about <a target="_blank" rel="noopener noreferrer" href="mailto:sponsorship@colinhacks.com">featured sponsorships</a></sub></p>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
### [Read the docs →](https://zod.dev/api)
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
## What is Zod?
|
||||
|
||||
Zod is a TypeScript-first validation library. Define a schema and parse some data with it. You'll get back a strongly typed, validated result.
|
||||
|
||||
```ts
|
||||
import * as z from "zod";
|
||||
|
||||
const User = z.object({
|
||||
name: z.string(),
|
||||
});
|
||||
|
||||
// some untrusted data...
|
||||
const input = {
|
||||
/* stuff */
|
||||
};
|
||||
|
||||
// the parsed result is validated and type safe!
|
||||
const data = User.parse(input);
|
||||
|
||||
// so you can use it with confidence :)
|
||||
console.log(data.name);
|
||||
```
|
||||
|
||||
<br/>
|
||||
|
||||
## Features
|
||||
|
||||
- Zero external dependencies
|
||||
- Works in Node.js and all modern browsers
|
||||
- Tiny: `2kb` core bundle (gzipped)
|
||||
- Immutable API: methods return a new instance
|
||||
- Concise interface
|
||||
- Works with TypeScript and plain JS
|
||||
- Built-in JSON Schema conversion
|
||||
- Extensive ecosystem
|
||||
|
||||
<br/>
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install zod
|
||||
```
|
||||
|
||||
<br/>
|
||||
|
||||
## Basic usage
|
||||
|
||||
Before you can do anything else, you need to define a schema. For the purposes of this guide, we'll use a simple object schema.
|
||||
|
||||
```ts
|
||||
import * as z from "zod";
|
||||
|
||||
const Player = z.object({
|
||||
username: z.string(),
|
||||
xp: z.number(),
|
||||
});
|
||||
```
|
||||
|
||||
### Parsing data
|
||||
|
||||
Given any Zod schema, use `.parse` to validate an input. If it's valid, Zod returns a strongly-typed _deep clone_ of the input.
|
||||
|
||||
```ts
|
||||
Player.parse({ username: "billie", xp: 100 });
|
||||
// => returns { username: "billie", xp: 100 }
|
||||
```
|
||||
|
||||
**Note** — If your schema uses certain asynchronous APIs like `async` [refinements](#refine) or [transforms](#transform), you'll need to use the `.parseAsync()` method instead.
|
||||
|
||||
```ts
|
||||
const schema = z.string().refine(async (val) => val.length <= 8);
|
||||
|
||||
await schema.parseAsync("hello");
|
||||
// => "hello"
|
||||
```
|
||||
|
||||
### Handling errors
|
||||
|
||||
When validation fails, the `.parse()` method will throw a `ZodError` instance with granular information about the validation issues.
|
||||
|
||||
```ts
|
||||
try {
|
||||
Player.parse({ username: 42, xp: "100" });
|
||||
} catch (err) {
|
||||
if (err instanceof z.ZodError) {
|
||||
err.issues;
|
||||
/* [
|
||||
{
|
||||
expected: 'string',
|
||||
code: 'invalid_type',
|
||||
path: [ 'username' ],
|
||||
message: 'Invalid input: expected string'
|
||||
},
|
||||
{
|
||||
expected: 'number',
|
||||
code: 'invalid_type',
|
||||
path: [ 'xp' ],
|
||||
message: 'Invalid input: expected number'
|
||||
}
|
||||
] */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To avoid a `try/catch` block, you can use the `.safeParse()` method to get back a plain result object containing either the successfully parsed data or a `ZodError`. The result type is a [discriminated union](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions), so you can handle both cases conveniently.
|
||||
|
||||
```ts
|
||||
const result = Player.safeParse({ username: 42, xp: "100" });
|
||||
if (!result.success) {
|
||||
result.error; // ZodError instance
|
||||
} else {
|
||||
result.data; // { username: string; xp: number }
|
||||
}
|
||||
```
|
||||
|
||||
**Note** — If your schema uses certain asynchronous APIs like `async` [refinements](#refine) or [transforms](#transform), you'll need to use the `.safeParseAsync()` method instead.
|
||||
|
||||
```ts
|
||||
const schema = z.string().refine(async (val) => val.length <= 8);
|
||||
|
||||
await schema.safeParseAsync("hello");
|
||||
// => { success: true; data: "hello" }
|
||||
```
|
||||
|
||||
### Inferring types
|
||||
|
||||
Zod infers a static type from your schema definitions. You can extract this type with the `z.infer<>` utility and use it however you like.
|
||||
|
||||
```ts
|
||||
const Player = z.object({
|
||||
username: z.string(),
|
||||
xp: z.number(),
|
||||
});
|
||||
|
||||
// extract the inferred type
|
||||
type Player = z.infer<typeof Player>;
|
||||
|
||||
// use it in your code
|
||||
const player: Player = { username: "billie", xp: 100 };
|
||||
```
|
||||
|
||||
In some cases, the input & output types of a schema can diverge. For instance, the `.transform()` API can convert the input from one type to another. In these cases, you can extract the input and output types independently:
|
||||
|
||||
```ts
|
||||
const mySchema = z.string().transform((val) => val.length);
|
||||
|
||||
type MySchemaIn = z.input<typeof mySchema>;
|
||||
// => string
|
||||
|
||||
type MySchemaOut = z.output<typeof mySchema>; // equivalent to z.infer<typeof mySchema>
|
||||
// number
|
||||
```
|
33
node_modules/zod/index.cjs
generated
vendored
Normal file
33
node_modules/zod/index.cjs
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.z = void 0;
|
||||
const z = __importStar(require("./v4/classic/external.cjs"));
|
||||
exports.z = z;
|
||||
__exportStar(require("./v4/classic/external.cjs"), exports);
|
||||
exports.default = z;
|
4
node_modules/zod/index.d.cts
generated
vendored
Normal file
4
node_modules/zod/index.d.cts
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
import * as z from "./v4/classic/external.cjs";
|
||||
export * from "./v4/classic/external.cjs";
|
||||
export { z };
|
||||
export default z;
|
4
node_modules/zod/index.d.ts
generated
vendored
Normal file
4
node_modules/zod/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
import * as z from "./v4/classic/external.js";
|
||||
export * from "./v4/classic/external.js";
|
||||
export { z };
|
||||
export default z;
|
4
node_modules/zod/index.js
generated
vendored
Normal file
4
node_modules/zod/index.js
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
import * as z from "./v4/classic/external.js";
|
||||
export * from "./v4/classic/external.js";
|
||||
export { z };
|
||||
export default z;
|
17
node_modules/zod/locales/index.cjs
generated
vendored
Normal file
17
node_modules/zod/locales/index.cjs
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("../v4/locales/index.cjs"), exports);
|
1
node_modules/zod/locales/index.d.cts
generated
vendored
Normal file
1
node_modules/zod/locales/index.d.cts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export * from "../v4/locales/index.cjs";
|
1
node_modules/zod/locales/index.d.ts
generated
vendored
Normal file
1
node_modules/zod/locales/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export * from "../v4/locales/index.js";
|
1
node_modules/zod/locales/index.js
generated
vendored
Normal file
1
node_modules/zod/locales/index.js
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export * from "../v4/locales/index.js";
|
17
node_modules/zod/mini/index.cjs
generated
vendored
Normal file
17
node_modules/zod/mini/index.cjs
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("../v4/mini/index.cjs"), exports);
|
1
node_modules/zod/mini/index.d.cts
generated
vendored
Normal file
1
node_modules/zod/mini/index.d.cts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export * from "../v4/mini/index.cjs";
|
1
node_modules/zod/mini/index.d.ts
generated
vendored
Normal file
1
node_modules/zod/mini/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export * from "../v4/mini/index.js";
|
1
node_modules/zod/mini/index.js
generated
vendored
Normal file
1
node_modules/zod/mini/index.js
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export * from "../v4/mini/index.js";
|
134
node_modules/zod/package.json
generated
vendored
Normal file
134
node_modules/zod/package.json
generated
vendored
Normal file
|
@ -0,0 +1,134 @@
|
|||
{
|
||||
"name": "zod",
|
||||
"version": "4.0.14",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"author": "Colin McDonnell <zod@colinhacks.com>",
|
||||
"description": "TypeScript-first schema declaration and validation library with static type inference",
|
||||
"homepage": "https://zod.dev",
|
||||
"llms": "https://zod.dev/llms.txt",
|
||||
"llmsFull": "https://zod.dev/llms-full.txt",
|
||||
"mcpServer": "https://mcp.inkeep.com/zod/mcp",
|
||||
"funding": "https://github.com/sponsors/colinhacks",
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"src",
|
||||
"**/*.js",
|
||||
"**/*.mjs",
|
||||
"**/*.cjs",
|
||||
"**/*.d.ts",
|
||||
"**/*.d.mts",
|
||||
"**/*.d.cts"
|
||||
],
|
||||
"keywords": [
|
||||
"typescript",
|
||||
"schema",
|
||||
"validation",
|
||||
"type",
|
||||
"inference"
|
||||
],
|
||||
"main": "./index.cjs",
|
||||
"types": "./index.d.cts",
|
||||
"module": "./index.js",
|
||||
"zshy": {
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts",
|
||||
"./mini": "./src/mini/index.ts",
|
||||
"./locales": "./src/locales/index.ts",
|
||||
"./v3": "./src/v3/index.ts",
|
||||
"./v4": "./src/v4/index.ts",
|
||||
"./v4-mini": "./src/v4-mini/index.ts",
|
||||
"./v4/mini": "./src/v4/mini/index.ts",
|
||||
"./v4/core": "./src/v4/core/index.ts",
|
||||
"./v4/locales": "./src/v4/locales/index.ts",
|
||||
"./v4/locales/*": "./src/v4/locales/*"
|
||||
},
|
||||
"conditions": {
|
||||
"@zod/source": "src"
|
||||
}
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"@zod/source": "./src/index.ts",
|
||||
"types": "./index.d.cts",
|
||||
"import": "./index.js",
|
||||
"require": "./index.cjs"
|
||||
},
|
||||
"./mini": {
|
||||
"@zod/source": "./src/mini/index.ts",
|
||||
"types": "./mini/index.d.cts",
|
||||
"import": "./mini/index.js",
|
||||
"require": "./mini/index.cjs"
|
||||
},
|
||||
"./locales": {
|
||||
"@zod/source": "./src/locales/index.ts",
|
||||
"types": "./locales/index.d.cts",
|
||||
"import": "./locales/index.js",
|
||||
"require": "./locales/index.cjs"
|
||||
},
|
||||
"./v3": {
|
||||
"@zod/source": "./src/v3/index.ts",
|
||||
"types": "./v3/index.d.cts",
|
||||
"import": "./v3/index.js",
|
||||
"require": "./v3/index.cjs"
|
||||
},
|
||||
"./v4": {
|
||||
"@zod/source": "./src/v4/index.ts",
|
||||
"types": "./v4/index.d.cts",
|
||||
"import": "./v4/index.js",
|
||||
"require": "./v4/index.cjs"
|
||||
},
|
||||
"./v4-mini": {
|
||||
"@zod/source": "./src/v4-mini/index.ts",
|
||||
"types": "./v4-mini/index.d.cts",
|
||||
"import": "./v4-mini/index.js",
|
||||
"require": "./v4-mini/index.cjs"
|
||||
},
|
||||
"./v4/mini": {
|
||||
"@zod/source": "./src/v4/mini/index.ts",
|
||||
"types": "./v4/mini/index.d.cts",
|
||||
"import": "./v4/mini/index.js",
|
||||
"require": "./v4/mini/index.cjs"
|
||||
},
|
||||
"./v4/core": {
|
||||
"@zod/source": "./src/v4/core/index.ts",
|
||||
"types": "./v4/core/index.d.cts",
|
||||
"import": "./v4/core/index.js",
|
||||
"require": "./v4/core/index.cjs"
|
||||
},
|
||||
"./v4/locales": {
|
||||
"@zod/source": "./src/v4/locales/index.ts",
|
||||
"types": "./v4/locales/index.d.cts",
|
||||
"import": "./v4/locales/index.js",
|
||||
"require": "./v4/locales/index.cjs"
|
||||
},
|
||||
"./v4/locales/*": {
|
||||
"@zod/source": "./src/v4/locales/*",
|
||||
"types": "./v4/locales/*",
|
||||
"import": "./v4/locales/*",
|
||||
"require": "./v4/locales/*"
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/colinhacks/zod.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/colinhacks/zod/issues"
|
||||
},
|
||||
"support": {
|
||||
"backing": {
|
||||
"npm-funding": true
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "git clean -xdf . -e node_modules",
|
||||
"build": "zshy --project tsconfig.build.json",
|
||||
"postbuild": "pnpm biome check --write .",
|
||||
"test:watch": "pnpm vitest",
|
||||
"test": "pnpm vitest run",
|
||||
"prepublishOnly": "tsx ../../scripts/check-versions.ts"
|
||||
}
|
||||
}
|
4
node_modules/zod/src/index.ts
generated
vendored
Normal file
4
node_modules/zod/src/index.ts
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
import * as z from "./v4/classic/external.js";
|
||||
export * from "./v4/classic/external.js";
|
||||
export { z };
|
||||
export default z;
|
1
node_modules/zod/src/locales/index.ts
generated
vendored
Normal file
1
node_modules/zod/src/locales/index.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export * from "../v4/locales/index.js";
|
1
node_modules/zod/src/mini/index.ts
generated
vendored
Normal file
1
node_modules/zod/src/mini/index.ts
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export * from "../v4/mini/index.js";
|
330
node_modules/zod/src/v3/ZodError.ts
generated
vendored
Normal file
330
node_modules/zod/src/v3/ZodError.ts
generated
vendored
Normal file
|
@ -0,0 +1,330 @@
|
|||
import type { Primitive } from "./helpers/typeAliases.js";
|
||||
import { util, type ZodParsedType } from "./helpers/util.js";
|
||||
import type { TypeOf, ZodType } from "./index.js";
|
||||
|
||||
type allKeys<T> = T extends any ? keyof T : never;
|
||||
|
||||
export type inferFlattenedErrors<T extends ZodType<any, any, any>, U = string> = typeToFlattenedError<TypeOf<T>, U>;
|
||||
export type typeToFlattenedError<T, U = string> = {
|
||||
formErrors: U[];
|
||||
fieldErrors: {
|
||||
[P in allKeys<T>]?: U[];
|
||||
};
|
||||
};
|
||||
|
||||
export const ZodIssueCode = util.arrayToEnum([
|
||||
"invalid_type",
|
||||
"invalid_literal",
|
||||
"custom",
|
||||
"invalid_union",
|
||||
"invalid_union_discriminator",
|
||||
"invalid_enum_value",
|
||||
"unrecognized_keys",
|
||||
"invalid_arguments",
|
||||
"invalid_return_type",
|
||||
"invalid_date",
|
||||
"invalid_string",
|
||||
"too_small",
|
||||
"too_big",
|
||||
"invalid_intersection_types",
|
||||
"not_multiple_of",
|
||||
"not_finite",
|
||||
]);
|
||||
|
||||
export type ZodIssueCode = keyof typeof ZodIssueCode;
|
||||
|
||||
export type ZodIssueBase = {
|
||||
path: (string | number)[];
|
||||
message?: string | undefined;
|
||||
};
|
||||
|
||||
export interface ZodInvalidTypeIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_type;
|
||||
expected: ZodParsedType;
|
||||
received: ZodParsedType;
|
||||
}
|
||||
|
||||
export interface ZodInvalidLiteralIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_literal;
|
||||
expected: unknown;
|
||||
received: unknown;
|
||||
}
|
||||
|
||||
export interface ZodUnrecognizedKeysIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.unrecognized_keys;
|
||||
keys: string[];
|
||||
}
|
||||
|
||||
export interface ZodInvalidUnionIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_union;
|
||||
unionErrors: ZodError[];
|
||||
}
|
||||
|
||||
export interface ZodInvalidUnionDiscriminatorIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_union_discriminator;
|
||||
options: Primitive[];
|
||||
}
|
||||
|
||||
export interface ZodInvalidEnumValueIssue extends ZodIssueBase {
|
||||
received: string | number;
|
||||
code: typeof ZodIssueCode.invalid_enum_value;
|
||||
options: (string | number)[];
|
||||
}
|
||||
|
||||
export interface ZodInvalidArgumentsIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_arguments;
|
||||
argumentsError: ZodError;
|
||||
}
|
||||
|
||||
export interface ZodInvalidReturnTypeIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_return_type;
|
||||
returnTypeError: ZodError;
|
||||
}
|
||||
|
||||
export interface ZodInvalidDateIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_date;
|
||||
}
|
||||
|
||||
export type StringValidation =
|
||||
| "email"
|
||||
| "url"
|
||||
| "emoji"
|
||||
| "uuid"
|
||||
| "nanoid"
|
||||
| "regex"
|
||||
| "cuid"
|
||||
| "cuid2"
|
||||
| "ulid"
|
||||
| "datetime"
|
||||
| "date"
|
||||
| "time"
|
||||
| "duration"
|
||||
| "ip"
|
||||
| "cidr"
|
||||
| "base64"
|
||||
| "jwt"
|
||||
| "base64url"
|
||||
| { includes: string; position?: number | undefined }
|
||||
| { startsWith: string }
|
||||
| { endsWith: string };
|
||||
|
||||
export interface ZodInvalidStringIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_string;
|
||||
validation: StringValidation;
|
||||
}
|
||||
|
||||
export interface ZodTooSmallIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.too_small;
|
||||
minimum: number | bigint;
|
||||
inclusive: boolean;
|
||||
exact?: boolean;
|
||||
type: "array" | "string" | "number" | "set" | "date" | "bigint";
|
||||
}
|
||||
|
||||
export interface ZodTooBigIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.too_big;
|
||||
maximum: number | bigint;
|
||||
inclusive: boolean;
|
||||
exact?: boolean;
|
||||
type: "array" | "string" | "number" | "set" | "date" | "bigint";
|
||||
}
|
||||
|
||||
export interface ZodInvalidIntersectionTypesIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_intersection_types;
|
||||
}
|
||||
|
||||
export interface ZodNotMultipleOfIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.not_multiple_of;
|
||||
multipleOf: number | bigint;
|
||||
}
|
||||
|
||||
export interface ZodNotFiniteIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.not_finite;
|
||||
}
|
||||
|
||||
export interface ZodCustomIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.custom;
|
||||
params?: { [k: string]: any };
|
||||
}
|
||||
|
||||
export type DenormalizedError = { [k: string]: DenormalizedError | string[] };
|
||||
|
||||
export type ZodIssueOptionalMessage =
|
||||
| ZodInvalidTypeIssue
|
||||
| ZodInvalidLiteralIssue
|
||||
| ZodUnrecognizedKeysIssue
|
||||
| ZodInvalidUnionIssue
|
||||
| ZodInvalidUnionDiscriminatorIssue
|
||||
| ZodInvalidEnumValueIssue
|
||||
| ZodInvalidArgumentsIssue
|
||||
| ZodInvalidReturnTypeIssue
|
||||
| ZodInvalidDateIssue
|
||||
| ZodInvalidStringIssue
|
||||
| ZodTooSmallIssue
|
||||
| ZodTooBigIssue
|
||||
| ZodInvalidIntersectionTypesIssue
|
||||
| ZodNotMultipleOfIssue
|
||||
| ZodNotFiniteIssue
|
||||
| ZodCustomIssue;
|
||||
|
||||
export type ZodIssue = ZodIssueOptionalMessage & {
|
||||
fatal?: boolean | undefined;
|
||||
message: string;
|
||||
};
|
||||
|
||||
export const quotelessJson = (obj: any) => {
|
||||
const json = JSON.stringify(obj, null, 2);
|
||||
return json.replace(/"([^"]+)":/g, "$1:");
|
||||
};
|
||||
|
||||
type recursiveZodFormattedError<T> = T extends [any, ...any[]]
|
||||
? { [K in keyof T]?: ZodFormattedError<T[K]> }
|
||||
: T extends any[]
|
||||
? { [k: number]: ZodFormattedError<T[number]> }
|
||||
: T extends object
|
||||
? { [K in keyof T]?: ZodFormattedError<T[K]> }
|
||||
: unknown;
|
||||
|
||||
export type ZodFormattedError<T, U = string> = {
|
||||
_errors: U[];
|
||||
} & recursiveZodFormattedError<NonNullable<T>>;
|
||||
|
||||
export type inferFormattedError<T extends ZodType<any, any, any>, U = string> = ZodFormattedError<TypeOf<T>, U>;
|
||||
|
||||
export class ZodError<T = any> extends Error {
|
||||
issues: ZodIssue[] = [];
|
||||
|
||||
get errors() {
|
||||
return this.issues;
|
||||
}
|
||||
|
||||
constructor(issues: ZodIssue[]) {
|
||||
super();
|
||||
|
||||
const actualProto = new.target.prototype;
|
||||
if (Object.setPrototypeOf) {
|
||||
// eslint-disable-next-line ban/ban
|
||||
Object.setPrototypeOf(this, actualProto);
|
||||
} else {
|
||||
(this as any).__proto__ = actualProto;
|
||||
}
|
||||
this.name = "ZodError";
|
||||
this.issues = issues;
|
||||
}
|
||||
|
||||
format(): ZodFormattedError<T>;
|
||||
format<U>(mapper: (issue: ZodIssue) => U): ZodFormattedError<T, U>;
|
||||
format(_mapper?: any) {
|
||||
const mapper: (issue: ZodIssue) => any =
|
||||
_mapper ||
|
||||
function (issue: ZodIssue) {
|
||||
return issue.message;
|
||||
};
|
||||
const fieldErrors: ZodFormattedError<T> = { _errors: [] } as any;
|
||||
const processError = (error: ZodError) => {
|
||||
for (const issue of error.issues) {
|
||||
if (issue.code === "invalid_union") {
|
||||
issue.unionErrors.map(processError);
|
||||
} else if (issue.code === "invalid_return_type") {
|
||||
processError(issue.returnTypeError);
|
||||
} else if (issue.code === "invalid_arguments") {
|
||||
processError(issue.argumentsError);
|
||||
} else if (issue.path.length === 0) {
|
||||
(fieldErrors as any)._errors.push(mapper(issue));
|
||||
} else {
|
||||
let curr: any = fieldErrors;
|
||||
let i = 0;
|
||||
while (i < issue.path.length) {
|
||||
const el = issue.path[i]!;
|
||||
const terminal = i === issue.path.length - 1;
|
||||
|
||||
if (!terminal) {
|
||||
curr[el] = curr[el] || { _errors: [] };
|
||||
// if (typeof el === "string") {
|
||||
// curr[el] = curr[el] || { _errors: [] };
|
||||
// } else if (typeof el === "number") {
|
||||
// const errorArray: any = [];
|
||||
// errorArray._errors = [];
|
||||
// curr[el] = curr[el] || errorArray;
|
||||
// }
|
||||
} else {
|
||||
curr[el] = curr[el] || { _errors: [] };
|
||||
curr[el]._errors.push(mapper(issue));
|
||||
}
|
||||
|
||||
curr = curr[el];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
processError(this);
|
||||
return fieldErrors;
|
||||
}
|
||||
|
||||
static create = (issues: ZodIssue[]) => {
|
||||
const error = new ZodError(issues);
|
||||
return error;
|
||||
};
|
||||
|
||||
static assert(value: unknown): asserts value is ZodError {
|
||||
if (!(value instanceof ZodError)) {
|
||||
throw new Error(`Not a ZodError: ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
override toString() {
|
||||
return this.message;
|
||||
}
|
||||
override get message() {
|
||||
return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
|
||||
}
|
||||
|
||||
get isEmpty(): boolean {
|
||||
return this.issues.length === 0;
|
||||
}
|
||||
|
||||
addIssue = (sub: ZodIssue) => {
|
||||
this.issues = [...this.issues, sub];
|
||||
};
|
||||
|
||||
addIssues = (subs: ZodIssue[] = []) => {
|
||||
this.issues = [...this.issues, ...subs];
|
||||
};
|
||||
|
||||
flatten(): typeToFlattenedError<T>;
|
||||
flatten<U>(mapper?: (issue: ZodIssue) => U): typeToFlattenedError<T, U>;
|
||||
flatten<U = string>(mapper: (issue: ZodIssue) => U = (issue: ZodIssue) => issue.message as any): any {
|
||||
const fieldErrors: any = {};
|
||||
const formErrors: U[] = [];
|
||||
for (const sub of this.issues) {
|
||||
if (sub.path.length > 0) {
|
||||
const firstEl = sub.path[0]!;
|
||||
fieldErrors[firstEl] = fieldErrors[firstEl] || [];
|
||||
fieldErrors[firstEl].push(mapper(sub));
|
||||
} else {
|
||||
formErrors.push(mapper(sub));
|
||||
}
|
||||
}
|
||||
return { formErrors, fieldErrors };
|
||||
}
|
||||
|
||||
get formErrors() {
|
||||
return this.flatten();
|
||||
}
|
||||
}
|
||||
|
||||
type stripPath<T extends object> = T extends any ? util.OmitKeys<T, "path"> : never;
|
||||
|
||||
export type IssueData = stripPath<ZodIssueOptionalMessage> & {
|
||||
path?: (string | number)[];
|
||||
fatal?: boolean | undefined;
|
||||
};
|
||||
|
||||
export type ErrorMapCtx = {
|
||||
defaultError: string;
|
||||
data: any;
|
||||
};
|
||||
|
||||
export type ZodErrorMap = (issue: ZodIssueOptionalMessage, _ctx: ErrorMapCtx) => { message: string };
|
58
node_modules/zod/src/v3/benchmarks/datetime.ts
generated
vendored
Normal file
58
node_modules/zod/src/v3/benchmarks/datetime.ts
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
import Benchmark from "benchmark";
|
||||
|
||||
const datetimeValidationSuite = new Benchmark.Suite("datetime");
|
||||
|
||||
const DATA = "2021-01-01";
|
||||
const MONTHS_31 = new Set([1, 3, 5, 7, 8, 10, 12]);
|
||||
const MONTHS_30 = new Set([4, 6, 9, 11]);
|
||||
|
||||
const simpleDatetimeRegex = /^(\d{4})-(\d{2})-(\d{2})$/;
|
||||
const datetimeRegexNoLeapYearValidation =
|
||||
/^\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9]|1[0-2])-(0[1-9]|1\d|2\d))$/;
|
||||
const datetimeRegexWithLeapYearValidation =
|
||||
/^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))$/;
|
||||
|
||||
datetimeValidationSuite
|
||||
.add("new Date()", () => {
|
||||
return !Number.isNaN(new Date(DATA).getTime());
|
||||
})
|
||||
.add("regex (no validation)", () => {
|
||||
return simpleDatetimeRegex.test(DATA);
|
||||
})
|
||||
.add("regex (no leap year)", () => {
|
||||
return datetimeRegexNoLeapYearValidation.test(DATA);
|
||||
})
|
||||
.add("regex (w/ leap year)", () => {
|
||||
return datetimeRegexWithLeapYearValidation.test(DATA);
|
||||
})
|
||||
.add("capture groups + code", () => {
|
||||
const match = DATA.match(simpleDatetimeRegex);
|
||||
if (!match) return false;
|
||||
|
||||
// Extract year, month, and day from the capture groups
|
||||
const year = Number.parseInt(match[1], 10);
|
||||
const month = Number.parseInt(match[2], 10); // month is 0-indexed in JavaScript Date, so subtract 1
|
||||
const day = Number.parseInt(match[3], 10);
|
||||
|
||||
if (month === 2) {
|
||||
if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
|
||||
return day <= 29;
|
||||
}
|
||||
return day <= 28;
|
||||
}
|
||||
if (MONTHS_30.has(month)) {
|
||||
return day <= 30;
|
||||
}
|
||||
if (MONTHS_31.has(month)) {
|
||||
return day <= 31;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`${datetimeValidationSuite.name!}: ${e.target}`);
|
||||
});
|
||||
|
||||
export default {
|
||||
suites: [datetimeValidationSuite],
|
||||
};
|
80
node_modules/zod/src/v3/benchmarks/discriminatedUnion.ts
generated
vendored
Normal file
80
node_modules/zod/src/v3/benchmarks/discriminatedUnion.ts
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
import Benchmark from "benchmark";
|
||||
|
||||
import { z } from "zod/v3";
|
||||
|
||||
const doubleSuite = new Benchmark.Suite("z.discriminatedUnion: double");
|
||||
const manySuite = new Benchmark.Suite("z.discriminatedUnion: many");
|
||||
|
||||
const aSchema = z.object({
|
||||
type: z.literal("a"),
|
||||
});
|
||||
const objA = {
|
||||
type: "a",
|
||||
};
|
||||
|
||||
const bSchema = z.object({
|
||||
type: z.literal("b"),
|
||||
});
|
||||
const objB = {
|
||||
type: "b",
|
||||
};
|
||||
|
||||
const cSchema = z.object({
|
||||
type: z.literal("c"),
|
||||
});
|
||||
const objC = {
|
||||
type: "c",
|
||||
};
|
||||
|
||||
const dSchema = z.object({
|
||||
type: z.literal("d"),
|
||||
});
|
||||
|
||||
const double = z.discriminatedUnion("type", [aSchema, bSchema]);
|
||||
const many = z.discriminatedUnion("type", [aSchema, bSchema, cSchema, dSchema]);
|
||||
|
||||
doubleSuite
|
||||
.add("valid: a", () => {
|
||||
double.parse(objA);
|
||||
})
|
||||
.add("valid: b", () => {
|
||||
double.parse(objB);
|
||||
})
|
||||
.add("invalid: null", () => {
|
||||
try {
|
||||
double.parse(null);
|
||||
} catch (_err) {}
|
||||
})
|
||||
.add("invalid: wrong shape", () => {
|
||||
try {
|
||||
double.parse(objC);
|
||||
} catch (_err) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`${(doubleSuite as any).name}: ${e.target}`);
|
||||
});
|
||||
|
||||
manySuite
|
||||
.add("valid: a", () => {
|
||||
many.parse(objA);
|
||||
})
|
||||
.add("valid: c", () => {
|
||||
many.parse(objC);
|
||||
})
|
||||
.add("invalid: null", () => {
|
||||
try {
|
||||
many.parse(null);
|
||||
} catch (_err) {}
|
||||
})
|
||||
.add("invalid: wrong shape", () => {
|
||||
try {
|
||||
many.parse({ type: "unknown" });
|
||||
} catch (_err) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`${(manySuite as any).name}: ${e.target}`);
|
||||
});
|
||||
|
||||
export default {
|
||||
suites: [doubleSuite, manySuite],
|
||||
};
|
59
node_modules/zod/src/v3/benchmarks/index.ts
generated
vendored
Normal file
59
node_modules/zod/src/v3/benchmarks/index.ts
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
import type Benchmark from "benchmark";
|
||||
|
||||
import datetimeBenchmarks from "./datetime.js";
|
||||
import discriminatedUnionBenchmarks from "./discriminatedUnion.js";
|
||||
import ipv4Benchmarks from "./ipv4.js";
|
||||
import objectBenchmarks from "./object.js";
|
||||
import primitiveBenchmarks from "./primitives.js";
|
||||
import realworld from "./realworld.js";
|
||||
import stringBenchmarks from "./string.js";
|
||||
import unionBenchmarks from "./union.js";
|
||||
|
||||
const argv = process.argv.slice(2);
|
||||
let suites: Benchmark.Suite[] = [];
|
||||
|
||||
if (!argv.length) {
|
||||
suites = [
|
||||
...realworld.suites,
|
||||
...primitiveBenchmarks.suites,
|
||||
...stringBenchmarks.suites,
|
||||
...objectBenchmarks.suites,
|
||||
...unionBenchmarks.suites,
|
||||
...discriminatedUnionBenchmarks.suites,
|
||||
];
|
||||
} else {
|
||||
if (argv.includes("--realworld")) {
|
||||
suites.push(...realworld.suites);
|
||||
}
|
||||
if (argv.includes("--primitives")) {
|
||||
suites.push(...primitiveBenchmarks.suites);
|
||||
}
|
||||
if (argv.includes("--string")) {
|
||||
suites.push(...stringBenchmarks.suites);
|
||||
}
|
||||
if (argv.includes("--object")) {
|
||||
suites.push(...objectBenchmarks.suites);
|
||||
}
|
||||
if (argv.includes("--union")) {
|
||||
suites.push(...unionBenchmarks.suites);
|
||||
}
|
||||
if (argv.includes("--discriminatedUnion")) {
|
||||
suites.push(...datetimeBenchmarks.suites);
|
||||
}
|
||||
if (argv.includes("--datetime")) {
|
||||
suites.push(...datetimeBenchmarks.suites);
|
||||
}
|
||||
if (argv.includes("--ipv4")) {
|
||||
suites.push(...ipv4Benchmarks.suites);
|
||||
}
|
||||
}
|
||||
|
||||
for (const suite of suites) {
|
||||
suite.run({});
|
||||
}
|
||||
|
||||
// exit on Ctrl-C
|
||||
process.on("SIGINT", function () {
|
||||
console.log("Exiting...");
|
||||
process.exit();
|
||||
});
|
57
node_modules/zod/src/v3/benchmarks/ipv4.ts
generated
vendored
Normal file
57
node_modules/zod/src/v3/benchmarks/ipv4.ts
generated
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
import Benchmark from "benchmark";
|
||||
|
||||
const suite = new Benchmark.Suite("ipv4");
|
||||
|
||||
const DATA = "127.0.0.1";
|
||||
const ipv4RegexA =
|
||||
/^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/;
|
||||
const ipv4RegexB =
|
||||
/^(?:(?:(?=(25[0-5]))\1|(?=(2[0-4][0-9]))\2|(?=(1[0-9]{2}))\3|(?=([0-9]{1,2}))\4)\.){3}(?:(?=(25[0-5]))\5|(?=(2[0-4][0-9]))\6|(?=(1[0-9]{2}))\7|(?=([0-9]{1,2}))\8)$/;
|
||||
const ipv4RegexC = /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/;
|
||||
const ipv4RegexD = /^(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/;
|
||||
const ipv4RegexE = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.){3}(25[0-5]|(2[0-4]|1\d|[1-9]|)\d)$/;
|
||||
const ipv4RegexF = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/;
|
||||
const ipv4RegexG = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$/;
|
||||
const ipv4RegexH = /^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$/;
|
||||
const ipv4RegexI =
|
||||
/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
|
||||
|
||||
suite
|
||||
.add("A", () => {
|
||||
return ipv4RegexA.test(DATA);
|
||||
})
|
||||
.add("B", () => {
|
||||
return ipv4RegexB.test(DATA);
|
||||
})
|
||||
.add("C", () => {
|
||||
return ipv4RegexC.test(DATA);
|
||||
})
|
||||
.add("D", () => {
|
||||
return ipv4RegexD.test(DATA);
|
||||
})
|
||||
.add("E", () => {
|
||||
return ipv4RegexE.test(DATA);
|
||||
})
|
||||
.add("F", () => {
|
||||
return ipv4RegexF.test(DATA);
|
||||
})
|
||||
.add("G", () => {
|
||||
return ipv4RegexG.test(DATA);
|
||||
})
|
||||
.add("H", () => {
|
||||
return ipv4RegexH.test(DATA);
|
||||
})
|
||||
.add("I", () => {
|
||||
return ipv4RegexI.test(DATA);
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`${suite.name!}: ${e.target}`);
|
||||
});
|
||||
|
||||
export default {
|
||||
suites: [suite],
|
||||
};
|
||||
|
||||
if (require.main === module) {
|
||||
suite.run();
|
||||
}
|
69
node_modules/zod/src/v3/benchmarks/object.ts
generated
vendored
Normal file
69
node_modules/zod/src/v3/benchmarks/object.ts
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
import Benchmark from "benchmark";
|
||||
|
||||
import { z } from "zod/v3";
|
||||
|
||||
const emptySuite = new Benchmark.Suite("z.object: empty");
|
||||
const shortSuite = new Benchmark.Suite("z.object: short");
|
||||
const longSuite = new Benchmark.Suite("z.object: long");
|
||||
|
||||
const empty = z.object({});
|
||||
const short = z.object({
|
||||
string: z.string(),
|
||||
});
|
||||
const long = z.object({
|
||||
string: z.string(),
|
||||
number: z.number(),
|
||||
boolean: z.boolean(),
|
||||
});
|
||||
|
||||
emptySuite
|
||||
.add("valid", () => {
|
||||
empty.parse({});
|
||||
})
|
||||
.add("valid: extra keys", () => {
|
||||
empty.parse({ string: "string" });
|
||||
})
|
||||
.add("invalid: null", () => {
|
||||
try {
|
||||
empty.parse(null);
|
||||
} catch (_err) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`${(emptySuite as any).name}: ${e.target}`);
|
||||
});
|
||||
|
||||
shortSuite
|
||||
.add("valid", () => {
|
||||
short.parse({ string: "string" });
|
||||
})
|
||||
.add("valid: extra keys", () => {
|
||||
short.parse({ string: "string", number: 42 });
|
||||
})
|
||||
.add("invalid: null", () => {
|
||||
try {
|
||||
short.parse(null);
|
||||
} catch (_err) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`${(shortSuite as any).name}: ${e.target}`);
|
||||
});
|
||||
|
||||
longSuite
|
||||
.add("valid", () => {
|
||||
long.parse({ string: "string", number: 42, boolean: true });
|
||||
})
|
||||
.add("valid: extra keys", () => {
|
||||
long.parse({ string: "string", number: 42, boolean: true, list: [] });
|
||||
})
|
||||
.add("invalid: null", () => {
|
||||
try {
|
||||
long.parse(null);
|
||||
} catch (_err) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`${(longSuite as any).name}: ${e.target}`);
|
||||
});
|
||||
|
||||
export default {
|
||||
suites: [emptySuite, shortSuite, longSuite],
|
||||
};
|
162
node_modules/zod/src/v3/benchmarks/primitives.ts
generated
vendored
Normal file
162
node_modules/zod/src/v3/benchmarks/primitives.ts
generated
vendored
Normal file
|
@ -0,0 +1,162 @@
|
|||
import Benchmark from "benchmark";
|
||||
|
||||
import { z } from "zod/v3";
|
||||
import { Mocker } from "../tests/Mocker.js";
|
||||
|
||||
const val = new Mocker();
|
||||
|
||||
const enumSuite = new Benchmark.Suite("z.enum");
|
||||
const enumSchema = z.enum(["a", "b", "c"]);
|
||||
|
||||
enumSuite
|
||||
.add("valid", () => {
|
||||
enumSchema.parse("a");
|
||||
})
|
||||
.add("invalid", () => {
|
||||
try {
|
||||
enumSchema.parse("x");
|
||||
} catch (_e: any) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`z.enum: ${e.target}`);
|
||||
});
|
||||
|
||||
const longEnumSuite = new Benchmark.Suite("long z.enum");
|
||||
const longEnumSchema = z.enum([
|
||||
"one",
|
||||
"two",
|
||||
"three",
|
||||
"four",
|
||||
"five",
|
||||
"six",
|
||||
"seven",
|
||||
"eight",
|
||||
"nine",
|
||||
"ten",
|
||||
"eleven",
|
||||
"twelve",
|
||||
"thirteen",
|
||||
"fourteen",
|
||||
"fifteen",
|
||||
"sixteen",
|
||||
"seventeen",
|
||||
]);
|
||||
|
||||
longEnumSuite
|
||||
.add("valid", () => {
|
||||
longEnumSchema.parse("five");
|
||||
})
|
||||
.add("invalid", () => {
|
||||
try {
|
||||
longEnumSchema.parse("invalid");
|
||||
} catch (_e: any) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`long z.enum: ${e.target}`);
|
||||
});
|
||||
|
||||
const undefinedSuite = new Benchmark.Suite("z.undefined");
|
||||
const undefinedSchema = z.undefined();
|
||||
|
||||
undefinedSuite
|
||||
.add("valid", () => {
|
||||
undefinedSchema.parse(undefined);
|
||||
})
|
||||
.add("invalid", () => {
|
||||
try {
|
||||
undefinedSchema.parse(1);
|
||||
} catch (_e: any) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`z.undefined: ${e.target}`);
|
||||
});
|
||||
|
||||
const literalSuite = new Benchmark.Suite("z.literal");
|
||||
const short = "short";
|
||||
const bad = "bad";
|
||||
const literalSchema = z.literal("short");
|
||||
|
||||
literalSuite
|
||||
.add("valid", () => {
|
||||
literalSchema.parse(short);
|
||||
})
|
||||
.add("invalid", () => {
|
||||
try {
|
||||
literalSchema.parse(bad);
|
||||
} catch (_e: any) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`z.literal: ${e.target}`);
|
||||
});
|
||||
|
||||
const numberSuite = new Benchmark.Suite("z.number");
|
||||
const numberSchema = z.number().int();
|
||||
|
||||
numberSuite
|
||||
.add("valid", () => {
|
||||
numberSchema.parse(1);
|
||||
})
|
||||
.add("invalid type", () => {
|
||||
try {
|
||||
numberSchema.parse("bad");
|
||||
} catch (_e: any) {}
|
||||
})
|
||||
.add("invalid number", () => {
|
||||
try {
|
||||
numberSchema.parse(0.5);
|
||||
} catch (_e: any) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`z.number: ${e.target}`);
|
||||
});
|
||||
|
||||
const dateSuite = new Benchmark.Suite("z.date");
|
||||
|
||||
const plainDate = z.date();
|
||||
const minMaxDate = z.date().min(new Date("2021-01-01")).max(new Date("2030-01-01"));
|
||||
|
||||
dateSuite
|
||||
.add("valid", () => {
|
||||
plainDate.parse(new Date());
|
||||
})
|
||||
.add("invalid", () => {
|
||||
try {
|
||||
plainDate.parse(1);
|
||||
} catch (_e: any) {}
|
||||
})
|
||||
.add("valid min and max", () => {
|
||||
minMaxDate.parse(new Date("2023-01-01"));
|
||||
})
|
||||
.add("invalid min", () => {
|
||||
try {
|
||||
minMaxDate.parse(new Date("2019-01-01"));
|
||||
} catch (_e: any) {}
|
||||
})
|
||||
.add("invalid max", () => {
|
||||
try {
|
||||
minMaxDate.parse(new Date("2031-01-01"));
|
||||
} catch (_e: any) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`z.date: ${e.target}`);
|
||||
});
|
||||
|
||||
const symbolSuite = new Benchmark.Suite("z.symbol");
|
||||
const symbolSchema = z.symbol();
|
||||
|
||||
symbolSuite
|
||||
.add("valid", () => {
|
||||
symbolSchema.parse(val.symbol);
|
||||
})
|
||||
.add("invalid", () => {
|
||||
try {
|
||||
symbolSchema.parse(1);
|
||||
} catch (_e: any) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`z.symbol: ${e.target}`);
|
||||
});
|
||||
|
||||
export default {
|
||||
suites: [enumSuite, longEnumSuite, undefinedSuite, literalSuite, numberSuite, dateSuite, symbolSuite],
|
||||
};
|
63
node_modules/zod/src/v3/benchmarks/realworld.ts
generated
vendored
Normal file
63
node_modules/zod/src/v3/benchmarks/realworld.ts
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
import Benchmark from "benchmark";
|
||||
|
||||
import { z } from "zod/v3";
|
||||
|
||||
const shortSuite = new Benchmark.Suite("realworld");
|
||||
|
||||
const People = z.array(
|
||||
z.object({
|
||||
type: z.literal("person"),
|
||||
hair: z.enum(["blue", "brown"]),
|
||||
active: z.boolean(),
|
||||
name: z.string(),
|
||||
age: z.number().int(),
|
||||
hobbies: z.array(z.string()),
|
||||
address: z.object({
|
||||
street: z.string(),
|
||||
zip: z.string(),
|
||||
country: z.string(),
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
let i = 0;
|
||||
|
||||
function num() {
|
||||
return ++i;
|
||||
}
|
||||
|
||||
function str() {
|
||||
return (++i % 100).toString(16);
|
||||
}
|
||||
|
||||
function array<T>(fn: () => T): T[] {
|
||||
return Array.from({ length: ++i % 10 }, () => fn());
|
||||
}
|
||||
|
||||
const people = Array.from({ length: 100 }, () => {
|
||||
return {
|
||||
type: "person",
|
||||
hair: i % 2 ? "blue" : "brown",
|
||||
active: !!(i % 2),
|
||||
name: str(),
|
||||
age: num(),
|
||||
hobbies: array(str),
|
||||
address: {
|
||||
street: str(),
|
||||
zip: str(),
|
||||
country: str(),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
shortSuite
|
||||
.add("valid", () => {
|
||||
People.parse(people);
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`${(shortSuite as any).name}: ${e.target}`);
|
||||
});
|
||||
|
||||
export default {
|
||||
suites: [shortSuite],
|
||||
};
|
55
node_modules/zod/src/v3/benchmarks/string.ts
generated
vendored
Normal file
55
node_modules/zod/src/v3/benchmarks/string.ts
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
import Benchmark from "benchmark";
|
||||
|
||||
import { z } from "zod/v3";
|
||||
|
||||
const SUITE_NAME = "z.string";
|
||||
const suite = new Benchmark.Suite(SUITE_NAME);
|
||||
|
||||
const empty = "";
|
||||
const short = "short";
|
||||
const long = "long".repeat(256);
|
||||
const manual = (str: unknown) => {
|
||||
if (typeof str !== "string") {
|
||||
throw new Error("Not a string");
|
||||
}
|
||||
|
||||
return str;
|
||||
};
|
||||
const stringSchema = z.string();
|
||||
const optionalStringSchema = z.string().optional();
|
||||
const optionalNullableStringSchema = z.string().optional().nullable();
|
||||
|
||||
suite
|
||||
.add("empty string", () => {
|
||||
stringSchema.parse(empty);
|
||||
})
|
||||
.add("short string", () => {
|
||||
stringSchema.parse(short);
|
||||
})
|
||||
.add("long string", () => {
|
||||
stringSchema.parse(long);
|
||||
})
|
||||
.add("optional string", () => {
|
||||
optionalStringSchema.parse(long);
|
||||
})
|
||||
.add("nullable string", () => {
|
||||
optionalNullableStringSchema.parse(long);
|
||||
})
|
||||
.add("nullable (null) string", () => {
|
||||
optionalNullableStringSchema.parse(null);
|
||||
})
|
||||
.add("invalid: null", () => {
|
||||
try {
|
||||
stringSchema.parse(null);
|
||||
} catch (_err) {}
|
||||
})
|
||||
.add("manual parser: long", () => {
|
||||
manual(long);
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`${SUITE_NAME}: ${e.target}`);
|
||||
});
|
||||
|
||||
export default {
|
||||
suites: [suite],
|
||||
};
|
80
node_modules/zod/src/v3/benchmarks/union.ts
generated
vendored
Normal file
80
node_modules/zod/src/v3/benchmarks/union.ts
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
import Benchmark from "benchmark";
|
||||
|
||||
import { z } from "zod/v3";
|
||||
|
||||
const doubleSuite = new Benchmark.Suite("z.union: double");
|
||||
const manySuite = new Benchmark.Suite("z.union: many");
|
||||
|
||||
const aSchema = z.object({
|
||||
type: z.literal("a"),
|
||||
});
|
||||
const objA = {
|
||||
type: "a",
|
||||
};
|
||||
|
||||
const bSchema = z.object({
|
||||
type: z.literal("b"),
|
||||
});
|
||||
const objB = {
|
||||
type: "b",
|
||||
};
|
||||
|
||||
const cSchema = z.object({
|
||||
type: z.literal("c"),
|
||||
});
|
||||
const objC = {
|
||||
type: "c",
|
||||
};
|
||||
|
||||
const dSchema = z.object({
|
||||
type: z.literal("d"),
|
||||
});
|
||||
|
||||
const double = z.union([aSchema, bSchema]);
|
||||
const many = z.union([aSchema, bSchema, cSchema, dSchema]);
|
||||
|
||||
doubleSuite
|
||||
.add("valid: a", () => {
|
||||
double.parse(objA);
|
||||
})
|
||||
.add("valid: b", () => {
|
||||
double.parse(objB);
|
||||
})
|
||||
.add("invalid: null", () => {
|
||||
try {
|
||||
double.parse(null);
|
||||
} catch (_err) {}
|
||||
})
|
||||
.add("invalid: wrong shape", () => {
|
||||
try {
|
||||
double.parse(objC);
|
||||
} catch (_err) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`${(doubleSuite as any).name}: ${e.target}`);
|
||||
});
|
||||
|
||||
manySuite
|
||||
.add("valid: a", () => {
|
||||
many.parse(objA);
|
||||
})
|
||||
.add("valid: c", () => {
|
||||
many.parse(objC);
|
||||
})
|
||||
.add("invalid: null", () => {
|
||||
try {
|
||||
many.parse(null);
|
||||
} catch (_err) {}
|
||||
})
|
||||
.add("invalid: wrong shape", () => {
|
||||
try {
|
||||
many.parse({ type: "unknown" });
|
||||
} catch (_err) {}
|
||||
})
|
||||
.on("cycle", (e: Benchmark.Event) => {
|
||||
console.log(`${(manySuite as any).name}: ${e.target}`);
|
||||
});
|
||||
|
||||
export default {
|
||||
suites: [doubleSuite, manySuite],
|
||||
};
|
13
node_modules/zod/src/v3/errors.ts
generated
vendored
Normal file
13
node_modules/zod/src/v3/errors.ts
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
import type { ZodErrorMap } from "./ZodError.js";
|
||||
import defaultErrorMap from "./locales/en.js";
|
||||
|
||||
let overrideErrorMap = defaultErrorMap;
|
||||
export { defaultErrorMap };
|
||||
|
||||
export function setErrorMap(map: ZodErrorMap) {
|
||||
overrideErrorMap = map;
|
||||
}
|
||||
|
||||
export function getErrorMap() {
|
||||
return overrideErrorMap;
|
||||
}
|
6
node_modules/zod/src/v3/external.ts
generated
vendored
Normal file
6
node_modules/zod/src/v3/external.ts
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
export * from "./errors.js";
|
||||
export * from "./helpers/parseUtil.js";
|
||||
export * from "./helpers/typeAliases.js";
|
||||
export * from "./helpers/util.js";
|
||||
export * from "./types.js";
|
||||
export * from "./ZodError.js";
|
17
node_modules/zod/src/v3/helpers/enumUtil.ts
generated
vendored
Normal file
17
node_modules/zod/src/v3/helpers/enumUtil.ts
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
export namespace enumUtil {
|
||||
type UnionToIntersectionFn<T> = (T extends unknown ? (k: () => T) => void : never) extends (
|
||||
k: infer Intersection
|
||||
) => void
|
||||
? Intersection
|
||||
: never;
|
||||
|
||||
type GetUnionLast<T> = UnionToIntersectionFn<T> extends () => infer Last ? Last : never;
|
||||
|
||||
type UnionToTuple<T, Tuple extends unknown[] = []> = [T] extends [never]
|
||||
? Tuple
|
||||
: UnionToTuple<Exclude<T, GetUnionLast<T>>, [GetUnionLast<T>, ...Tuple]>;
|
||||
|
||||
type CastToStringTuple<T> = T extends [string, ...string[]] ? T : never;
|
||||
|
||||
export type UnionToTupleString<T> = CastToStringTuple<UnionToTuple<T>>;
|
||||
}
|
8
node_modules/zod/src/v3/helpers/errorUtil.ts
generated
vendored
Normal file
8
node_modules/zod/src/v3/helpers/errorUtil.ts
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
export namespace errorUtil {
|
||||
export type ErrMessage = string | { message?: string | undefined };
|
||||
export const errToObj = (message?: ErrMessage): { message?: string | undefined } =>
|
||||
typeof message === "string" ? { message } : message || {};
|
||||
// biome-ignore lint:
|
||||
export const toString = (message?: ErrMessage): string | undefined =>
|
||||
typeof message === "string" ? message : message?.message;
|
||||
}
|
176
node_modules/zod/src/v3/helpers/parseUtil.ts
generated
vendored
Normal file
176
node_modules/zod/src/v3/helpers/parseUtil.ts
generated
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
import type { IssueData, ZodErrorMap, ZodIssue } from "../ZodError.js";
|
||||
import { getErrorMap } from "../errors.js";
|
||||
import defaultErrorMap from "../locales/en.js";
|
||||
import type { ZodParsedType } from "./util.js";
|
||||
|
||||
export const makeIssue = (params: {
|
||||
data: any;
|
||||
path: (string | number)[];
|
||||
errorMaps: ZodErrorMap[];
|
||||
issueData: IssueData;
|
||||
}): ZodIssue => {
|
||||
const { data, path, errorMaps, issueData } = params;
|
||||
const fullPath = [...path, ...(issueData.path || [])];
|
||||
const fullIssue = {
|
||||
...issueData,
|
||||
path: fullPath,
|
||||
};
|
||||
|
||||
if (issueData.message !== undefined) {
|
||||
return {
|
||||
...issueData,
|
||||
path: fullPath,
|
||||
message: issueData.message,
|
||||
};
|
||||
}
|
||||
|
||||
let errorMessage = "";
|
||||
const maps = errorMaps
|
||||
.filter((m) => !!m)
|
||||
.slice()
|
||||
.reverse();
|
||||
for (const map of maps) {
|
||||
errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message;
|
||||
}
|
||||
|
||||
return {
|
||||
...issueData,
|
||||
path: fullPath,
|
||||
message: errorMessage,
|
||||
};
|
||||
};
|
||||
|
||||
export type ParseParams = {
|
||||
path: (string | number)[];
|
||||
errorMap: ZodErrorMap;
|
||||
async: boolean;
|
||||
};
|
||||
|
||||
export type ParsePathComponent = string | number;
|
||||
export type ParsePath = ParsePathComponent[];
|
||||
export const EMPTY_PATH: ParsePath = [];
|
||||
|
||||
export interface ParseContext {
|
||||
readonly common: {
|
||||
readonly issues: ZodIssue[];
|
||||
readonly contextualErrorMap?: ZodErrorMap | undefined;
|
||||
readonly async: boolean;
|
||||
};
|
||||
readonly path: ParsePath;
|
||||
readonly schemaErrorMap?: ZodErrorMap | undefined;
|
||||
readonly parent: ParseContext | null;
|
||||
readonly data: any;
|
||||
readonly parsedType: ZodParsedType;
|
||||
}
|
||||
|
||||
export type ParseInput = {
|
||||
data: any;
|
||||
path: (string | number)[];
|
||||
parent: ParseContext;
|
||||
};
|
||||
|
||||
export function addIssueToContext(ctx: ParseContext, issueData: IssueData): void {
|
||||
const overrideMap = getErrorMap();
|
||||
const issue = makeIssue({
|
||||
issueData: issueData,
|
||||
data: ctx.data,
|
||||
path: ctx.path,
|
||||
errorMaps: [
|
||||
ctx.common.contextualErrorMap, // contextual error map is first priority
|
||||
ctx.schemaErrorMap, // then schema-bound map if available
|
||||
overrideMap, // then global override map
|
||||
overrideMap === defaultErrorMap ? undefined : defaultErrorMap, // then global default map
|
||||
].filter((x) => !!x),
|
||||
});
|
||||
ctx.common.issues.push(issue);
|
||||
}
|
||||
|
||||
export type ObjectPair = {
|
||||
key: SyncParseReturnType<any>;
|
||||
value: SyncParseReturnType<any>;
|
||||
};
|
||||
export class ParseStatus {
|
||||
value: "aborted" | "dirty" | "valid" = "valid";
|
||||
dirty(): void {
|
||||
if (this.value === "valid") this.value = "dirty";
|
||||
}
|
||||
abort(): void {
|
||||
if (this.value !== "aborted") this.value = "aborted";
|
||||
}
|
||||
|
||||
static mergeArray(status: ParseStatus, results: SyncParseReturnType<any>[]): SyncParseReturnType {
|
||||
const arrayValue: any[] = [];
|
||||
for (const s of results) {
|
||||
if (s.status === "aborted") return INVALID;
|
||||
if (s.status === "dirty") status.dirty();
|
||||
arrayValue.push(s.value);
|
||||
}
|
||||
|
||||
return { status: status.value, value: arrayValue };
|
||||
}
|
||||
|
||||
static async mergeObjectAsync(
|
||||
status: ParseStatus,
|
||||
pairs: { key: ParseReturnType<any>; value: ParseReturnType<any> }[]
|
||||
): Promise<SyncParseReturnType<any>> {
|
||||
const syncPairs: ObjectPair[] = [];
|
||||
for (const pair of pairs) {
|
||||
const key = await pair.key;
|
||||
const value = await pair.value;
|
||||
syncPairs.push({
|
||||
key,
|
||||
value,
|
||||
});
|
||||
}
|
||||
return ParseStatus.mergeObjectSync(status, syncPairs);
|
||||
}
|
||||
|
||||
static mergeObjectSync(
|
||||
status: ParseStatus,
|
||||
pairs: {
|
||||
key: SyncParseReturnType<any>;
|
||||
value: SyncParseReturnType<any>;
|
||||
alwaysSet?: boolean;
|
||||
}[]
|
||||
): SyncParseReturnType {
|
||||
const finalObject: any = {};
|
||||
for (const pair of pairs) {
|
||||
const { key, value } = pair;
|
||||
if (key.status === "aborted") return INVALID;
|
||||
if (value.status === "aborted") return INVALID;
|
||||
if (key.status === "dirty") status.dirty();
|
||||
if (value.status === "dirty") status.dirty();
|
||||
|
||||
if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) {
|
||||
finalObject[key.value] = value.value;
|
||||
}
|
||||
}
|
||||
|
||||
return { status: status.value, value: finalObject };
|
||||
}
|
||||
}
|
||||
export interface ParseResult {
|
||||
status: "aborted" | "dirty" | "valid";
|
||||
data: any;
|
||||
}
|
||||
|
||||
export type INVALID = { status: "aborted" };
|
||||
export const INVALID: INVALID = Object.freeze({
|
||||
status: "aborted",
|
||||
});
|
||||
|
||||
export type DIRTY<T> = { status: "dirty"; value: T };
|
||||
export const DIRTY = <T>(value: T): DIRTY<T> => ({ status: "dirty", value });
|
||||
|
||||
export type OK<T> = { status: "valid"; value: T };
|
||||
export const OK = <T>(value: T): OK<T> => ({ status: "valid", value });
|
||||
|
||||
export type SyncParseReturnType<T = any> = OK<T> | DIRTY<T> | INVALID;
|
||||
export type AsyncParseReturnType<T> = Promise<SyncParseReturnType<T>>;
|
||||
export type ParseReturnType<T> = SyncParseReturnType<T> | AsyncParseReturnType<T>;
|
||||
|
||||
export const isAborted = (x: ParseReturnType<any>): x is INVALID => (x as any).status === "aborted";
|
||||
export const isDirty = <T>(x: ParseReturnType<T>): x is OK<T> | DIRTY<T> => (x as any).status === "dirty";
|
||||
export const isValid = <T>(x: ParseReturnType<T>): x is OK<T> => (x as any).status === "valid";
|
||||
export const isAsync = <T>(x: ParseReturnType<T>): x is AsyncParseReturnType<T> =>
|
||||
typeof Promise !== "undefined" && x instanceof Promise;
|
34
node_modules/zod/src/v3/helpers/partialUtil.ts
generated
vendored
Normal file
34
node_modules/zod/src/v3/helpers/partialUtil.ts
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
import type {
|
||||
ZodArray,
|
||||
ZodNullable,
|
||||
ZodObject,
|
||||
ZodOptional,
|
||||
ZodRawShape,
|
||||
ZodTuple,
|
||||
ZodTupleItems,
|
||||
ZodTypeAny,
|
||||
} from "../types.js";
|
||||
|
||||
export namespace partialUtil {
|
||||
export type DeepPartial<T extends ZodTypeAny> = T extends ZodObject<ZodRawShape>
|
||||
? ZodObject<
|
||||
{ [k in keyof T["shape"]]: ZodOptional<DeepPartial<T["shape"][k]>> },
|
||||
T["_def"]["unknownKeys"],
|
||||
T["_def"]["catchall"]
|
||||
>
|
||||
: T extends ZodArray<infer Type, infer Card>
|
||||
? ZodArray<DeepPartial<Type>, Card>
|
||||
: T extends ZodOptional<infer Type>
|
||||
? ZodOptional<DeepPartial<Type>>
|
||||
: T extends ZodNullable<infer Type>
|
||||
? ZodNullable<DeepPartial<Type>>
|
||||
: T extends ZodTuple<infer Items>
|
||||
? {
|
||||
[k in keyof Items]: Items[k] extends ZodTypeAny ? DeepPartial<Items[k]> : never;
|
||||
} extends infer PI
|
||||
? PI extends ZodTupleItems
|
||||
? ZodTuple<PI>
|
||||
: never
|
||||
: never
|
||||
: T;
|
||||
}
|
2
node_modules/zod/src/v3/helpers/typeAliases.ts
generated
vendored
Normal file
2
node_modules/zod/src/v3/helpers/typeAliases.ts
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
export type Primitive = string | number | symbol | bigint | boolean | null | undefined;
|
||||
export type Scalars = Primitive | Primitive[];
|
224
node_modules/zod/src/v3/helpers/util.ts
generated
vendored
Normal file
224
node_modules/zod/src/v3/helpers/util.ts
generated
vendored
Normal file
|
@ -0,0 +1,224 @@
|
|||
export namespace util {
|
||||
type AssertEqual<T, U> = (<V>() => V extends T ? 1 : 2) extends <V>() => V extends U ? 1 : 2 ? true : false;
|
||||
|
||||
export type isAny<T> = 0 extends 1 & T ? true : false;
|
||||
export const assertEqual = <A, B>(_: AssertEqual<A, B>): void => {};
|
||||
export function assertIs<T>(_arg: T): void {}
|
||||
export function assertNever(_x: never): never {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
|
||||
export type OmitKeys<T, K extends string> = Pick<T, Exclude<keyof T, K>>;
|
||||
export type MakePartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
||||
export type Exactly<T, X> = T & Record<Exclude<keyof X, keyof T>, never>;
|
||||
export type InexactPartial<T> = { [k in keyof T]?: T[k] | undefined };
|
||||
export const arrayToEnum = <T extends string, U extends [T, ...T[]]>(items: U): { [k in U[number]]: k } => {
|
||||
const obj: any = {};
|
||||
for (const item of items) {
|
||||
obj[item] = item;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
export const getValidEnumValues = (obj: any): any[] => {
|
||||
const validKeys = objectKeys(obj).filter((k: any) => typeof obj[obj[k]] !== "number");
|
||||
const filtered: any = {};
|
||||
for (const k of validKeys) {
|
||||
filtered[k] = obj[k];
|
||||
}
|
||||
return objectValues(filtered);
|
||||
};
|
||||
|
||||
export const objectValues = (obj: any): any[] => {
|
||||
return objectKeys(obj).map(function (e) {
|
||||
return obj[e];
|
||||
});
|
||||
};
|
||||
|
||||
export const objectKeys: ObjectConstructor["keys"] =
|
||||
typeof Object.keys === "function" // eslint-disable-line ban/ban
|
||||
? (obj: any) => Object.keys(obj) // eslint-disable-line ban/ban
|
||||
: (object: any) => {
|
||||
const keys = [];
|
||||
for (const key in object) {
|
||||
if (Object.prototype.hasOwnProperty.call(object, key)) {
|
||||
keys.push(key);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
};
|
||||
|
||||
export const find = <T>(arr: T[], checker: (arg: T) => any): T | undefined => {
|
||||
for (const item of arr) {
|
||||
if (checker(item)) return item;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export type identity<T> = objectUtil.identity<T>;
|
||||
export type flatten<T> = objectUtil.flatten<T>;
|
||||
|
||||
export type noUndefined<T> = T extends undefined ? never : T;
|
||||
|
||||
export const isInteger: NumberConstructor["isInteger"] =
|
||||
typeof Number.isInteger === "function"
|
||||
? (val) => Number.isInteger(val) // eslint-disable-line ban/ban
|
||||
: (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val;
|
||||
|
||||
export function joinValues<T extends any[]>(array: T, separator = " | "): string {
|
||||
return array.map((val) => (typeof val === "string" ? `'${val}'` : val)).join(separator);
|
||||
}
|
||||
|
||||
export const jsonStringifyReplacer = (_: string, value: any): any => {
|
||||
if (typeof value === "bigint") {
|
||||
return value.toString();
|
||||
}
|
||||
return value;
|
||||
};
|
||||
}
|
||||
|
||||
export namespace objectUtil {
|
||||
export type MergeShapes<U, V> =
|
||||
// fast path when there is no keys overlap
|
||||
keyof U & keyof V extends never
|
||||
? U & V
|
||||
: {
|
||||
[k in Exclude<keyof U, keyof V>]: U[k];
|
||||
} & V;
|
||||
|
||||
type optionalKeys<T extends object> = {
|
||||
[k in keyof T]: undefined extends T[k] ? k : never;
|
||||
}[keyof T];
|
||||
type requiredKeys<T extends object> = {
|
||||
[k in keyof T]: undefined extends T[k] ? never : k;
|
||||
}[keyof T];
|
||||
export type addQuestionMarks<T extends object, _O = any> = {
|
||||
[K in requiredKeys<T>]: T[K];
|
||||
} & {
|
||||
[K in optionalKeys<T>]?: T[K];
|
||||
} & { [k in keyof T]?: unknown };
|
||||
|
||||
export type identity<T> = T;
|
||||
export type flatten<T> = identity<{ [k in keyof T]: T[k] }>;
|
||||
|
||||
export type noNeverKeys<T> = {
|
||||
[k in keyof T]: [T[k]] extends [never] ? never : k;
|
||||
}[keyof T];
|
||||
|
||||
export type noNever<T> = identity<{
|
||||
[k in noNeverKeys<T>]: k extends keyof T ? T[k] : never;
|
||||
}>;
|
||||
|
||||
export const mergeShapes = <U, T>(first: U, second: T): T & U => {
|
||||
return {
|
||||
...first,
|
||||
...second, // second overwrites first
|
||||
};
|
||||
};
|
||||
|
||||
export type extendShape<A extends object, B extends object> = keyof A & keyof B extends never // fast path when there is no keys overlap
|
||||
? A & B
|
||||
: {
|
||||
[K in keyof A as K extends keyof B ? never : K]: A[K];
|
||||
} & {
|
||||
[K in keyof B]: B[K];
|
||||
};
|
||||
}
|
||||
|
||||
export const ZodParsedType: {
|
||||
string: "string";
|
||||
nan: "nan";
|
||||
number: "number";
|
||||
integer: "integer";
|
||||
float: "float";
|
||||
boolean: "boolean";
|
||||
date: "date";
|
||||
bigint: "bigint";
|
||||
symbol: "symbol";
|
||||
function: "function";
|
||||
undefined: "undefined";
|
||||
null: "null";
|
||||
array: "array";
|
||||
object: "object";
|
||||
unknown: "unknown";
|
||||
promise: "promise";
|
||||
void: "void";
|
||||
never: "never";
|
||||
map: "map";
|
||||
set: "set";
|
||||
} = util.arrayToEnum([
|
||||
"string",
|
||||
"nan",
|
||||
"number",
|
||||
"integer",
|
||||
"float",
|
||||
"boolean",
|
||||
"date",
|
||||
"bigint",
|
||||
"symbol",
|
||||
"function",
|
||||
"undefined",
|
||||
"null",
|
||||
"array",
|
||||
"object",
|
||||
"unknown",
|
||||
"promise",
|
||||
"void",
|
||||
"never",
|
||||
"map",
|
||||
"set",
|
||||
]);
|
||||
|
||||
export type ZodParsedType = keyof typeof ZodParsedType;
|
||||
|
||||
export const getParsedType = (data: any): ZodParsedType => {
|
||||
const t = typeof data;
|
||||
|
||||
switch (t) {
|
||||
case "undefined":
|
||||
return ZodParsedType.undefined;
|
||||
|
||||
case "string":
|
||||
return ZodParsedType.string;
|
||||
|
||||
case "number":
|
||||
return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;
|
||||
|
||||
case "boolean":
|
||||
return ZodParsedType.boolean;
|
||||
|
||||
case "function":
|
||||
return ZodParsedType.function;
|
||||
|
||||
case "bigint":
|
||||
return ZodParsedType.bigint;
|
||||
|
||||
case "symbol":
|
||||
return ZodParsedType.symbol;
|
||||
|
||||
case "object":
|
||||
if (Array.isArray(data)) {
|
||||
return ZodParsedType.array;
|
||||
}
|
||||
if (data === null) {
|
||||
return ZodParsedType.null;
|
||||
}
|
||||
if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") {
|
||||
return ZodParsedType.promise;
|
||||
}
|
||||
if (typeof Map !== "undefined" && data instanceof Map) {
|
||||
return ZodParsedType.map;
|
||||
}
|
||||
if (typeof Set !== "undefined" && data instanceof Set) {
|
||||
return ZodParsedType.set;
|
||||
}
|
||||
if (typeof Date !== "undefined" && data instanceof Date) {
|
||||
return ZodParsedType.date;
|
||||
}
|
||||
return ZodParsedType.object;
|
||||
|
||||
default:
|
||||
return ZodParsedType.unknown;
|
||||
}
|
||||
};
|
4
node_modules/zod/src/v3/index.ts
generated
vendored
Normal file
4
node_modules/zod/src/v3/index.ts
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
import * as z from "./external.js";
|
||||
export * from "./external.js";
|
||||
export { z };
|
||||
export default z;
|
124
node_modules/zod/src/v3/locales/en.ts
generated
vendored
Normal file
124
node_modules/zod/src/v3/locales/en.ts
generated
vendored
Normal file
|
@ -0,0 +1,124 @@
|
|||
import { type ZodErrorMap, ZodIssueCode } from "../ZodError.js";
|
||||
import { util, ZodParsedType } from "../helpers/util.js";
|
||||
|
||||
const errorMap: ZodErrorMap = (issue, _ctx) => {
|
||||
let message: string;
|
||||
switch (issue.code) {
|
||||
case ZodIssueCode.invalid_type:
|
||||
if (issue.received === ZodParsedType.undefined) {
|
||||
message = "Required";
|
||||
} else {
|
||||
message = `Expected ${issue.expected}, received ${issue.received}`;
|
||||
}
|
||||
break;
|
||||
case ZodIssueCode.invalid_literal:
|
||||
message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`;
|
||||
break;
|
||||
case ZodIssueCode.unrecognized_keys:
|
||||
message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;
|
||||
break;
|
||||
case ZodIssueCode.invalid_union:
|
||||
message = `Invalid input`;
|
||||
break;
|
||||
case ZodIssueCode.invalid_union_discriminator:
|
||||
message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;
|
||||
break;
|
||||
case ZodIssueCode.invalid_enum_value:
|
||||
message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;
|
||||
break;
|
||||
case ZodIssueCode.invalid_arguments:
|
||||
message = `Invalid function arguments`;
|
||||
break;
|
||||
case ZodIssueCode.invalid_return_type:
|
||||
message = `Invalid function return type`;
|
||||
break;
|
||||
case ZodIssueCode.invalid_date:
|
||||
message = `Invalid date`;
|
||||
break;
|
||||
case ZodIssueCode.invalid_string:
|
||||
if (typeof issue.validation === "object") {
|
||||
if ("includes" in issue.validation) {
|
||||
message = `Invalid input: must include "${issue.validation.includes}"`;
|
||||
|
||||
if (typeof issue.validation.position === "number") {
|
||||
message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;
|
||||
}
|
||||
} else if ("startsWith" in issue.validation) {
|
||||
message = `Invalid input: must start with "${issue.validation.startsWith}"`;
|
||||
} else if ("endsWith" in issue.validation) {
|
||||
message = `Invalid input: must end with "${issue.validation.endsWith}"`;
|
||||
} else {
|
||||
util.assertNever(issue.validation);
|
||||
}
|
||||
} else if (issue.validation !== "regex") {
|
||||
message = `Invalid ${issue.validation}`;
|
||||
} else {
|
||||
message = "Invalid";
|
||||
}
|
||||
break;
|
||||
case ZodIssueCode.too_small:
|
||||
if (issue.type === "array")
|
||||
message = `Array must contain ${
|
||||
issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`
|
||||
} ${issue.minimum} element(s)`;
|
||||
else if (issue.type === "string")
|
||||
message = `String must contain ${
|
||||
issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`
|
||||
} ${issue.minimum} character(s)`;
|
||||
else if (issue.type === "number")
|
||||
message = `Number must be ${
|
||||
issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `
|
||||
}${issue.minimum}`;
|
||||
else if (issue.type === "bigint")
|
||||
message = `Number must be ${
|
||||
issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `
|
||||
}${issue.minimum}`;
|
||||
else if (issue.type === "date")
|
||||
message = `Date must be ${
|
||||
issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `
|
||||
}${new Date(Number(issue.minimum))}`;
|
||||
else message = "Invalid input";
|
||||
break;
|
||||
case ZodIssueCode.too_big:
|
||||
if (issue.type === "array")
|
||||
message = `Array must contain ${
|
||||
issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`
|
||||
} ${issue.maximum} element(s)`;
|
||||
else if (issue.type === "string")
|
||||
message = `String must contain ${
|
||||
issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`
|
||||
} ${issue.maximum} character(s)`;
|
||||
else if (issue.type === "number")
|
||||
message = `Number must be ${
|
||||
issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`
|
||||
} ${issue.maximum}`;
|
||||
else if (issue.type === "bigint")
|
||||
message = `BigInt must be ${
|
||||
issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`
|
||||
} ${issue.maximum}`;
|
||||
else if (issue.type === "date")
|
||||
message = `Date must be ${
|
||||
issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`
|
||||
} ${new Date(Number(issue.maximum))}`;
|
||||
else message = "Invalid input";
|
||||
break;
|
||||
case ZodIssueCode.custom:
|
||||
message = `Invalid input`;
|
||||
break;
|
||||
case ZodIssueCode.invalid_intersection_types:
|
||||
message = `Intersection results could not be merged`;
|
||||
break;
|
||||
case ZodIssueCode.not_multiple_of:
|
||||
message = `Number must be a multiple of ${issue.multipleOf}`;
|
||||
break;
|
||||
case ZodIssueCode.not_finite:
|
||||
message = "Number must be finite";
|
||||
break;
|
||||
default:
|
||||
message = _ctx.defaultError;
|
||||
util.assertNever(issue);
|
||||
}
|
||||
return { message };
|
||||
};
|
||||
|
||||
export default errorMap;
|
113
node_modules/zod/src/v3/standard-schema.ts
generated
vendored
Normal file
113
node_modules/zod/src/v3/standard-schema.ts
generated
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* The Standard Schema interface.
|
||||
*/
|
||||
export type StandardSchemaV1<Input = unknown, Output = Input> = {
|
||||
/**
|
||||
* The Standard Schema properties.
|
||||
*/
|
||||
readonly "~standard": StandardSchemaV1.Props<Input, Output>;
|
||||
};
|
||||
|
||||
export declare namespace StandardSchemaV1 {
|
||||
/**
|
||||
* The Standard Schema properties interface.
|
||||
*/
|
||||
export interface Props<Input = unknown, Output = Input> {
|
||||
/**
|
||||
* The version number of the standard.
|
||||
*/
|
||||
readonly version: 1;
|
||||
/**
|
||||
* The vendor name of the schema library.
|
||||
*/
|
||||
readonly vendor: string;
|
||||
/**
|
||||
* Validates unknown input values.
|
||||
*/
|
||||
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
|
||||
/**
|
||||
* Inferred types associated with the schema.
|
||||
*/
|
||||
readonly types?: Types<Input, Output> | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The result interface of the validate function.
|
||||
*/
|
||||
export type Result<Output> = SuccessResult<Output> | FailureResult;
|
||||
|
||||
/**
|
||||
* The result interface if validation succeeds.
|
||||
*/
|
||||
export interface SuccessResult<Output> {
|
||||
/**
|
||||
* The typed output value.
|
||||
*/
|
||||
readonly value: Output;
|
||||
/**
|
||||
* The non-existent issues.
|
||||
*/
|
||||
readonly issues?: undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The result interface if validation fails.
|
||||
*/
|
||||
export interface FailureResult {
|
||||
/**
|
||||
* The issues of failed validation.
|
||||
*/
|
||||
readonly issues: ReadonlyArray<Issue>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The issue interface of the failure output.
|
||||
*/
|
||||
export interface Issue {
|
||||
/**
|
||||
* The error message of the issue.
|
||||
*/
|
||||
readonly message: string;
|
||||
/**
|
||||
* The path of the issue, if any.
|
||||
*/
|
||||
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The path segment interface of the issue.
|
||||
*/
|
||||
export interface PathSegment {
|
||||
/**
|
||||
* The key representing a path segment.
|
||||
*/
|
||||
readonly key: PropertyKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Standard Schema types interface.
|
||||
*/
|
||||
export interface Types<Input = unknown, Output = Input> {
|
||||
/**
|
||||
* The input type of the schema.
|
||||
*/
|
||||
readonly input: Input;
|
||||
/**
|
||||
* The output type of the schema.
|
||||
*/
|
||||
readonly output: Output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Infers the input type of a Standard Schema.
|
||||
*/
|
||||
export type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"];
|
||||
|
||||
/**
|
||||
* Infers the output type of a Standard Schema.
|
||||
*/
|
||||
export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
|
||||
|
||||
// biome-ignore lint/complexity/noUselessEmptyExport: needed for granular visibility control of TS namespace
|
||||
export {};
|
||||
}
|
54
node_modules/zod/src/v3/tests/Mocker.ts
generated
vendored
Normal file
54
node_modules/zod/src/v3/tests/Mocker.ts
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
function getRandomInt(max: number) {
|
||||
return Math.floor(Math.random() * Math.floor(max));
|
||||
}
|
||||
|
||||
const testSymbol = Symbol("test");
|
||||
|
||||
export class Mocker {
|
||||
pick = (...args: any[]): any => {
|
||||
return args[getRandomInt(args.length)];
|
||||
};
|
||||
|
||||
get string(): string {
|
||||
return Math.random().toString(36).substring(7);
|
||||
}
|
||||
get number(): number {
|
||||
return Math.random() * 100;
|
||||
}
|
||||
get bigint(): bigint {
|
||||
return BigInt(Math.floor(Math.random() * 10000));
|
||||
}
|
||||
get boolean(): boolean {
|
||||
return Math.random() < 0.5;
|
||||
}
|
||||
get date(): Date {
|
||||
return new Date(Math.floor(Date.now() * Math.random()));
|
||||
}
|
||||
get symbol(): symbol {
|
||||
return testSymbol;
|
||||
}
|
||||
get null(): null {
|
||||
return null;
|
||||
}
|
||||
get undefined(): undefined {
|
||||
return undefined;
|
||||
}
|
||||
get stringOptional(): string | undefined {
|
||||
return this.pick(this.string, this.undefined);
|
||||
}
|
||||
get stringNullable(): string | null {
|
||||
return this.pick(this.string, this.null);
|
||||
}
|
||||
get numberOptional(): number | undefined {
|
||||
return this.pick(this.number, this.undefined);
|
||||
}
|
||||
get numberNullable(): number | null {
|
||||
return this.pick(this.number, this.null);
|
||||
}
|
||||
get booleanOptional(): boolean | undefined {
|
||||
return this.pick(this.boolean, this.undefined);
|
||||
}
|
||||
get booleanNullable(): boolean | null {
|
||||
return this.pick(this.boolean, this.null);
|
||||
}
|
||||
}
|
157
node_modules/zod/src/v3/tests/all-errors.test.ts
generated
vendored
Normal file
157
node_modules/zod/src/v3/tests/all-errors.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
const Test = z.object({
|
||||
f1: z.number(),
|
||||
f2: z.string().optional(),
|
||||
f3: z.string().nullable(),
|
||||
f4: z.array(z.object({ t: z.union([z.string(), z.boolean()]) })),
|
||||
});
|
||||
type TestFlattenedErrors = z.inferFlattenedErrors<typeof Test, { message: string; code: number }>;
|
||||
type TestFormErrors = z.inferFlattenedErrors<typeof Test>;
|
||||
|
||||
test("default flattened errors type inference", () => {
|
||||
type TestTypeErrors = {
|
||||
formErrors: string[];
|
||||
fieldErrors: { [P in keyof z.TypeOf<typeof Test>]?: string[] | undefined };
|
||||
};
|
||||
|
||||
util.assertEqual<z.inferFlattenedErrors<typeof Test>, TestTypeErrors>(true);
|
||||
util.assertEqual<z.inferFlattenedErrors<typeof Test, { message: string }>, TestTypeErrors>(false);
|
||||
});
|
||||
|
||||
test("custom flattened errors type inference", () => {
|
||||
type ErrorType = { message: string; code: number };
|
||||
type TestTypeErrors = {
|
||||
formErrors: ErrorType[];
|
||||
fieldErrors: {
|
||||
[P in keyof z.TypeOf<typeof Test>]?: ErrorType[] | undefined;
|
||||
};
|
||||
};
|
||||
|
||||
util.assertEqual<z.inferFlattenedErrors<typeof Test>, TestTypeErrors>(false);
|
||||
util.assertEqual<z.inferFlattenedErrors<typeof Test, { message: string; code: number }>, TestTypeErrors>(true);
|
||||
util.assertEqual<z.inferFlattenedErrors<typeof Test, { message: string }>, TestTypeErrors>(false);
|
||||
});
|
||||
|
||||
test("form errors type inference", () => {
|
||||
type TestTypeErrors = {
|
||||
formErrors: string[];
|
||||
fieldErrors: { [P in keyof z.TypeOf<typeof Test>]?: string[] | undefined };
|
||||
};
|
||||
|
||||
util.assertEqual<z.inferFlattenedErrors<typeof Test>, TestTypeErrors>(true);
|
||||
});
|
||||
|
||||
test(".flatten() type assertion", () => {
|
||||
const parsed = Test.safeParse({}) as z.SafeParseError<void>;
|
||||
const validFlattenedErrors: TestFlattenedErrors = parsed.error.flatten(() => ({ message: "", code: 0 }));
|
||||
// @ts-expect-error should fail assertion between `TestFlattenedErrors` and unmapped `flatten()`.
|
||||
const invalidFlattenedErrors: TestFlattenedErrors = parsed.error.flatten();
|
||||
const validFormErrors: TestFormErrors = parsed.error.flatten();
|
||||
// @ts-expect-error should fail assertion between `TestFormErrors` and mapped `flatten()`.
|
||||
const invalidFormErrors: TestFormErrors = parsed.error.flatten(() => ({
|
||||
message: "string",
|
||||
code: 0,
|
||||
}));
|
||||
|
||||
[validFlattenedErrors, invalidFlattenedErrors, validFormErrors, invalidFormErrors];
|
||||
});
|
||||
|
||||
test(".formErrors type assertion", () => {
|
||||
const parsed = Test.safeParse({}) as z.SafeParseError<void>;
|
||||
const validFormErrors: TestFormErrors = parsed.error.formErrors;
|
||||
// @ts-expect-error should fail assertion between `TestFlattenedErrors` and `.formErrors`.
|
||||
const invalidFlattenedErrors: TestFlattenedErrors = parsed.error.formErrors;
|
||||
|
||||
[validFormErrors, invalidFlattenedErrors];
|
||||
});
|
||||
|
||||
test("all errors", () => {
|
||||
const propertySchema = z.string();
|
||||
const schema = z
|
||||
.object({
|
||||
a: propertySchema,
|
||||
b: propertySchema,
|
||||
})
|
||||
.refine(
|
||||
(val) => {
|
||||
return val.a === val.b;
|
||||
},
|
||||
{ message: "Must be equal" }
|
||||
);
|
||||
|
||||
try {
|
||||
schema.parse({
|
||||
a: "asdf",
|
||||
b: "qwer",
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
expect(error.flatten()).toEqual({
|
||||
formErrors: ["Must be equal"],
|
||||
fieldErrors: {},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
schema.parse({
|
||||
a: null,
|
||||
b: null,
|
||||
});
|
||||
} catch (_error) {
|
||||
const error = _error as z.ZodError;
|
||||
expect(error.flatten()).toEqual({
|
||||
formErrors: [],
|
||||
fieldErrors: {
|
||||
a: ["Expected string, received null"],
|
||||
b: ["Expected string, received null"],
|
||||
},
|
||||
});
|
||||
|
||||
expect(error.flatten((iss) => iss.message.toUpperCase())).toEqual({
|
||||
formErrors: [],
|
||||
fieldErrors: {
|
||||
a: ["EXPECTED STRING, RECEIVED NULL"],
|
||||
b: ["EXPECTED STRING, RECEIVED NULL"],
|
||||
},
|
||||
});
|
||||
// Test identity
|
||||
|
||||
expect(error.flatten((i: z.ZodIssue) => i)).toEqual({
|
||||
formErrors: [],
|
||||
fieldErrors: {
|
||||
a: [
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "string",
|
||||
message: "Expected string, received null",
|
||||
path: ["a"],
|
||||
received: "null",
|
||||
},
|
||||
],
|
||||
b: [
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "string",
|
||||
message: "Expected string, received null",
|
||||
path: ["b"],
|
||||
received: "null",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
// Test mapping
|
||||
expect(error.flatten((i: z.ZodIssue) => i.message.length)).toEqual({
|
||||
formErrors: [],
|
||||
fieldErrors: {
|
||||
a: ["Expected string, received null".length],
|
||||
b: ["Expected string, received null".length],
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
28
node_modules/zod/src/v3/tests/anyunknown.test.ts
generated
vendored
Normal file
28
node_modules/zod/src/v3/tests/anyunknown.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("check any inference", () => {
|
||||
const t1 = z.any();
|
||||
t1.optional();
|
||||
t1.nullable();
|
||||
type t1 = z.infer<typeof t1>;
|
||||
util.assertEqual<t1, any>(true);
|
||||
});
|
||||
|
||||
test("check unknown inference", () => {
|
||||
const t1 = z.unknown();
|
||||
t1.optional();
|
||||
t1.nullable();
|
||||
type t1 = z.infer<typeof t1>;
|
||||
util.assertEqual<t1, unknown>(true);
|
||||
});
|
||||
|
||||
test("check never inference", () => {
|
||||
const t1 = z.never();
|
||||
expect(() => t1.parse(undefined)).toThrow();
|
||||
expect(() => t1.parse("asdf")).toThrow();
|
||||
expect(() => t1.parse(null)).toThrow();
|
||||
});
|
71
node_modules/zod/src/v3/tests/array.test.ts
generated
vendored
Normal file
71
node_modules/zod/src/v3/tests/array.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
const minTwo = z.string().array().min(2);
|
||||
const maxTwo = z.string().array().max(2);
|
||||
const justTwo = z.string().array().length(2);
|
||||
const intNum = z.string().array().nonempty();
|
||||
const nonEmptyMax = z.string().array().nonempty().max(2);
|
||||
|
||||
type t1 = z.infer<typeof nonEmptyMax>;
|
||||
util.assertEqual<[string, ...string[]], t1>(true);
|
||||
|
||||
type t2 = z.infer<typeof minTwo>;
|
||||
util.assertEqual<string[], t2>(true);
|
||||
|
||||
test("passing validations", () => {
|
||||
minTwo.parse(["a", "a"]);
|
||||
minTwo.parse(["a", "a", "a"]);
|
||||
maxTwo.parse(["a", "a"]);
|
||||
maxTwo.parse(["a"]);
|
||||
justTwo.parse(["a", "a"]);
|
||||
intNum.parse(["a"]);
|
||||
nonEmptyMax.parse(["a"]);
|
||||
});
|
||||
|
||||
test("failing validations", () => {
|
||||
expect(() => minTwo.parse(["a"])).toThrow();
|
||||
expect(() => maxTwo.parse(["a", "a", "a"])).toThrow();
|
||||
expect(() => justTwo.parse(["a"])).toThrow();
|
||||
expect(() => justTwo.parse(["a", "a", "a"])).toThrow();
|
||||
expect(() => intNum.parse([])).toThrow();
|
||||
expect(() => nonEmptyMax.parse([])).toThrow();
|
||||
expect(() => nonEmptyMax.parse(["a", "a", "a"])).toThrow();
|
||||
});
|
||||
|
||||
test("parse empty array in nonempty", () => {
|
||||
expect(() =>
|
||||
z
|
||||
.array(z.string())
|
||||
.nonempty()
|
||||
.parse([] as any)
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
test("get element", () => {
|
||||
justTwo.element.parse("asdf");
|
||||
expect(() => justTwo.element.parse(12)).toThrow();
|
||||
});
|
||||
|
||||
test("continue parsing despite array size error", () => {
|
||||
const schema = z.object({
|
||||
people: z.string().array().min(2),
|
||||
});
|
||||
|
||||
const result = schema.safeParse({
|
||||
people: [123],
|
||||
});
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
}
|
||||
});
|
||||
|
||||
test("parse should fail given sparse array", () => {
|
||||
const schema = z.array(z.string()).nonempty().min(1).max(3);
|
||||
|
||||
expect(() => schema.parse(new Array(3))).toThrow();
|
||||
});
|
388
node_modules/zod/src/v3/tests/async-parsing.test.ts
generated
vendored
Normal file
388
node_modules/zod/src/v3/tests/async-parsing.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,388 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
/// string
|
||||
const stringSchema = z.string();
|
||||
|
||||
test("string async parse", async () => {
|
||||
const goodData = "XXX";
|
||||
const badData = 12;
|
||||
|
||||
const goodResult = await stringSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await stringSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// number
|
||||
const numberSchema = z.number();
|
||||
test("number async parse", async () => {
|
||||
const goodData = 1234.2353;
|
||||
const badData = "1234";
|
||||
|
||||
const goodResult = await numberSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await numberSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// bigInt
|
||||
const bigIntSchema = z.bigint();
|
||||
test("bigInt async parse", async () => {
|
||||
const goodData = BigInt(145);
|
||||
const badData = 134;
|
||||
|
||||
const goodResult = await bigIntSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await bigIntSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// boolean
|
||||
const booleanSchema = z.boolean();
|
||||
test("boolean async parse", async () => {
|
||||
const goodData = true;
|
||||
const badData = 1;
|
||||
|
||||
const goodResult = await booleanSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await booleanSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// date
|
||||
const dateSchema = z.date();
|
||||
test("date async parse", async () => {
|
||||
const goodData = new Date();
|
||||
const badData = new Date().toISOString();
|
||||
|
||||
const goodResult = await dateSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await dateSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// undefined
|
||||
const undefinedSchema = z.undefined();
|
||||
test("undefined async parse", async () => {
|
||||
const goodData = undefined;
|
||||
const badData = "XXX";
|
||||
|
||||
const goodResult = await undefinedSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(undefined);
|
||||
|
||||
const badResult = await undefinedSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// null
|
||||
const nullSchema = z.null();
|
||||
test("null async parse", async () => {
|
||||
const goodData = null;
|
||||
const badData = undefined;
|
||||
|
||||
const goodResult = await nullSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await nullSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// any
|
||||
const anySchema = z.any();
|
||||
test("any async parse", async () => {
|
||||
const goodData = [{}];
|
||||
// const badData = 'XXX';
|
||||
|
||||
const goodResult = await anySchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
// const badResult = await anySchema.safeParseAsync(badData);
|
||||
// expect(badResult.success).toBe(false);
|
||||
// if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// unknown
|
||||
const unknownSchema = z.unknown();
|
||||
test("unknown async parse", async () => {
|
||||
const goodData = ["asdf", 124, () => {}];
|
||||
// const badData = 'XXX';
|
||||
|
||||
const goodResult = await unknownSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
// const badResult = await unknownSchema.safeParseAsync(badData);
|
||||
// expect(badResult.success).toBe(false);
|
||||
// if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// void
|
||||
const voidSchema = z.void();
|
||||
test("void async parse", async () => {
|
||||
const goodData = undefined;
|
||||
const badData = 0;
|
||||
|
||||
const goodResult = await voidSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await voidSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// array
|
||||
const arraySchema = z.array(z.string());
|
||||
test("array async parse", async () => {
|
||||
const goodData = ["XXX"];
|
||||
const badData = "XXX";
|
||||
|
||||
const goodResult = await arraySchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await arraySchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// object
|
||||
const objectSchema = z.object({ string: z.string() });
|
||||
test("object async parse", async () => {
|
||||
const goodData = { string: "XXX" };
|
||||
const badData = { string: 12 };
|
||||
|
||||
const goodResult = await objectSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await objectSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// union
|
||||
const unionSchema = z.union([z.string(), z.undefined()]);
|
||||
test("union async parse", async () => {
|
||||
const goodData = undefined;
|
||||
const badData = null;
|
||||
|
||||
const goodResult = await unionSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await unionSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// record
|
||||
const recordSchema = z.record(z.object({}));
|
||||
test("record async parse", async () => {
|
||||
const goodData = { adsf: {}, asdf: {} };
|
||||
const badData = [{}];
|
||||
|
||||
const goodResult = await recordSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await recordSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// function
|
||||
const functionSchema = z.function();
|
||||
test("function async parse", async () => {
|
||||
const goodData = () => {};
|
||||
const badData = "XXX";
|
||||
|
||||
const goodResult = await functionSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(typeof goodResult.data).toEqual("function");
|
||||
|
||||
const badResult = await functionSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// literal
|
||||
const literalSchema = z.literal("asdf");
|
||||
test("literal async parse", async () => {
|
||||
const goodData = "asdf";
|
||||
const badData = "asdff";
|
||||
|
||||
const goodResult = await literalSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await literalSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// enum
|
||||
const enumSchema = z.enum(["fish", "whale"]);
|
||||
test("enum async parse", async () => {
|
||||
const goodData = "whale";
|
||||
const badData = "leopard";
|
||||
|
||||
const goodResult = await enumSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await enumSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// nativeEnum
|
||||
enum nativeEnumTest {
|
||||
asdf = "qwer",
|
||||
}
|
||||
// @ts-ignore
|
||||
const nativeEnumSchema = z.nativeEnum(nativeEnumTest);
|
||||
test("nativeEnum async parse", async () => {
|
||||
const goodData = nativeEnumTest.asdf;
|
||||
const badData = "asdf";
|
||||
|
||||
const goodResult = await nativeEnumSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await nativeEnumSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// promise
|
||||
const promiseSchema = z.promise(z.number());
|
||||
test("promise async parse good", async () => {
|
||||
const goodData = Promise.resolve(123);
|
||||
|
||||
const goodResult = await promiseSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) {
|
||||
expect(goodResult.data).toBeInstanceOf(Promise);
|
||||
const data = await goodResult.data;
|
||||
expect(data).toEqual(123);
|
||||
// expect(goodResult.data).resolves.toEqual(124);
|
||||
// return goodResult.data;
|
||||
} else {
|
||||
throw new Error("success should be true");
|
||||
}
|
||||
});
|
||||
|
||||
test("promise async parse bad", async () => {
|
||||
const badData = Promise.resolve("XXX");
|
||||
const badResult = await promiseSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(true);
|
||||
if (badResult.success) {
|
||||
await expect(badResult.data).rejects.toBeInstanceOf(z.ZodError);
|
||||
} else {
|
||||
throw new Error("success should be true");
|
||||
}
|
||||
});
|
||||
|
||||
test("async validation non-empty strings", async () => {
|
||||
const base = z.object({
|
||||
hello: z.string().refine((x) => x && x.length > 0),
|
||||
foo: z.string().refine((x) => x && x.length > 0),
|
||||
});
|
||||
|
||||
const testval = { hello: "", foo: "" };
|
||||
const result1 = base.safeParse(testval);
|
||||
const result2 = base.safeParseAsync(testval);
|
||||
|
||||
const r1 = result1;
|
||||
await result2.then((r2) => {
|
||||
if (r1.success === false && r2.success === false) expect(r1.error.issues.length).toBe(r2.error.issues.length); // <--- r1 has length 2, r2 has length 1
|
||||
});
|
||||
});
|
||||
|
||||
test("async validation multiple errors 1", async () => {
|
||||
const base = z.object({
|
||||
hello: z.string(),
|
||||
foo: z.number(),
|
||||
});
|
||||
|
||||
const testval = { hello: 3, foo: "hello" };
|
||||
const result1 = base.safeParse(testval);
|
||||
const result2 = base.safeParseAsync(testval);
|
||||
|
||||
const r1 = result1;
|
||||
await result2.then((r2) => {
|
||||
if (r1.success === false && r2.success === false) expect(r2.error.issues.length).toBe(r1.error.issues.length);
|
||||
});
|
||||
});
|
||||
|
||||
test("async validation multiple errors 2", async () => {
|
||||
const base = (is_async?: boolean) =>
|
||||
z.object({
|
||||
hello: z.string(),
|
||||
foo: z.object({
|
||||
bar: z.number().refine(is_async ? async () => false : () => false),
|
||||
}),
|
||||
});
|
||||
|
||||
const testval = { hello: 3, foo: { bar: 4 } };
|
||||
const result1 = base().safeParse(testval);
|
||||
const result2 = base(true).safeParseAsync(testval);
|
||||
|
||||
const r1 = result1;
|
||||
await result2.then((r2) => {
|
||||
if (r1.success === false && r2.success === false) expect(r2.error.issues.length).toBe(r1.error.issues.length);
|
||||
});
|
||||
});
|
||||
|
||||
test("ensure early async failure prevents follow-up refinement checks", async () => {
|
||||
let count = 0;
|
||||
const base = z.object({
|
||||
hello: z.string(),
|
||||
foo: z
|
||||
.number()
|
||||
.refine(async () => {
|
||||
count++;
|
||||
return true;
|
||||
})
|
||||
.refine(async () => {
|
||||
count++;
|
||||
return true;
|
||||
}, "Good"),
|
||||
});
|
||||
|
||||
const testval = { hello: "bye", foo: 3 };
|
||||
const result = await base.safeParseAsync(testval);
|
||||
if (result.success === false) {
|
||||
expect(result.error.issues.length).toBe(1);
|
||||
expect(count).toBe(1);
|
||||
}
|
||||
|
||||
// await result.then((r) => {
|
||||
// if (r.success === false) expect(r.error.issues.length).toBe(1);
|
||||
// expect(count).toBe(2);
|
||||
// });
|
||||
});
|
46
node_modules/zod/src/v3/tests/async-refinements.test.ts
generated
vendored
Normal file
46
node_modules/zod/src/v3/tests/async-refinements.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
test("parse async test", async () => {
|
||||
const schema1 = z.string().refine(async (_val) => false);
|
||||
expect(() => schema1.parse("asdf")).toThrow();
|
||||
|
||||
const schema2 = z.string().refine((_val) => Promise.resolve(true));
|
||||
return await expect(() => schema2.parse("asdf")).toThrow();
|
||||
});
|
||||
|
||||
test("parseAsync async test", async () => {
|
||||
const schema1 = z.string().refine(async (_val) => true);
|
||||
await schema1.parseAsync("asdf");
|
||||
|
||||
const schema2 = z.string().refine(async (_val) => false);
|
||||
return await expect(schema2.parseAsync("asdf")).rejects.toBeDefined();
|
||||
// expect(async () => await schema2.parseAsync('asdf')).toThrow();
|
||||
});
|
||||
|
||||
test("parseAsync async test", async () => {
|
||||
// expect.assertions(2);
|
||||
|
||||
const schema1 = z.string().refine((_val) => Promise.resolve(true));
|
||||
const v1 = await schema1.parseAsync("asdf");
|
||||
expect(v1).toEqual("asdf");
|
||||
|
||||
const schema2 = z.string().refine((_val) => Promise.resolve(false));
|
||||
await expect(schema2.parseAsync("asdf")).rejects.toBeDefined();
|
||||
|
||||
const schema3 = z.string().refine((_val) => Promise.resolve(true));
|
||||
await expect(schema3.parseAsync("asdf")).resolves.toEqual("asdf");
|
||||
return await expect(schema3.parseAsync("qwer")).resolves.toEqual("qwer");
|
||||
});
|
||||
|
||||
test("parseAsync async with value", async () => {
|
||||
const schema1 = z.string().refine(async (val) => {
|
||||
return val.length > 5;
|
||||
});
|
||||
await expect(schema1.parseAsync("asdf")).rejects.toBeDefined();
|
||||
|
||||
const v = await schema1.parseAsync("asdf123");
|
||||
return await expect(v).toEqual("asdf123");
|
||||
});
|
29
node_modules/zod/src/v3/tests/base.test.ts
generated
vendored
Normal file
29
node_modules/zod/src/v3/tests/base.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("type guard", () => {
|
||||
const stringToNumber = z.string().transform((arg) => arg.length);
|
||||
|
||||
const s1 = z.object({
|
||||
stringToNumber,
|
||||
});
|
||||
type t1 = z.input<typeof s1>;
|
||||
|
||||
const data = { stringToNumber: "asdf" };
|
||||
const parsed = s1.safeParse(data);
|
||||
if (parsed.success) {
|
||||
util.assertEqual<typeof data, t1>(true);
|
||||
}
|
||||
});
|
||||
|
||||
test("test this binding", () => {
|
||||
const callback = (predicate: (val: string) => boolean) => {
|
||||
return predicate("hello");
|
||||
};
|
||||
|
||||
expect(callback((value) => z.string().safeParse(value).success)).toBe(true); // true
|
||||
expect(callback((value) => z.string().safeParse(value).success)).toBe(true); // true
|
||||
});
|
55
node_modules/zod/src/v3/tests/bigint.test.ts
generated
vendored
Normal file
55
node_modules/zod/src/v3/tests/bigint.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
const gtFive = z.bigint().gt(BigInt(5));
|
||||
const gteFive = z.bigint().gte(BigInt(5));
|
||||
const ltFive = z.bigint().lt(BigInt(5));
|
||||
const lteFive = z.bigint().lte(BigInt(5));
|
||||
const positive = z.bigint().positive();
|
||||
const negative = z.bigint().negative();
|
||||
const nonnegative = z.bigint().nonnegative();
|
||||
const nonpositive = z.bigint().nonpositive();
|
||||
const multipleOfFive = z.bigint().multipleOf(BigInt(5));
|
||||
|
||||
test("passing validations", () => {
|
||||
z.bigint().parse(BigInt(1));
|
||||
z.bigint().parse(BigInt(0));
|
||||
z.bigint().parse(BigInt(-1));
|
||||
gtFive.parse(BigInt(6));
|
||||
gteFive.parse(BigInt(5));
|
||||
gteFive.parse(BigInt(6));
|
||||
ltFive.parse(BigInt(4));
|
||||
lteFive.parse(BigInt(5));
|
||||
lteFive.parse(BigInt(4));
|
||||
positive.parse(BigInt(3));
|
||||
negative.parse(BigInt(-2));
|
||||
nonnegative.parse(BigInt(0));
|
||||
nonnegative.parse(BigInt(7));
|
||||
nonpositive.parse(BigInt(0));
|
||||
nonpositive.parse(BigInt(-12));
|
||||
multipleOfFive.parse(BigInt(15));
|
||||
});
|
||||
|
||||
test("failing validations", () => {
|
||||
expect(() => gtFive.parse(BigInt(5))).toThrow();
|
||||
expect(() => gteFive.parse(BigInt(4))).toThrow();
|
||||
expect(() => ltFive.parse(BigInt(5))).toThrow();
|
||||
expect(() => lteFive.parse(BigInt(6))).toThrow();
|
||||
expect(() => positive.parse(BigInt(0))).toThrow();
|
||||
expect(() => positive.parse(BigInt(-2))).toThrow();
|
||||
expect(() => negative.parse(BigInt(0))).toThrow();
|
||||
expect(() => negative.parse(BigInt(3))).toThrow();
|
||||
expect(() => nonnegative.parse(BigInt(-1))).toThrow();
|
||||
expect(() => nonpositive.parse(BigInt(1))).toThrow();
|
||||
expect(() => multipleOfFive.parse(BigInt(13))).toThrow();
|
||||
});
|
||||
|
||||
test("min max getters", () => {
|
||||
expect(z.bigint().min(BigInt(5)).minValue).toEqual(BigInt(5));
|
||||
expect(z.bigint().min(BigInt(5)).min(BigInt(10)).minValue).toEqual(BigInt(10));
|
||||
|
||||
expect(z.bigint().max(BigInt(5)).maxValue).toEqual(BigInt(5));
|
||||
expect(z.bigint().max(BigInt(5)).max(BigInt(1)).maxValue).toEqual(BigInt(1));
|
||||
});
|
53
node_modules/zod/src/v3/tests/branded.test.ts
generated
vendored
Normal file
53
node_modules/zod/src/v3/tests/branded.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
// @ts-ignore TS6133
|
||||
import { test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("branded types", () => {
|
||||
const mySchema = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
})
|
||||
.brand<"superschema">();
|
||||
|
||||
// simple branding
|
||||
type MySchema = z.infer<typeof mySchema>;
|
||||
util.assertEqual<MySchema, { name: string } & { [z.BRAND]: { superschema: true } }>(true);
|
||||
|
||||
const doStuff = (arg: MySchema) => arg;
|
||||
doStuff(mySchema.parse({ name: "hello there" }));
|
||||
|
||||
// inheritance
|
||||
const extendedSchema = mySchema.brand<"subschema">();
|
||||
type ExtendedSchema = z.infer<typeof extendedSchema>;
|
||||
util.assertEqual<ExtendedSchema, { name: string } & z.BRAND<"superschema"> & z.BRAND<"subschema">>(true);
|
||||
|
||||
doStuff(extendedSchema.parse({ name: "hello again" }));
|
||||
|
||||
// number branding
|
||||
const numberSchema = z.number().brand<42>();
|
||||
type NumberSchema = z.infer<typeof numberSchema>;
|
||||
util.assertEqual<NumberSchema, number & { [z.BRAND]: { 42: true } }>(true);
|
||||
|
||||
// symbol branding
|
||||
const MyBrand: unique symbol = Symbol("hello");
|
||||
type MyBrand = typeof MyBrand;
|
||||
const symbolBrand = z.number().brand<"sup">().brand<typeof MyBrand>();
|
||||
type SymbolBrand = z.infer<typeof symbolBrand>;
|
||||
// number & { [z.BRAND]: { sup: true, [MyBrand]: true } }
|
||||
util.assertEqual<SymbolBrand, number & z.BRAND<"sup"> & z.BRAND<MyBrand>>(true);
|
||||
|
||||
// keeping brands out of input types
|
||||
const age = z.number().brand<"age">();
|
||||
|
||||
type Age = z.infer<typeof age>;
|
||||
type AgeInput = z.input<typeof age>;
|
||||
|
||||
util.assertEqual<AgeInput, Age>(false);
|
||||
util.assertEqual<number, AgeInput>(true);
|
||||
util.assertEqual<number & z.BRAND<"age">, Age>(true);
|
||||
|
||||
// @ts-expect-error
|
||||
doStuff({ name: "hello there!" });
|
||||
});
|
220
node_modules/zod/src/v3/tests/catch.test.ts
generated
vendored
Normal file
220
node_modules/zod/src/v3/tests/catch.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,220 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import { z } from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("basic catch", () => {
|
||||
expect(z.string().catch("default").parse(undefined)).toBe("default");
|
||||
});
|
||||
|
||||
test("catch fn does not run when parsing succeeds", () => {
|
||||
let isCalled = false;
|
||||
const cb = () => {
|
||||
isCalled = true;
|
||||
return "asdf";
|
||||
};
|
||||
expect(z.string().catch(cb).parse("test")).toBe("test");
|
||||
expect(isCalled).toEqual(false);
|
||||
});
|
||||
|
||||
test("basic catch async", async () => {
|
||||
const result = await z.string().catch("default").parseAsync(1243);
|
||||
expect(result).toBe("default");
|
||||
});
|
||||
|
||||
test("catch replace wrong types", () => {
|
||||
expect(z.string().catch("default").parse(true)).toBe("default");
|
||||
expect(z.string().catch("default").parse(true)).toBe("default");
|
||||
expect(z.string().catch("default").parse(15)).toBe("default");
|
||||
expect(z.string().catch("default").parse([])).toBe("default");
|
||||
expect(z.string().catch("default").parse(new Map())).toBe("default");
|
||||
expect(z.string().catch("default").parse(new Set())).toBe("default");
|
||||
expect(z.string().catch("default").parse({})).toBe("default");
|
||||
});
|
||||
|
||||
test("catch with transform", () => {
|
||||
const stringWithDefault = z
|
||||
.string()
|
||||
.transform((val) => val.toUpperCase())
|
||||
.catch("default");
|
||||
expect(stringWithDefault.parse(undefined)).toBe("default");
|
||||
expect(stringWithDefault.parse(15)).toBe("default");
|
||||
expect(stringWithDefault).toBeInstanceOf(z.ZodCatch);
|
||||
expect(stringWithDefault._def.innerType).toBeInstanceOf(z.ZodEffects);
|
||||
expect(stringWithDefault._def.innerType._def.schema).toBeInstanceOf(z.ZodSchema);
|
||||
|
||||
type inp = z.input<typeof stringWithDefault>;
|
||||
util.assertEqual<inp, unknown>(true);
|
||||
type out = z.output<typeof stringWithDefault>;
|
||||
util.assertEqual<out, string>(true);
|
||||
});
|
||||
|
||||
test("catch on existing optional", () => {
|
||||
const stringWithDefault = z.string().optional().catch("asdf");
|
||||
expect(stringWithDefault.parse(undefined)).toBe(undefined);
|
||||
expect(stringWithDefault.parse(15)).toBe("asdf");
|
||||
expect(stringWithDefault).toBeInstanceOf(z.ZodCatch);
|
||||
expect(stringWithDefault._def.innerType).toBeInstanceOf(z.ZodOptional);
|
||||
expect(stringWithDefault._def.innerType._def.innerType).toBeInstanceOf(z.ZodString);
|
||||
|
||||
type inp = z.input<typeof stringWithDefault>;
|
||||
util.assertEqual<inp, unknown>(true);
|
||||
type out = z.output<typeof stringWithDefault>;
|
||||
util.assertEqual<out, string | undefined>(true);
|
||||
});
|
||||
|
||||
test("optional on catch", () => {
|
||||
const stringWithDefault = z.string().catch("asdf").optional();
|
||||
|
||||
type inp = z.input<typeof stringWithDefault>;
|
||||
util.assertEqual<inp, unknown>(true);
|
||||
type out = z.output<typeof stringWithDefault>;
|
||||
util.assertEqual<out, string | undefined>(true);
|
||||
});
|
||||
|
||||
test("complex chain example", () => {
|
||||
const complex = z
|
||||
.string()
|
||||
.catch("asdf")
|
||||
.transform((val) => val + "!")
|
||||
.transform((val) => val.toUpperCase())
|
||||
.catch("qwer")
|
||||
.removeCatch()
|
||||
.optional()
|
||||
.catch("asdfasdf");
|
||||
|
||||
expect(complex.parse("qwer")).toBe("QWER!");
|
||||
expect(complex.parse(15)).toBe("ASDF!");
|
||||
expect(complex.parse(true)).toBe("ASDF!");
|
||||
});
|
||||
|
||||
test("removeCatch", () => {
|
||||
const stringWithRemovedDefault = z.string().catch("asdf").removeCatch();
|
||||
|
||||
type out = z.output<typeof stringWithRemovedDefault>;
|
||||
util.assertEqual<out, string>(true);
|
||||
});
|
||||
|
||||
test("nested", () => {
|
||||
const inner = z.string().catch("asdf");
|
||||
const outer = z.object({ inner }).catch({
|
||||
inner: "asdf",
|
||||
});
|
||||
type input = z.input<typeof outer>;
|
||||
util.assertEqual<input, unknown>(true);
|
||||
type out = z.output<typeof outer>;
|
||||
util.assertEqual<out, { inner: string }>(true);
|
||||
expect(outer.parse(undefined)).toEqual({ inner: "asdf" });
|
||||
expect(outer.parse({})).toEqual({ inner: "asdf" });
|
||||
expect(outer.parse({ inner: undefined })).toEqual({ inner: "asdf" });
|
||||
});
|
||||
|
||||
test("chained catch", () => {
|
||||
const stringWithDefault = z.string().catch("inner").catch("outer");
|
||||
const result = stringWithDefault.parse(undefined);
|
||||
expect(result).toEqual("inner");
|
||||
const resultDiff = stringWithDefault.parse(5);
|
||||
expect(resultDiff).toEqual("inner");
|
||||
});
|
||||
|
||||
test("factory", () => {
|
||||
z.ZodCatch.create(z.string(), {
|
||||
catch: "asdf",
|
||||
}).parse(undefined);
|
||||
});
|
||||
|
||||
test("native enum", () => {
|
||||
enum Fruits {
|
||||
apple = "apple",
|
||||
orange = "orange",
|
||||
}
|
||||
|
||||
const schema = z.object({
|
||||
fruit: z.nativeEnum(Fruits).catch(Fruits.apple),
|
||||
});
|
||||
|
||||
expect(schema.parse({})).toEqual({ fruit: Fruits.apple });
|
||||
expect(schema.parse({ fruit: 15 })).toEqual({ fruit: Fruits.apple });
|
||||
});
|
||||
|
||||
test("enum", () => {
|
||||
const schema = z.object({
|
||||
fruit: z.enum(["apple", "orange"]).catch("apple"),
|
||||
});
|
||||
|
||||
expect(schema.parse({})).toEqual({ fruit: "apple" });
|
||||
expect(schema.parse({ fruit: true })).toEqual({ fruit: "apple" });
|
||||
expect(schema.parse({ fruit: 15 })).toEqual({ fruit: "apple" });
|
||||
});
|
||||
|
||||
test("reported issues with nested usage", () => {
|
||||
const schema = z.object({
|
||||
string: z.string(),
|
||||
obj: z.object({
|
||||
sub: z.object({
|
||||
lit: z.literal("a"),
|
||||
subCatch: z.number().catch(23),
|
||||
}),
|
||||
midCatch: z.number().catch(42),
|
||||
}),
|
||||
number: z.number().catch(0),
|
||||
bool: z.boolean(),
|
||||
});
|
||||
|
||||
try {
|
||||
schema.parse({
|
||||
string: {},
|
||||
obj: {
|
||||
sub: {
|
||||
lit: "b",
|
||||
subCatch: "24",
|
||||
},
|
||||
midCatch: 444,
|
||||
},
|
||||
number: "",
|
||||
bool: "yes",
|
||||
});
|
||||
} catch (error) {
|
||||
const issues = (error as z.ZodError).issues;
|
||||
|
||||
expect(issues.length).toEqual(3);
|
||||
expect(issues[0].message).toMatch("string");
|
||||
expect(issues[1].message).toMatch("literal");
|
||||
expect(issues[2].message).toMatch("boolean");
|
||||
}
|
||||
});
|
||||
|
||||
test("catch error", () => {
|
||||
let catchError: z.ZodError | undefined = undefined;
|
||||
|
||||
const schema = z.object({
|
||||
age: z.number(),
|
||||
name: z.string().catch((ctx) => {
|
||||
catchError = ctx.error;
|
||||
|
||||
return "John Doe";
|
||||
}),
|
||||
});
|
||||
|
||||
const result = schema.safeParse({
|
||||
age: null,
|
||||
name: null,
|
||||
});
|
||||
|
||||
expect(result.success).toEqual(false);
|
||||
expect(!result.success && result.error.issues.length).toEqual(1);
|
||||
expect(!result.success && result.error.issues[0].message).toMatch("number");
|
||||
|
||||
expect(catchError).toBeInstanceOf(z.ZodError);
|
||||
expect(catchError !== undefined && (catchError as z.ZodError).issues.length).toEqual(1);
|
||||
expect(catchError !== undefined && (catchError as z.ZodError).issues[0].message).toMatch("string");
|
||||
});
|
||||
|
||||
test("ctx.input", () => {
|
||||
const schema = z.string().catch((ctx) => {
|
||||
return String(ctx.input);
|
||||
});
|
||||
|
||||
expect(schema.parse(123)).toEqual("123");
|
||||
});
|
133
node_modules/zod/src/v3/tests/coerce.test.ts
generated
vendored
Normal file
133
node_modules/zod/src/v3/tests/coerce.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
test("string coercion", () => {
|
||||
const schema = z.coerce.string();
|
||||
expect(schema.parse("sup")).toEqual("sup");
|
||||
expect(schema.parse("")).toEqual("");
|
||||
expect(schema.parse(12)).toEqual("12");
|
||||
expect(schema.parse(0)).toEqual("0");
|
||||
expect(schema.parse(-12)).toEqual("-12");
|
||||
expect(schema.parse(3.14)).toEqual("3.14");
|
||||
expect(schema.parse(BigInt(15))).toEqual("15");
|
||||
expect(schema.parse(Number.NaN)).toEqual("NaN");
|
||||
expect(schema.parse(Number.POSITIVE_INFINITY)).toEqual("Infinity");
|
||||
expect(schema.parse(Number.NEGATIVE_INFINITY)).toEqual("-Infinity");
|
||||
expect(schema.parse(true)).toEqual("true");
|
||||
expect(schema.parse(false)).toEqual("false");
|
||||
expect(schema.parse(null)).toEqual("null");
|
||||
expect(schema.parse(undefined)).toEqual("undefined");
|
||||
expect(schema.parse({ hello: "world!" })).toEqual("[object Object]");
|
||||
expect(schema.parse(["item", "another_item"])).toEqual("item,another_item");
|
||||
expect(schema.parse([])).toEqual("");
|
||||
expect(schema.parse(new Date("2022-01-01T00:00:00.000Z"))).toEqual(new Date("2022-01-01T00:00:00.000Z").toString());
|
||||
});
|
||||
|
||||
test("number coercion", () => {
|
||||
const schema = z.coerce.number();
|
||||
expect(schema.parse("12")).toEqual(12);
|
||||
expect(schema.parse("0")).toEqual(0);
|
||||
expect(schema.parse("-12")).toEqual(-12);
|
||||
expect(schema.parse("3.14")).toEqual(3.14);
|
||||
expect(schema.parse("")).toEqual(0);
|
||||
expect(() => schema.parse("NOT_A_NUMBER")).toThrow(); // z.ZodError
|
||||
expect(schema.parse(12)).toEqual(12);
|
||||
expect(schema.parse(0)).toEqual(0);
|
||||
expect(schema.parse(-12)).toEqual(-12);
|
||||
expect(schema.parse(3.14)).toEqual(3.14);
|
||||
expect(schema.parse(BigInt(15))).toEqual(15);
|
||||
expect(() => schema.parse(Number.NaN)).toThrow(); // z.ZodError
|
||||
expect(schema.parse(Number.POSITIVE_INFINITY)).toEqual(Number.POSITIVE_INFINITY);
|
||||
expect(schema.parse(Number.NEGATIVE_INFINITY)).toEqual(Number.NEGATIVE_INFINITY);
|
||||
expect(schema.parse(true)).toEqual(1);
|
||||
expect(schema.parse(false)).toEqual(0);
|
||||
expect(schema.parse(null)).toEqual(0);
|
||||
expect(() => schema.parse(undefined)).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse({ hello: "world!" })).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse(["item", "another_item"])).toThrow(); // z.ZodError
|
||||
expect(schema.parse([])).toEqual(0);
|
||||
expect(schema.parse(new Date(1670139203496))).toEqual(1670139203496);
|
||||
});
|
||||
|
||||
test("boolean coercion", () => {
|
||||
const schema = z.coerce.boolean();
|
||||
expect(schema.parse("true")).toEqual(true);
|
||||
expect(schema.parse("false")).toEqual(true);
|
||||
expect(schema.parse("0")).toEqual(true);
|
||||
expect(schema.parse("1")).toEqual(true);
|
||||
expect(schema.parse("")).toEqual(false);
|
||||
expect(schema.parse(1)).toEqual(true);
|
||||
expect(schema.parse(0)).toEqual(false);
|
||||
expect(schema.parse(-1)).toEqual(true);
|
||||
expect(schema.parse(3.14)).toEqual(true);
|
||||
expect(schema.parse(BigInt(15))).toEqual(true);
|
||||
expect(schema.parse(Number.NaN)).toEqual(false);
|
||||
expect(schema.parse(Number.POSITIVE_INFINITY)).toEqual(true);
|
||||
expect(schema.parse(Number.NEGATIVE_INFINITY)).toEqual(true);
|
||||
expect(schema.parse(true)).toEqual(true);
|
||||
expect(schema.parse(false)).toEqual(false);
|
||||
expect(schema.parse(null)).toEqual(false);
|
||||
expect(schema.parse(undefined)).toEqual(false);
|
||||
expect(schema.parse({ hello: "world!" })).toEqual(true);
|
||||
expect(schema.parse(["item", "another_item"])).toEqual(true);
|
||||
expect(schema.parse([])).toEqual(true);
|
||||
expect(schema.parse(new Date(1670139203496))).toEqual(true);
|
||||
});
|
||||
|
||||
test("bigint coercion", () => {
|
||||
const schema = z.coerce.bigint();
|
||||
expect(schema.parse("5")).toEqual(BigInt(5));
|
||||
expect(schema.parse("0")).toEqual(BigInt(0));
|
||||
expect(schema.parse("-5")).toEqual(BigInt(-5));
|
||||
expect(() => schema.parse("3.14")).toThrow(); // not a z.ZodError!
|
||||
expect(schema.parse("")).toEqual(BigInt(0));
|
||||
expect(() => schema.parse("NOT_A_NUMBER")).toThrow(); // not a z.ZodError!
|
||||
expect(schema.parse(5)).toEqual(BigInt(5));
|
||||
expect(schema.parse(0)).toEqual(BigInt(0));
|
||||
expect(schema.parse(-5)).toEqual(BigInt(-5));
|
||||
expect(() => schema.parse(3.14)).toThrow(); // not a z.ZodError!
|
||||
expect(schema.parse(BigInt(5))).toEqual(BigInt(5));
|
||||
expect(() => schema.parse(Number.NaN)).toThrow(); // not a z.ZodError!
|
||||
expect(() => schema.parse(Number.POSITIVE_INFINITY)).toThrow(); // not a z.ZodError!
|
||||
expect(() => schema.parse(Number.NEGATIVE_INFINITY)).toThrow(); // not a z.ZodError!
|
||||
expect(schema.parse(true)).toEqual(BigInt(1));
|
||||
expect(schema.parse(false)).toEqual(BigInt(0));
|
||||
expect(() => schema.parse(null)).toThrow(); // not a z.ZodError!
|
||||
expect(() => schema.parse(undefined)).toThrow(); // not a z.ZodError!
|
||||
expect(() => schema.parse({ hello: "world!" })).toThrow(); // not a z.ZodError!
|
||||
expect(() => schema.parse(["item", "another_item"])).toThrow(); // not a z.ZodError!
|
||||
expect(schema.parse([])).toEqual(BigInt(0));
|
||||
expect(schema.parse(new Date(1670139203496))).toEqual(BigInt(1670139203496));
|
||||
});
|
||||
|
||||
test("date coercion", () => {
|
||||
const schema = z.coerce.date();
|
||||
expect(schema.parse(new Date().toDateString())).toBeInstanceOf(Date);
|
||||
expect(schema.parse(new Date().toISOString())).toBeInstanceOf(Date);
|
||||
expect(schema.parse(new Date().toUTCString())).toBeInstanceOf(Date);
|
||||
expect(schema.parse("5")).toBeInstanceOf(Date);
|
||||
expect(schema.parse("2000-01-01")).toBeInstanceOf(Date);
|
||||
// expect(schema.parse("0")).toBeInstanceOf(Date);
|
||||
// expect(schema.parse("-5")).toBeInstanceOf(Date);
|
||||
// expect(schema.parse("3.14")).toBeInstanceOf(Date);
|
||||
expect(() => schema.parse("")).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse("NOT_A_DATE")).toThrow(); // z.ZodError
|
||||
expect(schema.parse(5)).toBeInstanceOf(Date);
|
||||
expect(schema.parse(0)).toBeInstanceOf(Date);
|
||||
expect(schema.parse(-5)).toBeInstanceOf(Date);
|
||||
expect(schema.parse(3.14)).toBeInstanceOf(Date);
|
||||
expect(() => schema.parse(BigInt(5))).toThrow(); // not a z.ZodError!
|
||||
expect(() => schema.parse(Number.NaN)).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse(Number.POSITIVE_INFINITY)).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse(Number.NEGATIVE_INFINITY)).toThrow(); // z.ZodError
|
||||
expect(schema.parse(true)).toBeInstanceOf(Date);
|
||||
expect(schema.parse(false)).toBeInstanceOf(Date);
|
||||
expect(schema.parse(null)).toBeInstanceOf(Date);
|
||||
expect(() => schema.parse(undefined)).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse({ hello: "world!" })).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse(["item", "another_item"])).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse([])).toThrow(); // z.ZodError
|
||||
expect(schema.parse(new Date())).toBeInstanceOf(Date);
|
||||
});
|
56
node_modules/zod/src/v3/tests/complex.test.ts
generated
vendored
Normal file
56
node_modules/zod/src/v3/tests/complex.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
import { test } from "vitest";
|
||||
import * as z from "zod/v3";
|
||||
|
||||
const crazySchema = z.object({
|
||||
tuple: z.tuple([
|
||||
z.string().nullable().optional(),
|
||||
z.number().nullable().optional(),
|
||||
z.boolean().nullable().optional(),
|
||||
z.null().nullable().optional(),
|
||||
z.undefined().nullable().optional(),
|
||||
z.literal("1234").nullable().optional(),
|
||||
]),
|
||||
merged: z
|
||||
.object({
|
||||
k1: z.string().optional(),
|
||||
})
|
||||
.merge(z.object({ k1: z.string().nullable(), k2: z.number() })),
|
||||
union: z.array(z.union([z.literal("asdf"), z.literal(12)])).nonempty(),
|
||||
array: z.array(z.number()),
|
||||
// sumTransformer: z.transformer(z.array(z.number()), z.number(), (arg) => {
|
||||
// return arg.reduce((a, b) => a + b, 0);
|
||||
// }),
|
||||
sumMinLength: z.array(z.number()).refine((arg) => arg.length > 5),
|
||||
intersection: z.intersection(z.object({ p1: z.string().optional() }), z.object({ p1: z.number().optional() })),
|
||||
enum: z.intersection(z.enum(["zero", "one"]), z.enum(["one", "two"])),
|
||||
nonstrict: z.object({ points: z.number() }).nonstrict(),
|
||||
numProm: z.promise(z.number()),
|
||||
lenfun: z.function(z.tuple([z.string()]), z.boolean()),
|
||||
});
|
||||
|
||||
// const asyncCrazySchema = crazySchema.extend({
|
||||
// // async_transform: z.transformer(
|
||||
// // z.array(z.number()),
|
||||
// // z.number(),
|
||||
// // async (arg) => {
|
||||
// // return arg.reduce((a, b) => a + b, 0);
|
||||
// // }
|
||||
// // ),
|
||||
// async_refine: z.array(z.number()).refine(async (arg) => arg.length > 5),
|
||||
// });
|
||||
|
||||
test("parse", () => {
|
||||
crazySchema.parse({
|
||||
tuple: ["asdf", 1234, true, null, undefined, "1234"],
|
||||
merged: { k1: "asdf", k2: 12 },
|
||||
union: ["asdf", 12, "asdf", 12, "asdf", 12],
|
||||
array: [12, 15, 16],
|
||||
// sumTransformer: [12, 15, 16],
|
||||
sumMinLength: [12, 15, 16, 98, 24, 63],
|
||||
intersection: {},
|
||||
enum: "one",
|
||||
nonstrict: { points: 1234 },
|
||||
numProm: Promise.resolve(12),
|
||||
lenfun: (x: string) => x.length,
|
||||
});
|
||||
});
|
31
node_modules/zod/src/v3/tests/custom.test.ts
generated
vendored
Normal file
31
node_modules/zod/src/v3/tests/custom.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
test("passing validations", () => {
|
||||
const example1 = z.custom<number>((x) => typeof x === "number");
|
||||
example1.parse(1234);
|
||||
expect(() => example1.parse({})).toThrow();
|
||||
});
|
||||
|
||||
test("string params", () => {
|
||||
const example1 = z.custom<number>((x) => typeof x !== "number", "customerr");
|
||||
const result = example1.safeParse(1234);
|
||||
expect(result.success).toEqual(false);
|
||||
// @ts-ignore
|
||||
expect(JSON.stringify(result.error).includes("customerr")).toEqual(true);
|
||||
});
|
||||
|
||||
test("async validations", async () => {
|
||||
const example1 = z.custom<number>(async (x) => {
|
||||
return typeof x === "number";
|
||||
});
|
||||
const r1 = await example1.safeParseAsync(1234);
|
||||
expect(r1.success).toEqual(true);
|
||||
expect(r1.data).toEqual(1234);
|
||||
|
||||
const r2 = await example1.safeParseAsync("asdf");
|
||||
expect(r2.success).toEqual(false);
|
||||
expect(r2.error!.issues.length).toEqual(1);
|
||||
});
|
32
node_modules/zod/src/v3/tests/date.test.ts
generated
vendored
Normal file
32
node_modules/zod/src/v3/tests/date.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
const beforeBenchmarkDate = new Date(2022, 10, 4);
|
||||
const benchmarkDate = new Date(2022, 10, 5);
|
||||
const afterBenchmarkDate = new Date(2022, 10, 6);
|
||||
|
||||
const minCheck = z.date().min(benchmarkDate);
|
||||
const maxCheck = z.date().max(benchmarkDate);
|
||||
|
||||
test("passing validations", () => {
|
||||
minCheck.parse(benchmarkDate);
|
||||
minCheck.parse(afterBenchmarkDate);
|
||||
|
||||
maxCheck.parse(benchmarkDate);
|
||||
maxCheck.parse(beforeBenchmarkDate);
|
||||
});
|
||||
|
||||
test("failing validations", () => {
|
||||
expect(() => minCheck.parse(beforeBenchmarkDate)).toThrow();
|
||||
expect(() => maxCheck.parse(afterBenchmarkDate)).toThrow();
|
||||
});
|
||||
|
||||
test("min max getters", () => {
|
||||
expect(minCheck.minDate).toEqual(benchmarkDate);
|
||||
expect(minCheck.min(afterBenchmarkDate).minDate).toEqual(afterBenchmarkDate);
|
||||
|
||||
expect(maxCheck.maxDate).toEqual(benchmarkDate);
|
||||
expect(maxCheck.max(beforeBenchmarkDate).maxDate).toEqual(beforeBenchmarkDate);
|
||||
});
|
186
node_modules/zod/src/v3/tests/deepmasking.test.ts
generated
vendored
Normal file
186
node_modules/zod/src/v3/tests/deepmasking.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
// @ts-ignore TS6133
|
||||
import { test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
test("test", () => {
|
||||
z;
|
||||
});
|
||||
|
||||
// const fish = z.object({
|
||||
// name: z.string(),
|
||||
// props: z.object({
|
||||
// color: z.string(),
|
||||
// numScales: z.number(),
|
||||
// }),
|
||||
// });
|
||||
|
||||
// const nonStrict = z
|
||||
// .object({
|
||||
// name: z.string(),
|
||||
// color: z.string(),
|
||||
// })
|
||||
// .nonstrict();
|
||||
|
||||
// test('object pick type', () => {
|
||||
// const modNonStrictFish = nonStrict.omit({ name: true });
|
||||
// modNonStrictFish.parse({ color: 'asdf' });
|
||||
|
||||
// const bad1 = () => fish.pick({ props: { unknown: true } } as any);
|
||||
// const bad2 = () => fish.omit({ name: true, props: { unknown: true } } as any);
|
||||
|
||||
// expect(bad1).toThrow();
|
||||
// expect(bad2).toThrow();
|
||||
// });
|
||||
|
||||
// test('f1', () => {
|
||||
// const f1 = fish.pick(true);
|
||||
// f1.parse({ name: 'a', props: { color: 'b', numScales: 3 } });
|
||||
// });
|
||||
// test('f2', () => {
|
||||
// const f2 = fish.pick({ props: true });
|
||||
// f2.parse({ props: { color: 'asdf', numScales: 1 } });
|
||||
// const badcheck2 = () => f2.parse({ name: 'a', props: { color: 'b', numScales: 3 } } as any);
|
||||
// expect(badcheck2).toThrow();
|
||||
// });
|
||||
// test('f3', () => {
|
||||
// const f3 = fish.pick({ props: { color: true } });
|
||||
// f3.parse({ props: { color: 'b' } });
|
||||
// const badcheck3 = () => f3.parse({ name: 'a', props: { color: 'b', numScales: 3 } } as any);
|
||||
// expect(badcheck3).toThrow();
|
||||
// });
|
||||
// test('f4', () => {
|
||||
// const badcheck4 = () => fish.pick({ props: { color: true, unknown: true } });
|
||||
// expect(badcheck4).toThrow();
|
||||
// });
|
||||
// test('f6', () => {
|
||||
// const f6 = fish.omit({ props: true });
|
||||
// const badcheck6 = () => f6.parse({ name: 'a', props: { color: 'b', numScales: 3 } } as any);
|
||||
// f6.parse({ name: 'adsf' });
|
||||
// expect(badcheck6).toThrow();
|
||||
// });
|
||||
// test('f7', () => {
|
||||
// const f7 = fish.omit({ props: { color: true } });
|
||||
// f7.parse({ name: 'a', props: { numScales: 3 } });
|
||||
// const badcheck7 = () => f7.parse({ name: 'a', props: { color: 'b', numScales: 3 } } as any);
|
||||
// expect(badcheck7).toThrow();
|
||||
// });
|
||||
// test('f8', () => {
|
||||
// const badcheck8 = () => fish.omit({ props: { color: true, unknown: true } });
|
||||
// expect(badcheck8).toThrow();
|
||||
// });
|
||||
// test('f9', () => {
|
||||
// const f9 = nonStrict.pick(true);
|
||||
// f9.parse({ name: 'a', color: 'asdf' });
|
||||
// });
|
||||
// test('f10', () => {
|
||||
// const f10 = nonStrict.pick({ name: true });
|
||||
// f10.parse({ name: 'a' });
|
||||
// const val = f10.parse({ name: 'a', color: 'b' });
|
||||
// expect(val).toEqual({ name: 'a' });
|
||||
// });
|
||||
// test('f12', () => {
|
||||
// const badfcheck12 = () => nonStrict.omit({ color: true, asdf: true });
|
||||
// expect(badfcheck12).toThrow();
|
||||
// });
|
||||
|
||||
// test('array masking', () => {
|
||||
// const fishArray = z.array(fish);
|
||||
// const modFishArray = fishArray.pick({
|
||||
// name: true,
|
||||
// props: {
|
||||
// numScales: true,
|
||||
// },
|
||||
// });
|
||||
|
||||
// modFishArray.parse([{ name: 'fish', props: { numScales: 12 } }]);
|
||||
// const bad1 = () => modFishArray.parse([{ name: 'fish', props: { numScales: 12, color: 'asdf' } }] as any);
|
||||
// expect(bad1).toThrow();
|
||||
// });
|
||||
|
||||
// test('array masking', () => {
|
||||
// const fishArray = z.array(fish);
|
||||
// const fail = () =>
|
||||
// fishArray.pick({
|
||||
// name: true,
|
||||
// props: {
|
||||
// whatever: true,
|
||||
// },
|
||||
// } as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
||||
|
||||
// test('array masking', () => {
|
||||
// const fishArray = z.array(fish);
|
||||
// const fail = () =>
|
||||
// fishArray.omit({
|
||||
// whateve: true,
|
||||
// } as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
||||
|
||||
// test('array masking', () => {
|
||||
// const fishArray = z.array(fish);
|
||||
// const modFishList = fishArray.omit({
|
||||
// name: true,
|
||||
// props: {
|
||||
// color: true,
|
||||
// },
|
||||
// });
|
||||
|
||||
// modFishList.parse([{ props: { numScales: 12 } }]);
|
||||
// const fail = () => modFishList.parse([{ name: 'hello', props: { numScales: 12 } }] as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
||||
|
||||
// test('primitive array masking', () => {
|
||||
// const fishArray = z.array(z.number());
|
||||
// const fail = () => fishArray.pick({} as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
||||
|
||||
// test('other array masking', () => {
|
||||
// const fishArray = z.array(z.array(z.number()));
|
||||
// const fail = () => fishArray.pick({} as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
||||
|
||||
// test('invalid mask #1', () => {
|
||||
// const fail = () => fish.pick(1 as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
||||
|
||||
// test('invalid mask #2', () => {
|
||||
// const fail = () => fish.pick([] as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
||||
|
||||
// test('invalid mask #3', () => {
|
||||
// const fail = () => fish.pick(false as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
||||
|
||||
// test('invalid mask #4', () => {
|
||||
// const fail = () => fish.pick('asdf' as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
||||
|
||||
// test('invalid mask #5', () => {
|
||||
// const fail = () => fish.omit(1 as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
||||
|
||||
// test('invalid mask #6', () => {
|
||||
// const fail = () => fish.omit([] as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
||||
|
||||
// test('invalid mask #7', () => {
|
||||
// const fail = () => fish.omit(false as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
||||
|
||||
// test('invalid mask #8', () => {
|
||||
// const fail = () => fish.omit('asdf' as any);
|
||||
// expect(fail).toThrow();
|
||||
// });
|
112
node_modules/zod/src/v3/tests/default.test.ts
generated
vendored
Normal file
112
node_modules/zod/src/v3/tests/default.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import { z } from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("basic defaults", () => {
|
||||
expect(z.string().default("default").parse(undefined)).toBe("default");
|
||||
});
|
||||
|
||||
test("default with transform", () => {
|
||||
const stringWithDefault = z
|
||||
.string()
|
||||
.transform((val) => val.toUpperCase())
|
||||
.default("default");
|
||||
expect(stringWithDefault.parse(undefined)).toBe("DEFAULT");
|
||||
expect(stringWithDefault).toBeInstanceOf(z.ZodDefault);
|
||||
expect(stringWithDefault._def.innerType).toBeInstanceOf(z.ZodEffects);
|
||||
expect(stringWithDefault._def.innerType._def.schema).toBeInstanceOf(z.ZodSchema);
|
||||
|
||||
type inp = z.input<typeof stringWithDefault>;
|
||||
util.assertEqual<inp, string | undefined>(true);
|
||||
type out = z.output<typeof stringWithDefault>;
|
||||
util.assertEqual<out, string>(true);
|
||||
});
|
||||
|
||||
test("default on existing optional", () => {
|
||||
const stringWithDefault = z.string().optional().default("asdf");
|
||||
expect(stringWithDefault.parse(undefined)).toBe("asdf");
|
||||
expect(stringWithDefault).toBeInstanceOf(z.ZodDefault);
|
||||
expect(stringWithDefault._def.innerType).toBeInstanceOf(z.ZodOptional);
|
||||
expect(stringWithDefault._def.innerType._def.innerType).toBeInstanceOf(z.ZodString);
|
||||
|
||||
type inp = z.input<typeof stringWithDefault>;
|
||||
util.assertEqual<inp, string | undefined>(true);
|
||||
type out = z.output<typeof stringWithDefault>;
|
||||
util.assertEqual<out, string>(true);
|
||||
});
|
||||
|
||||
test("optional on default", () => {
|
||||
const stringWithDefault = z.string().default("asdf").optional();
|
||||
|
||||
type inp = z.input<typeof stringWithDefault>;
|
||||
util.assertEqual<inp, string | undefined>(true);
|
||||
type out = z.output<typeof stringWithDefault>;
|
||||
util.assertEqual<out, string | undefined>(true);
|
||||
});
|
||||
|
||||
test("complex chain example", () => {
|
||||
const complex = z
|
||||
.string()
|
||||
.default("asdf")
|
||||
.transform((val) => val.toUpperCase())
|
||||
.default("qwer")
|
||||
.removeDefault()
|
||||
.optional()
|
||||
.default("asdfasdf");
|
||||
|
||||
expect(complex.parse(undefined)).toBe("ASDFASDF");
|
||||
});
|
||||
|
||||
test("removeDefault", () => {
|
||||
const stringWithRemovedDefault = z.string().default("asdf").removeDefault();
|
||||
|
||||
type out = z.output<typeof stringWithRemovedDefault>;
|
||||
util.assertEqual<out, string>(true);
|
||||
});
|
||||
|
||||
test("nested", () => {
|
||||
const inner = z.string().default("asdf");
|
||||
const outer = z.object({ inner }).default({
|
||||
inner: undefined,
|
||||
});
|
||||
type input = z.input<typeof outer>;
|
||||
util.assertEqual<input, { inner?: string | undefined } | undefined>(true);
|
||||
type out = z.output<typeof outer>;
|
||||
util.assertEqual<out, { inner: string }>(true);
|
||||
expect(outer.parse(undefined)).toEqual({ inner: "asdf" });
|
||||
expect(outer.parse({})).toEqual({ inner: "asdf" });
|
||||
expect(outer.parse({ inner: undefined })).toEqual({ inner: "asdf" });
|
||||
});
|
||||
|
||||
test("chained defaults", () => {
|
||||
const stringWithDefault = z.string().default("inner").default("outer");
|
||||
const result = stringWithDefault.parse(undefined);
|
||||
expect(result).toEqual("outer");
|
||||
});
|
||||
|
||||
test("factory", () => {
|
||||
expect(z.ZodDefault.create(z.string(), { default: "asdf" }).parse(undefined)).toEqual("asdf");
|
||||
});
|
||||
|
||||
test("native enum", () => {
|
||||
enum Fruits {
|
||||
apple = "apple",
|
||||
orange = "orange",
|
||||
}
|
||||
|
||||
const schema = z.object({
|
||||
fruit: z.nativeEnum(Fruits).default(Fruits.apple),
|
||||
});
|
||||
|
||||
expect(schema.parse({})).toEqual({ fruit: Fruits.apple });
|
||||
});
|
||||
|
||||
test("enum", () => {
|
||||
const schema = z.object({
|
||||
fruit: z.enum(["apple", "orange"]).default("apple"),
|
||||
});
|
||||
|
||||
expect(schema.parse({})).toEqual({ fruit: "apple" });
|
||||
});
|
33
node_modules/zod/src/v3/tests/description.test.ts
generated
vendored
Normal file
33
node_modules/zod/src/v3/tests/description.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
const description = "a description";
|
||||
|
||||
test("passing `description` to schema should add a description", () => {
|
||||
expect(z.string({ description }).description).toEqual(description);
|
||||
expect(z.number({ description }).description).toEqual(description);
|
||||
expect(z.boolean({ description }).description).toEqual(description);
|
||||
});
|
||||
|
||||
test("`.describe` should add a description", () => {
|
||||
expect(z.string().describe(description).description).toEqual(description);
|
||||
expect(z.number().describe(description).description).toEqual(description);
|
||||
expect(z.boolean().describe(description).description).toEqual(description);
|
||||
});
|
||||
|
||||
test("description should carry over to chained schemas", () => {
|
||||
const schema = z.string({ description });
|
||||
expect(schema.description).toEqual(description);
|
||||
expect(schema.optional().description).toEqual(description);
|
||||
expect(schema.optional().nullable().default("default").description).toEqual(description);
|
||||
});
|
||||
|
||||
test("description should not carry over to chained array schema", () => {
|
||||
const schema = z.string().describe(description);
|
||||
|
||||
expect(schema.description).toEqual(description);
|
||||
expect(schema.array().description).toEqual(undefined);
|
||||
expect(z.array(schema).description).toEqual(undefined);
|
||||
});
|
315
node_modules/zod/src/v3/tests/discriminated-unions.test.ts
generated
vendored
Normal file
315
node_modules/zod/src/v3/tests/discriminated-unions.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,315 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
test("valid", () => {
|
||||
expect(
|
||||
z
|
||||
.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a"), a: z.string() }),
|
||||
z.object({ type: z.literal("b"), b: z.string() }),
|
||||
])
|
||||
.parse({ type: "a", a: "abc" })
|
||||
).toEqual({ type: "a", a: "abc" });
|
||||
});
|
||||
|
||||
test("valid - discriminator value of various primitive types", () => {
|
||||
const schema = z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("1"), val: z.literal(1) }),
|
||||
z.object({ type: z.literal(1), val: z.literal(2) }),
|
||||
z.object({ type: z.literal(BigInt(1)), val: z.literal(3) }),
|
||||
z.object({ type: z.literal("true"), val: z.literal(4) }),
|
||||
z.object({ type: z.literal(true), val: z.literal(5) }),
|
||||
z.object({ type: z.literal("null"), val: z.literal(6) }),
|
||||
z.object({ type: z.literal(null), val: z.literal(7) }),
|
||||
z.object({ type: z.literal("undefined"), val: z.literal(8) }),
|
||||
z.object({ type: z.literal(undefined), val: z.literal(9) }),
|
||||
z.object({ type: z.literal("transform"), val: z.literal(10) }),
|
||||
z.object({ type: z.literal("refine"), val: z.literal(11) }),
|
||||
z.object({ type: z.literal("superRefine"), val: z.literal(12) }),
|
||||
]);
|
||||
|
||||
expect(schema.parse({ type: "1", val: 1 })).toEqual({ type: "1", val: 1 });
|
||||
expect(schema.parse({ type: 1, val: 2 })).toEqual({ type: 1, val: 2 });
|
||||
expect(schema.parse({ type: BigInt(1), val: 3 })).toEqual({
|
||||
type: BigInt(1),
|
||||
val: 3,
|
||||
});
|
||||
expect(schema.parse({ type: "true", val: 4 })).toEqual({
|
||||
type: "true",
|
||||
val: 4,
|
||||
});
|
||||
expect(schema.parse({ type: true, val: 5 })).toEqual({
|
||||
type: true,
|
||||
val: 5,
|
||||
});
|
||||
expect(schema.parse({ type: "null", val: 6 })).toEqual({
|
||||
type: "null",
|
||||
val: 6,
|
||||
});
|
||||
expect(schema.parse({ type: null, val: 7 })).toEqual({
|
||||
type: null,
|
||||
val: 7,
|
||||
});
|
||||
expect(schema.parse({ type: "undefined", val: 8 })).toEqual({
|
||||
type: "undefined",
|
||||
val: 8,
|
||||
});
|
||||
expect(schema.parse({ type: undefined, val: 9 })).toEqual({
|
||||
type: undefined,
|
||||
val: 9,
|
||||
});
|
||||
});
|
||||
|
||||
test("invalid - null", () => {
|
||||
try {
|
||||
z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a"), a: z.string() }),
|
||||
z.object({ type: z.literal("b"), b: z.string() }),
|
||||
]).parse(null);
|
||||
throw new Error();
|
||||
} catch (e: any) {
|
||||
expect(JSON.parse(e.message)).toEqual([
|
||||
{
|
||||
code: z.ZodIssueCode.invalid_type,
|
||||
expected: z.ZodParsedType.object,
|
||||
message: "Expected object, received null",
|
||||
received: z.ZodParsedType.null,
|
||||
path: [],
|
||||
},
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
test("invalid discriminator value", () => {
|
||||
try {
|
||||
z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a"), a: z.string() }),
|
||||
z.object({ type: z.literal("b"), b: z.string() }),
|
||||
]).parse({ type: "x", a: "abc" });
|
||||
throw new Error();
|
||||
} catch (e: any) {
|
||||
expect(JSON.parse(e.message)).toEqual([
|
||||
{
|
||||
code: z.ZodIssueCode.invalid_union_discriminator,
|
||||
options: ["a", "b"],
|
||||
message: "Invalid discriminator value. Expected 'a' | 'b'",
|
||||
path: ["type"],
|
||||
},
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
test("valid discriminator value, invalid data", () => {
|
||||
try {
|
||||
z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a"), a: z.string() }),
|
||||
z.object({ type: z.literal("b"), b: z.string() }),
|
||||
]).parse({ type: "a", b: "abc" });
|
||||
throw new Error();
|
||||
} catch (e: any) {
|
||||
expect(JSON.parse(e.message)).toEqual([
|
||||
{
|
||||
code: z.ZodIssueCode.invalid_type,
|
||||
expected: z.ZodParsedType.string,
|
||||
message: "Required",
|
||||
path: ["a"],
|
||||
received: z.ZodParsedType.undefined,
|
||||
},
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
test("wrong schema - missing discriminator", () => {
|
||||
try {
|
||||
z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a"), a: z.string() }),
|
||||
z.object({ b: z.string() }) as any,
|
||||
]);
|
||||
throw new Error();
|
||||
} catch (e: any) {
|
||||
expect(e.message.includes("could not be extracted")).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
test("wrong schema - duplicate discriminator values", () => {
|
||||
try {
|
||||
z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a"), a: z.string() }),
|
||||
z.object({ type: z.literal("a"), b: z.string() }),
|
||||
]);
|
||||
throw new Error();
|
||||
} catch (e: any) {
|
||||
expect(e.message.includes("has duplicate value")).toEqual(true);
|
||||
}
|
||||
});
|
||||
|
||||
test("async - valid", async () => {
|
||||
expect(
|
||||
await z
|
||||
.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal("a"),
|
||||
a: z
|
||||
.string()
|
||||
.refine(async () => true)
|
||||
.transform(async (val) => Number(val)),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal("b"),
|
||||
b: z.string(),
|
||||
}),
|
||||
])
|
||||
.parseAsync({ type: "a", a: "1" })
|
||||
).toEqual({ type: "a", a: 1 });
|
||||
});
|
||||
|
||||
test("async - invalid", async () => {
|
||||
try {
|
||||
await z
|
||||
.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal("a"),
|
||||
a: z
|
||||
.string()
|
||||
.refine(async () => true)
|
||||
.transform(async (val) => val),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal("b"),
|
||||
b: z.string(),
|
||||
}),
|
||||
])
|
||||
.parseAsync({ type: "a", a: 1 });
|
||||
throw new Error();
|
||||
} catch (e: any) {
|
||||
expect(JSON.parse(e.message)).toEqual([
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "string",
|
||||
received: "number",
|
||||
path: ["a"],
|
||||
message: "Expected string, received number",
|
||||
},
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
test("valid - literals with .default or .preprocess", () => {
|
||||
const schema = z.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal("foo").default("foo"),
|
||||
a: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal("custom"),
|
||||
method: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
type: z.preprocess((val) => String(val), z.literal("bar")),
|
||||
c: z.string(),
|
||||
}),
|
||||
]);
|
||||
expect(schema.parse({ type: "foo", a: "foo" })).toEqual({
|
||||
type: "foo",
|
||||
a: "foo",
|
||||
});
|
||||
});
|
||||
|
||||
test("enum and nativeEnum", () => {
|
||||
enum MyEnum {
|
||||
d = 0,
|
||||
e = "e",
|
||||
}
|
||||
|
||||
const schema = z.discriminatedUnion("key", [
|
||||
z.object({
|
||||
key: z.literal("a"),
|
||||
// Add other properties specific to this option
|
||||
}),
|
||||
z.object({
|
||||
key: z.enum(["b", "c"]),
|
||||
// Add other properties specific to this option
|
||||
}),
|
||||
z.object({
|
||||
key: z.nativeEnum(MyEnum),
|
||||
// Add other properties specific to this option
|
||||
}),
|
||||
]);
|
||||
|
||||
// type schema = z.infer<typeof schema>;
|
||||
|
||||
schema.parse({ key: "a" });
|
||||
schema.parse({ key: "b" });
|
||||
schema.parse({ key: "c" });
|
||||
schema.parse({ key: MyEnum.d });
|
||||
schema.parse({ key: MyEnum.e });
|
||||
schema.parse({ key: "e" });
|
||||
});
|
||||
|
||||
test("branded", () => {
|
||||
const schema = z.discriminatedUnion("key", [
|
||||
z.object({
|
||||
key: z.literal("a"),
|
||||
// Add other properties specific to this option
|
||||
}),
|
||||
z.object({
|
||||
key: z.literal("b").brand("asdfaf"),
|
||||
// Add other properties specific to this option
|
||||
}),
|
||||
]);
|
||||
|
||||
// type schema = z.infer<typeof schema>;
|
||||
|
||||
schema.parse({ key: "a" });
|
||||
schema.parse({ key: "b" });
|
||||
expect(() => {
|
||||
schema.parse({ key: "c" });
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
test("optional and nullable", () => {
|
||||
const schema = z.discriminatedUnion("key", [
|
||||
z.object({
|
||||
key: z.literal("a").optional(),
|
||||
a: z.literal(true),
|
||||
}),
|
||||
z.object({
|
||||
key: z.literal("b").nullable(),
|
||||
b: z.literal(true),
|
||||
// Add other properties specific to this option
|
||||
}),
|
||||
]);
|
||||
|
||||
type schema = z.infer<typeof schema>;
|
||||
z.util.assertEqual<schema, { key?: "a" | undefined; a: true } | { key: "b" | null; b: true }>(true);
|
||||
|
||||
schema.parse({ key: "a", a: true });
|
||||
schema.parse({ key: undefined, a: true });
|
||||
schema.parse({ key: "b", b: true });
|
||||
schema.parse({ key: null, b: true });
|
||||
expect(() => {
|
||||
schema.parse({ key: null, a: true });
|
||||
}).toThrow();
|
||||
expect(() => {
|
||||
schema.parse({ key: "b", a: true });
|
||||
}).toThrow();
|
||||
|
||||
const value = schema.parse({ key: null, b: true });
|
||||
|
||||
if (!("key" in value)) value.a;
|
||||
if (value.key === undefined) value.a;
|
||||
if (value.key === "a") value.a;
|
||||
if (value.key === "b") value.b;
|
||||
if (value.key === null) value.b;
|
||||
});
|
||||
|
||||
test("readonly array of options", () => {
|
||||
const options = [
|
||||
z.object({ type: z.literal("x"), val: z.literal(1) }),
|
||||
z.object({ type: z.literal("y"), val: z.literal(2) }),
|
||||
] as const;
|
||||
|
||||
expect(z.discriminatedUnion("type", options).parse({ type: "x", val: 1 })).toEqual({ type: "x", val: 1 });
|
||||
});
|
80
node_modules/zod/src/v3/tests/enum.test.ts
generated
vendored
Normal file
80
node_modules/zod/src/v3/tests/enum.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("create enum", () => {
|
||||
const MyEnum = z.enum(["Red", "Green", "Blue"]);
|
||||
expect(MyEnum.Values.Red).toEqual("Red");
|
||||
expect(MyEnum.Enum.Red).toEqual("Red");
|
||||
expect(MyEnum.enum.Red).toEqual("Red");
|
||||
});
|
||||
|
||||
test("infer enum", () => {
|
||||
const MyEnum = z.enum(["Red", "Green", "Blue"]);
|
||||
type MyEnum = z.infer<typeof MyEnum>;
|
||||
util.assertEqual<MyEnum, "Red" | "Green" | "Blue">(true);
|
||||
});
|
||||
|
||||
test("get options", () => {
|
||||
expect(z.enum(["tuna", "trout"]).options).toEqual(["tuna", "trout"]);
|
||||
});
|
||||
|
||||
test("readonly enum", () => {
|
||||
const HTTP_SUCCESS = ["200", "201"] as const;
|
||||
const arg = z.enum(HTTP_SUCCESS);
|
||||
type arg = z.infer<typeof arg>;
|
||||
util.assertEqual<arg, "200" | "201">(true);
|
||||
|
||||
arg.parse("201");
|
||||
expect(() => arg.parse("202")).toThrow();
|
||||
});
|
||||
|
||||
test("error params", () => {
|
||||
const result = z.enum(["test"], { required_error: "REQUIRED" }).safeParse(undefined);
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues[0].message).toEqual("REQUIRED");
|
||||
}
|
||||
});
|
||||
|
||||
test("extract/exclude", () => {
|
||||
const foods = ["Pasta", "Pizza", "Tacos", "Burgers", "Salad"] as const;
|
||||
const FoodEnum = z.enum(foods);
|
||||
const ItalianEnum = FoodEnum.extract(["Pasta", "Pizza"]);
|
||||
const UnhealthyEnum = FoodEnum.exclude(["Salad"]);
|
||||
const EmptyFoodEnum = FoodEnum.exclude(foods);
|
||||
|
||||
util.assertEqual<z.infer<typeof ItalianEnum>, "Pasta" | "Pizza">(true);
|
||||
util.assertEqual<z.infer<typeof UnhealthyEnum>, "Pasta" | "Pizza" | "Tacos" | "Burgers">(true);
|
||||
// @ts-expect-error TS2344
|
||||
util.assertEqual<typeof EmptyFoodEnum, z.ZodEnum<[]>>(true);
|
||||
util.assertEqual<z.infer<typeof EmptyFoodEnum>, never>(true);
|
||||
});
|
||||
|
||||
test("error map in extract/exclude", () => {
|
||||
const foods = ["Pasta", "Pizza", "Tacos", "Burgers", "Salad"] as const;
|
||||
const FoodEnum = z.enum(foods, {
|
||||
errorMap: () => ({ message: "This is not food!" }),
|
||||
});
|
||||
const ItalianEnum = FoodEnum.extract(["Pasta", "Pizza"]);
|
||||
const foodsError = FoodEnum.safeParse("Cucumbers");
|
||||
const italianError = ItalianEnum.safeParse("Tacos");
|
||||
if (!foodsError.success && !italianError.success) {
|
||||
expect(foodsError.error.issues[0].message).toEqual(italianError.error.issues[0].message);
|
||||
}
|
||||
|
||||
const UnhealthyEnum = FoodEnum.exclude(["Salad"], {
|
||||
errorMap: () => ({ message: "This is not healthy food!" }),
|
||||
});
|
||||
const unhealthyError = UnhealthyEnum.safeParse("Salad");
|
||||
if (!unhealthyError.success) {
|
||||
expect(unhealthyError.error.issues[0].message).toEqual("This is not healthy food!");
|
||||
}
|
||||
});
|
||||
|
||||
test("readonly in ZodEnumDef", () => {
|
||||
let _t!: z.ZodEnumDef<readonly ["a", "b"]>;
|
||||
_t;
|
||||
});
|
551
node_modules/zod/src/v3/tests/error.test.ts
generated
vendored
Normal file
551
node_modules/zod/src/v3/tests/error.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,551 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { ZodError, ZodIssueCode } from "../ZodError.js";
|
||||
import { ZodParsedType } from "../helpers/util.js";
|
||||
|
||||
test("error creation", () => {
|
||||
const err1 = ZodError.create([]);
|
||||
err1.addIssue({
|
||||
code: ZodIssueCode.invalid_type,
|
||||
expected: ZodParsedType.object,
|
||||
received: ZodParsedType.string,
|
||||
path: [],
|
||||
message: "",
|
||||
fatal: true,
|
||||
});
|
||||
err1.isEmpty;
|
||||
|
||||
const err2 = ZodError.create(err1.issues);
|
||||
const err3 = new ZodError([]);
|
||||
err3.addIssues(err1.issues);
|
||||
err3.addIssue(err1.issues[0]);
|
||||
err1.message;
|
||||
err2.message;
|
||||
err3.message;
|
||||
});
|
||||
|
||||
const errorMap: z.ZodErrorMap = (error, ctx) => {
|
||||
if (error.code === ZodIssueCode.invalid_type) {
|
||||
if (error.expected === "string") {
|
||||
return { message: "bad type!" };
|
||||
}
|
||||
}
|
||||
if (error.code === ZodIssueCode.custom) {
|
||||
return { message: `less-than-${error.params?.minimum}` };
|
||||
}
|
||||
return { message: ctx.defaultError };
|
||||
};
|
||||
|
||||
test("type error with custom error map", () => {
|
||||
try {
|
||||
z.string().parse(234, { errorMap });
|
||||
} catch (err) {
|
||||
const zerr: z.ZodError = err as any;
|
||||
|
||||
expect(zerr.issues[0].code).toEqual(z.ZodIssueCode.invalid_type);
|
||||
expect(zerr.issues[0].message).toEqual(`bad type!`);
|
||||
}
|
||||
});
|
||||
|
||||
test("refinement fail with params", () => {
|
||||
try {
|
||||
z.number()
|
||||
.refine((val) => val >= 3, {
|
||||
params: { minimum: 3 },
|
||||
})
|
||||
.parse(2, { errorMap });
|
||||
} catch (err) {
|
||||
const zerr: z.ZodError = err as any;
|
||||
expect(zerr.issues[0].code).toEqual(z.ZodIssueCode.custom);
|
||||
expect(zerr.issues[0].message).toEqual(`less-than-3`);
|
||||
}
|
||||
});
|
||||
|
||||
test("custom error with custom errormap", () => {
|
||||
try {
|
||||
z.string()
|
||||
.refine((val) => val.length > 12, {
|
||||
params: { minimum: 13 },
|
||||
message: "override",
|
||||
})
|
||||
.parse("asdf", { errorMap });
|
||||
} catch (err) {
|
||||
const zerr: z.ZodError = err as any;
|
||||
expect(zerr.issues[0].message).toEqual("override");
|
||||
}
|
||||
});
|
||||
|
||||
test("default error message", () => {
|
||||
try {
|
||||
z.number()
|
||||
.refine((x) => x > 3)
|
||||
.parse(2);
|
||||
} catch (err) {
|
||||
const zerr: z.ZodError = err as any;
|
||||
expect(zerr.issues.length).toEqual(1);
|
||||
expect(zerr.issues[0].message).toEqual("Invalid input");
|
||||
}
|
||||
});
|
||||
|
||||
test("override error in refine", () => {
|
||||
try {
|
||||
z.number()
|
||||
.refine((x) => x > 3, "override")
|
||||
.parse(2);
|
||||
} catch (err) {
|
||||
const zerr: z.ZodError = err as any;
|
||||
expect(zerr.issues.length).toEqual(1);
|
||||
expect(zerr.issues[0].message).toEqual("override");
|
||||
}
|
||||
});
|
||||
|
||||
test("override error in refinement", () => {
|
||||
try {
|
||||
z.number()
|
||||
.refine((x) => x > 3, {
|
||||
message: "override",
|
||||
})
|
||||
.parse(2);
|
||||
} catch (err) {
|
||||
const zerr: z.ZodError = err as any;
|
||||
expect(zerr.issues.length).toEqual(1);
|
||||
expect(zerr.issues[0].message).toEqual("override");
|
||||
}
|
||||
});
|
||||
|
||||
test("array minimum", () => {
|
||||
try {
|
||||
z.array(z.string()).min(3, "tooshort").parse(["asdf", "qwer"]);
|
||||
} catch (err) {
|
||||
const zerr: ZodError = err as any;
|
||||
expect(zerr.issues[0].code).toEqual(ZodIssueCode.too_small);
|
||||
expect(zerr.issues[0].message).toEqual("tooshort");
|
||||
}
|
||||
try {
|
||||
z.array(z.string()).min(3).parse(["asdf", "qwer"]);
|
||||
} catch (err) {
|
||||
const zerr: ZodError = err as any;
|
||||
expect(zerr.issues[0].code).toEqual(ZodIssueCode.too_small);
|
||||
expect(zerr.issues[0].message).toEqual(`Array must contain at least 3 element(s)`);
|
||||
}
|
||||
});
|
||||
|
||||
// implement test for semi-smart union logic that checks for type error on either left or right
|
||||
// test("union smart errors", () => {
|
||||
// // expect.assertions(2);
|
||||
|
||||
// const p1 = z
|
||||
// .union([z.string(), z.number().refine((x) => x > 0)])
|
||||
// .safeParse(-3.2);
|
||||
|
||||
// if (p1.success === true) throw new Error();
|
||||
// expect(p1.success).toBe(false);
|
||||
// expect(p1.error.issues[0].code).toEqual(ZodIssueCode.custom);
|
||||
|
||||
// const p2 = z.union([z.string(), z.number()]).safeParse(false);
|
||||
// // .catch(err => expect(err.issues[0].code).toEqual(ZodIssueCode.invalid_union));
|
||||
// if (p2.success === true) throw new Error();
|
||||
// expect(p2.success).toBe(false);
|
||||
// expect(p2.error.issues[0].code).toEqual(ZodIssueCode.invalid_union);
|
||||
// });
|
||||
|
||||
test("custom path in custom error map", () => {
|
||||
const schema = z.object({
|
||||
items: z.array(z.string()).refine((data) => data.length > 3, {
|
||||
path: ["items-too-few"],
|
||||
}),
|
||||
});
|
||||
|
||||
const errorMap: z.ZodErrorMap = (error) => {
|
||||
expect(error.path.length).toBe(2);
|
||||
return { message: "doesnt matter" };
|
||||
};
|
||||
const result = schema.safeParse({ items: ["first"] }, { errorMap });
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues[0].path).toEqual(["items", "items-too-few"]);
|
||||
}
|
||||
});
|
||||
|
||||
test("error metadata from value", () => {
|
||||
const dynamicRefine = z.string().refine(
|
||||
(val) => val === val.toUpperCase(),
|
||||
(val) => ({ params: { val } })
|
||||
);
|
||||
|
||||
const result = dynamicRefine.safeParse("asdf");
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
const sub = result.error.issues[0];
|
||||
expect(result.error.issues[0].code).toEqual("custom");
|
||||
if (sub.code === "custom") {
|
||||
expect(sub.params!.val).toEqual("asdf");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// test("don't call refine after validation failed", () => {
|
||||
// const asdf = z
|
||||
// .union([
|
||||
// z.number(),
|
||||
// z.string().transform(z.number(), (val) => {
|
||||
// return parseFloat(val);
|
||||
// }),
|
||||
// ])
|
||||
// .refine((v) => v >= 1);
|
||||
|
||||
// expect(() => asdf.safeParse("foo")).not.toThrow();
|
||||
// });
|
||||
|
||||
test("root level formatting", () => {
|
||||
const schema = z.string().email();
|
||||
const result = schema.safeParse("asdfsdf");
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.format()._errors).toEqual(["Invalid email"]);
|
||||
}
|
||||
});
|
||||
|
||||
test("custom path", () => {
|
||||
const schema = z
|
||||
.object({
|
||||
password: z.string(),
|
||||
confirm: z.string(),
|
||||
})
|
||||
.refine((val) => val.confirm === val.password, { path: ["confirm"] });
|
||||
|
||||
const result = schema.safeParse({
|
||||
password: "peanuts",
|
||||
confirm: "qeanuts",
|
||||
});
|
||||
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
// nested errors
|
||||
const error = result.error.format();
|
||||
expect(error._errors).toEqual([]);
|
||||
expect(error.password?._errors).toEqual(undefined);
|
||||
expect(error.confirm?._errors).toEqual(["Invalid input"]);
|
||||
}
|
||||
});
|
||||
|
||||
test("custom path", () => {
|
||||
const schema = z
|
||||
.object({
|
||||
password: z.string().min(6),
|
||||
confirm: z.string().min(6),
|
||||
})
|
||||
.refine((val) => val.confirm === val.password);
|
||||
|
||||
const result = schema.safeParse({
|
||||
password: "qwer",
|
||||
confirm: "asdf",
|
||||
});
|
||||
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues.length).toEqual(3);
|
||||
}
|
||||
});
|
||||
|
||||
const schema = z.object({
|
||||
inner: z.object({
|
||||
name: z
|
||||
.string()
|
||||
.refine((val) => val.length > 5)
|
||||
.array()
|
||||
.refine((val) => val.length <= 1),
|
||||
}),
|
||||
});
|
||||
|
||||
test("no abort early on refinements", () => {
|
||||
const invalidItem = {
|
||||
inner: { name: ["aasd", "asdfasdfasfd"] },
|
||||
};
|
||||
|
||||
const result1 = schema.safeParse(invalidItem);
|
||||
expect(result1.success).toEqual(false);
|
||||
if (!result1.success) {
|
||||
expect(result1.error.issues.length).toEqual(2);
|
||||
}
|
||||
});
|
||||
test("formatting", () => {
|
||||
const invalidItem = {
|
||||
inner: { name: ["aasd", "asdfasdfasfd"] },
|
||||
};
|
||||
const invalidArray = {
|
||||
inner: { name: ["asdfasdf", "asdfasdfasfd"] },
|
||||
};
|
||||
const result1 = schema.safeParse(invalidItem);
|
||||
const result2 = schema.safeParse(invalidArray);
|
||||
|
||||
expect(result1.success).toEqual(false);
|
||||
expect(result2.success).toEqual(false);
|
||||
if (!result1.success) {
|
||||
const error = result1.error.format();
|
||||
|
||||
expect(error._errors).toEqual([]);
|
||||
expect(error.inner?._errors).toEqual([]);
|
||||
// expect(error.inner?.name?._errors).toEqual(["Invalid input"]);
|
||||
// expect(error.inner?.name?.[0]._errors).toEqual(["Invalid input"]);
|
||||
expect(error.inner?.name?.[1]).toEqual(undefined);
|
||||
}
|
||||
if (!result2.success) {
|
||||
type FormattedError = z.inferFormattedError<typeof schema>;
|
||||
const error: FormattedError = result2.error.format();
|
||||
expect(error._errors).toEqual([]);
|
||||
expect(error.inner?._errors).toEqual([]);
|
||||
expect(error.inner?.name?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.inner?.name?.[0]).toEqual(undefined);
|
||||
expect(error.inner?.name?.[1]).toEqual(undefined);
|
||||
expect(error.inner?.name?.[2]).toEqual(undefined);
|
||||
}
|
||||
|
||||
// test custom mapper
|
||||
if (!result2.success) {
|
||||
type FormattedError = z.inferFormattedError<typeof schema, number>;
|
||||
const error: FormattedError = result2.error.format(() => 5);
|
||||
expect(error._errors).toEqual([]);
|
||||
expect(error.inner?._errors).toEqual([]);
|
||||
expect(error.inner?.name?._errors).toEqual([5]);
|
||||
}
|
||||
});
|
||||
|
||||
test("formatting with nullable and optional fields", () => {
|
||||
const nameSchema = z.string().refine((val) => val.length > 5);
|
||||
const schema = z.object({
|
||||
nullableObject: z.object({ name: nameSchema }).nullable(),
|
||||
nullableArray: z.array(nameSchema).nullable(),
|
||||
nullableTuple: z.tuple([nameSchema, nameSchema, z.number()]).nullable(),
|
||||
optionalObject: z.object({ name: nameSchema }).optional(),
|
||||
optionalArray: z.array(nameSchema).optional(),
|
||||
optionalTuple: z.tuple([nameSchema, nameSchema, z.number()]).optional(),
|
||||
});
|
||||
const invalidItem = {
|
||||
nullableObject: { name: "abcd" },
|
||||
nullableArray: ["abcd"],
|
||||
nullableTuple: ["abcd", "abcd", 1],
|
||||
optionalObject: { name: "abcd" },
|
||||
optionalArray: ["abcd"],
|
||||
optionalTuple: ["abcd", "abcd", 1],
|
||||
};
|
||||
const result = schema.safeParse(invalidItem);
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
type FormattedError = z.inferFormattedError<typeof schema>;
|
||||
const error: FormattedError = result.error.format();
|
||||
expect(error._errors).toEqual([]);
|
||||
expect(error.nullableObject?._errors).toEqual([]);
|
||||
expect(error.nullableObject?.name?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.nullableArray?._errors).toEqual([]);
|
||||
expect(error.nullableArray?.[0]?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.nullableTuple?._errors).toEqual([]);
|
||||
expect(error.nullableTuple?.[0]?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.nullableTuple?.[1]?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.optionalObject?._errors).toEqual([]);
|
||||
expect(error.optionalObject?.name?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.optionalArray?._errors).toEqual([]);
|
||||
expect(error.optionalArray?.[0]?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.optionalTuple?._errors).toEqual([]);
|
||||
expect(error.optionalTuple?.[0]?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.optionalTuple?.[1]?._errors).toEqual(["Invalid input"]);
|
||||
}
|
||||
});
|
||||
|
||||
const stringWithCustomError = z.string({
|
||||
errorMap: (issue, ctx) => ({
|
||||
message: issue.code === "invalid_type" ? (ctx.data ? "Invalid name" : "Name is required") : ctx.defaultError,
|
||||
}),
|
||||
});
|
||||
|
||||
test("schema-bound error map", () => {
|
||||
const result = stringWithCustomError.safeParse(1234);
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues[0].message).toEqual("Invalid name");
|
||||
}
|
||||
|
||||
const result2 = stringWithCustomError.safeParse(undefined);
|
||||
expect(result2.success).toEqual(false);
|
||||
if (!result2.success) {
|
||||
expect(result2.error.issues[0].message).toEqual("Name is required");
|
||||
}
|
||||
|
||||
// support contextual override
|
||||
const result3 = stringWithCustomError.safeParse(undefined, {
|
||||
errorMap: () => ({ message: "OVERRIDE" }),
|
||||
});
|
||||
expect(result3.success).toEqual(false);
|
||||
if (!result3.success) {
|
||||
expect(result3.error.issues[0].message).toEqual("OVERRIDE");
|
||||
}
|
||||
});
|
||||
|
||||
test("overrideErrorMap", () => {
|
||||
// support overrideErrorMap
|
||||
z.setErrorMap(() => ({ message: "OVERRIDE" }));
|
||||
const result4 = stringWithCustomError.min(10).safeParse("tooshort");
|
||||
expect(result4.success).toEqual(false);
|
||||
if (!result4.success) {
|
||||
expect(result4.error.issues[0].message).toEqual("OVERRIDE");
|
||||
}
|
||||
z.setErrorMap(z.defaultErrorMap);
|
||||
});
|
||||
|
||||
test("invalid and required", () => {
|
||||
const str = z.string({
|
||||
invalid_type_error: "Invalid name",
|
||||
required_error: "Name is required",
|
||||
});
|
||||
const result1 = str.safeParse(1234);
|
||||
expect(result1.success).toEqual(false);
|
||||
if (!result1.success) {
|
||||
expect(result1.error.issues[0].message).toEqual("Invalid name");
|
||||
}
|
||||
const result2 = str.safeParse(undefined);
|
||||
expect(result2.success).toEqual(false);
|
||||
if (!result2.success) {
|
||||
expect(result2.error.issues[0].message).toEqual("Name is required");
|
||||
}
|
||||
});
|
||||
|
||||
test("Fallback to default required error", () => {
|
||||
const str = z.string({
|
||||
invalid_type_error: "Invalid name",
|
||||
// required_error: "Name is required",
|
||||
});
|
||||
|
||||
const result2 = str.safeParse(undefined);
|
||||
expect(result2.success).toEqual(false);
|
||||
if (!result2.success) {
|
||||
expect(result2.error.issues[0].message).toEqual("Required");
|
||||
}
|
||||
});
|
||||
|
||||
test("invalid and required and errorMap", () => {
|
||||
expect(() => {
|
||||
return z.string({
|
||||
invalid_type_error: "Invalid name",
|
||||
required_error: "Name is required",
|
||||
errorMap: () => ({ message: "OVERRIDE" }),
|
||||
});
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
test("strict error message", () => {
|
||||
const errorMsg = "Invalid object";
|
||||
const obj = z.object({ x: z.string() }).strict(errorMsg);
|
||||
const result = obj.safeParse({ x: "a", y: "b" });
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues[0].message).toEqual(errorMsg);
|
||||
}
|
||||
});
|
||||
|
||||
test("enum error message, invalid enum elementstring", () => {
|
||||
try {
|
||||
z.enum(["Tuna", "Trout"]).parse("Salmon");
|
||||
} catch (err) {
|
||||
const zerr: z.ZodError = err as any;
|
||||
expect(zerr.issues.length).toEqual(1);
|
||||
expect(zerr.issues[0].message).toEqual("Invalid enum value. Expected 'Tuna' | 'Trout', received 'Salmon'");
|
||||
}
|
||||
});
|
||||
|
||||
test("enum error message, invalid type", () => {
|
||||
try {
|
||||
z.enum(["Tuna", "Trout"]).parse(12);
|
||||
} catch (err) {
|
||||
const zerr: z.ZodError = err as any;
|
||||
expect(zerr.issues.length).toEqual(1);
|
||||
expect(zerr.issues[0].message).toEqual("Expected 'Tuna' | 'Trout', received number");
|
||||
}
|
||||
});
|
||||
|
||||
test("nativeEnum default error message", () => {
|
||||
enum Fish {
|
||||
Tuna = "Tuna",
|
||||
Trout = "Trout",
|
||||
}
|
||||
try {
|
||||
z.nativeEnum(Fish).parse("Salmon");
|
||||
} catch (err) {
|
||||
const zerr: z.ZodError = err as any;
|
||||
expect(zerr.issues.length).toEqual(1);
|
||||
expect(zerr.issues[0].message).toEqual("Invalid enum value. Expected 'Tuna' | 'Trout', received 'Salmon'");
|
||||
}
|
||||
});
|
||||
|
||||
test("literal default error message", () => {
|
||||
try {
|
||||
z.literal("Tuna").parse("Trout");
|
||||
} catch (err) {
|
||||
const zerr: z.ZodError = err as any;
|
||||
expect(zerr.issues.length).toEqual(1);
|
||||
expect(zerr.issues[0].message).toEqual(`Invalid literal value, expected "Tuna"`);
|
||||
}
|
||||
});
|
||||
|
||||
test("literal bigint default error message", () => {
|
||||
try {
|
||||
z.literal(BigInt(12)).parse(BigInt(13));
|
||||
} catch (err) {
|
||||
const zerr: z.ZodError = err as any;
|
||||
expect(zerr.issues.length).toEqual(1);
|
||||
expect(zerr.issues[0].message).toEqual(`Invalid literal value, expected "12"`);
|
||||
}
|
||||
});
|
||||
|
||||
test("enum with message returns the custom error message", () => {
|
||||
const schema = z.enum(["apple", "banana"], {
|
||||
message: "the value provided is invalid",
|
||||
});
|
||||
|
||||
const result1 = schema.safeParse("berries");
|
||||
expect(result1.success).toEqual(false);
|
||||
if (!result1.success) {
|
||||
expect(result1.error.issues[0].message).toEqual("the value provided is invalid");
|
||||
}
|
||||
|
||||
const result2 = schema.safeParse(undefined);
|
||||
expect(result2.success).toEqual(false);
|
||||
if (!result2.success) {
|
||||
expect(result2.error.issues[0].message).toEqual("the value provided is invalid");
|
||||
}
|
||||
|
||||
const result3 = schema.safeParse("banana");
|
||||
expect(result3.success).toEqual(true);
|
||||
|
||||
const result4 = schema.safeParse(null);
|
||||
expect(result4.success).toEqual(false);
|
||||
if (!result4.success) {
|
||||
expect(result4.error.issues[0].message).toEqual("the value provided is invalid");
|
||||
}
|
||||
});
|
||||
|
||||
test("when the message is falsy, it is used as is provided", () => {
|
||||
const schema = z.string().max(1, { message: "" });
|
||||
const result = schema.safeParse("asdf");
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues[0].message).toEqual("");
|
||||
}
|
||||
});
|
||||
|
||||
// test("dont short circuit on continuable errors", () => {
|
||||
// const user = z
|
||||
// .object({
|
||||
// password: z.string().min(6),
|
||||
// confirm: z.string(),
|
||||
// })
|
||||
// .refine((data) => data.password === data.confirm, {
|
||||
// message: "Passwords don't match",
|
||||
// path: ["confirm"],
|
||||
// });
|
||||
// const result = user.safeParse({ password: "asdf", confirm: "qwer" });
|
||||
// if (!result.success) {
|
||||
// expect(result.error.issues.length).toEqual(2);
|
||||
// }
|
||||
// });
|
87
node_modules/zod/src/v3/tests/firstparty.test.ts
generated
vendored
Normal file
87
node_modules/zod/src/v3/tests/firstparty.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
// @ts-ignore TS6133
|
||||
import { test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("first party switch", () => {
|
||||
const myType = z.string() as z.ZodFirstPartySchemaTypes;
|
||||
const def = myType._def;
|
||||
|
||||
switch (def.typeName) {
|
||||
case z.ZodFirstPartyTypeKind.ZodString:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodNumber:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodNaN:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodBigInt:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodBoolean:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodDate:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodUndefined:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodNull:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodAny:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodUnknown:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodNever:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodVoid:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodArray:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodObject:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodUnion:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodDiscriminatedUnion:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodIntersection:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodTuple:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodRecord:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodMap:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodSet:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodFunction:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodLazy:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodLiteral:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodEnum:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodEffects:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodNativeEnum:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodOptional:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodNullable:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodDefault:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodCatch:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodPromise:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodBranded:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodPipeline:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodSymbol:
|
||||
break;
|
||||
case z.ZodFirstPartyTypeKind.ZodReadonly:
|
||||
break;
|
||||
default:
|
||||
util.assertNever(def);
|
||||
}
|
||||
});
|
21
node_modules/zod/src/v3/tests/firstpartyschematypes.test.ts
generated
vendored
Normal file
21
node_modules/zod/src/v3/tests/firstpartyschematypes.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
// @ts-ignore TS6133
|
||||
import { test } from "vitest";
|
||||
|
||||
import type { ZodFirstPartySchemaTypes, ZodFirstPartyTypeKind } from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("Identify missing [ZodFirstPartySchemaTypes]", () => {
|
||||
type ZodFirstPartySchemaForType<T extends ZodFirstPartyTypeKind> = ZodFirstPartySchemaTypes extends infer Schema
|
||||
? Schema extends { _def: { typeName: T } }
|
||||
? Schema
|
||||
: never
|
||||
: never;
|
||||
type ZodMappedTypes = {
|
||||
[key in ZodFirstPartyTypeKind]: ZodFirstPartySchemaForType<key>;
|
||||
};
|
||||
type ZodFirstPartySchemaTypesMissingFromUnion = keyof {
|
||||
[key in keyof ZodMappedTypes as ZodMappedTypes[key] extends { _def: never } ? key : never]: unknown;
|
||||
};
|
||||
|
||||
util.assertEqual<ZodFirstPartySchemaTypesMissingFromUnion, never>(true);
|
||||
});
|
257
node_modules/zod/src/v3/tests/function.test.ts
generated
vendored
Normal file
257
node_modules/zod/src/v3/tests/function.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,257 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
const args1 = z.tuple([z.string()]);
|
||||
const returns1 = z.number();
|
||||
const func1 = z.function(args1, returns1);
|
||||
|
||||
test("function parsing", () => {
|
||||
const parsed = func1.parse((arg: any) => arg.length);
|
||||
parsed("asdf");
|
||||
});
|
||||
|
||||
test("parsed function fail 1", () => {
|
||||
const parsed = func1.parse((x: string) => x);
|
||||
expect(() => parsed("asdf")).toThrow();
|
||||
});
|
||||
|
||||
test("parsed function fail 2", () => {
|
||||
const parsed = func1.parse((x: string) => x);
|
||||
expect(() => parsed(13 as any)).toThrow();
|
||||
});
|
||||
|
||||
test("function inference 1", () => {
|
||||
type func1 = z.TypeOf<typeof func1>;
|
||||
util.assertEqual<func1, (k: string) => number>(true);
|
||||
});
|
||||
|
||||
test("method parsing", () => {
|
||||
const methodObject = z.object({
|
||||
property: z.number(),
|
||||
method: z.function().args(z.string()).returns(z.number()),
|
||||
});
|
||||
const methodInstance = {
|
||||
property: 3,
|
||||
method: function (s: string) {
|
||||
return s.length + this.property;
|
||||
},
|
||||
};
|
||||
const parsed = methodObject.parse(methodInstance);
|
||||
expect(parsed.method("length=8")).toBe(11); // 8 length + 3 property
|
||||
});
|
||||
|
||||
test("async method parsing", async () => {
|
||||
const methodObject = z.object({
|
||||
property: z.number(),
|
||||
method: z.function().args(z.string()).returns(z.promise(z.number())),
|
||||
});
|
||||
const methodInstance = {
|
||||
property: 3,
|
||||
method: async function (s: string) {
|
||||
return s.length + this.property;
|
||||
},
|
||||
};
|
||||
const parsed = methodObject.parse(methodInstance);
|
||||
expect(await parsed.method("length=8")).toBe(11); // 8 length + 3 property
|
||||
});
|
||||
|
||||
test("args method", () => {
|
||||
const t1 = z.function();
|
||||
type t1 = z.infer<typeof t1>;
|
||||
util.assertEqual<t1, (...args_1: unknown[]) => unknown>(true);
|
||||
|
||||
const t2 = t1.args(z.string());
|
||||
type t2 = z.infer<typeof t2>;
|
||||
util.assertEqual<t2, (arg: string, ...args_1: unknown[]) => unknown>(true);
|
||||
|
||||
const t3 = t2.returns(z.boolean());
|
||||
type t3 = z.infer<typeof t3>;
|
||||
util.assertEqual<t3, (arg: string, ...args_1: unknown[]) => boolean>(true);
|
||||
});
|
||||
|
||||
const args2 = z.tuple([
|
||||
z.object({
|
||||
f1: z.number(),
|
||||
f2: z.string().nullable(),
|
||||
f3: z.array(z.boolean().optional()).optional(),
|
||||
}),
|
||||
]);
|
||||
const returns2 = z.union([z.string(), z.number()]);
|
||||
|
||||
const func2 = z.function(args2, returns2);
|
||||
|
||||
test("function inference 2", () => {
|
||||
type func2 = z.TypeOf<typeof func2>;
|
||||
util.assertEqual<
|
||||
func2,
|
||||
(arg: {
|
||||
f1: number;
|
||||
f2: string | null;
|
||||
f3?: (boolean | undefined)[] | undefined;
|
||||
}) => string | number
|
||||
>(true);
|
||||
});
|
||||
|
||||
test("valid function run", () => {
|
||||
const validFunc2Instance = func2.validate((_x) => {
|
||||
return "adf" as any;
|
||||
});
|
||||
|
||||
const checker = () => {
|
||||
validFunc2Instance({
|
||||
f1: 21,
|
||||
f2: "asdf",
|
||||
f3: [true, false],
|
||||
});
|
||||
};
|
||||
|
||||
checker();
|
||||
});
|
||||
|
||||
test("input validation error", () => {
|
||||
const invalidFuncInstance = func2.validate((_x) => {
|
||||
return "adf" as any;
|
||||
});
|
||||
|
||||
const checker = () => {
|
||||
invalidFuncInstance("Invalid_input" as any);
|
||||
};
|
||||
|
||||
expect(checker).toThrow();
|
||||
});
|
||||
|
||||
test("output validation error", () => {
|
||||
const invalidFuncInstance = func2.validate((_x) => {
|
||||
return ["this", "is", "not", "valid", "output"] as any;
|
||||
});
|
||||
|
||||
const checker = () => {
|
||||
invalidFuncInstance({
|
||||
f1: 21,
|
||||
f2: "asdf",
|
||||
f3: [true, false],
|
||||
});
|
||||
};
|
||||
|
||||
expect(checker).toThrow();
|
||||
});
|
||||
|
||||
z.function(z.tuple([z.string()])).args()._def.args;
|
||||
|
||||
test("special function error codes", () => {
|
||||
const checker = z.function(z.tuple([z.string()]), z.boolean()).implement((arg) => {
|
||||
return arg.length as any;
|
||||
});
|
||||
try {
|
||||
checker("12" as any);
|
||||
} catch (err) {
|
||||
const zerr = err as z.ZodError;
|
||||
const first = zerr.issues[0];
|
||||
if (first.code !== z.ZodIssueCode.invalid_return_type) throw new Error();
|
||||
|
||||
expect(first.returnTypeError).toBeInstanceOf(z.ZodError);
|
||||
}
|
||||
|
||||
try {
|
||||
checker(12 as any);
|
||||
} catch (err) {
|
||||
const zerr = err as z.ZodError;
|
||||
const first = zerr.issues[0];
|
||||
if (first.code !== z.ZodIssueCode.invalid_arguments) throw new Error();
|
||||
expect(first.argumentsError).toBeInstanceOf(z.ZodError);
|
||||
}
|
||||
});
|
||||
|
||||
test("function with async refinements", async () => {
|
||||
const func = z
|
||||
.function()
|
||||
.args(z.string().refine(async (val) => val.length > 10))
|
||||
.returns(z.promise(z.number().refine(async (val) => val > 10)))
|
||||
.implement(async (val) => {
|
||||
return val.length;
|
||||
});
|
||||
const results = [];
|
||||
try {
|
||||
await func("asdfasdf");
|
||||
results.push("success");
|
||||
} catch (_err) {
|
||||
results.push("fail");
|
||||
}
|
||||
try {
|
||||
await func("asdflkjasdflkjsf");
|
||||
results.push("success");
|
||||
} catch (_err) {
|
||||
results.push("fail");
|
||||
}
|
||||
|
||||
expect(results).toEqual(["fail", "success"]);
|
||||
});
|
||||
|
||||
test("non async function with async refinements should fail", async () => {
|
||||
const func = z
|
||||
.function()
|
||||
.args(z.string().refine(async (val) => val.length > 10))
|
||||
.returns(z.number().refine(async (val) => val > 10))
|
||||
.implement((val) => {
|
||||
return val.length;
|
||||
});
|
||||
|
||||
const results = [];
|
||||
try {
|
||||
await func("asdasdfasdffasdf");
|
||||
results.push("success");
|
||||
} catch (_err) {
|
||||
results.push("fail");
|
||||
}
|
||||
|
||||
expect(results).toEqual(["fail"]);
|
||||
});
|
||||
|
||||
test("allow extra parameters", () => {
|
||||
const maxLength5 = z
|
||||
.function()
|
||||
.args(z.string())
|
||||
.returns(z.boolean())
|
||||
.implement((str, _arg, _qewr) => {
|
||||
return str.length <= 5;
|
||||
});
|
||||
|
||||
const filteredList = ["apple", "orange", "pear", "banana", "strawberry"].filter(maxLength5);
|
||||
expect(filteredList.length).toEqual(2);
|
||||
});
|
||||
|
||||
test("params and returnType getters", () => {
|
||||
const func = z.function().args(z.string()).returns(z.string());
|
||||
|
||||
func.parameters().items[0].parse("asdf");
|
||||
func.returnType().parse("asdf");
|
||||
});
|
||||
|
||||
test("inference with transforms", () => {
|
||||
const funcSchema = z
|
||||
.function()
|
||||
.args(z.string().transform((val) => val.length))
|
||||
.returns(z.object({ val: z.number() }));
|
||||
const myFunc = funcSchema.implement((val) => {
|
||||
return { val, extra: "stuff" };
|
||||
});
|
||||
myFunc("asdf");
|
||||
|
||||
util.assertEqual<typeof myFunc, (arg: string, ...args_1: unknown[]) => { val: number; extra: string }>(true);
|
||||
});
|
||||
|
||||
test("fallback to OuterTypeOfFunction", () => {
|
||||
const funcSchema = z
|
||||
.function()
|
||||
.args(z.string().transform((val) => val.length))
|
||||
.returns(z.object({ arg: z.number() }).transform((val) => val.arg));
|
||||
|
||||
const myFunc = funcSchema.implement((val) => {
|
||||
return { arg: val, arg2: false };
|
||||
});
|
||||
|
||||
util.assertEqual<typeof myFunc, (arg: string, ...args_1: unknown[]) => number>(true);
|
||||
});
|
48
node_modules/zod/src/v3/tests/generics.test.ts
generated
vendored
Normal file
48
node_modules/zod/src/v3/tests/generics.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("generics", () => {
|
||||
async function stripOuter<TData extends z.ZodTypeAny>(schema: TData, data: unknown) {
|
||||
return z
|
||||
.object({
|
||||
nested: schema, // as z.ZodTypeAny,
|
||||
})
|
||||
.transform((data) => {
|
||||
return data.nested!;
|
||||
})
|
||||
.parse({ nested: data });
|
||||
}
|
||||
|
||||
const result = stripOuter(z.object({ a: z.string() }), { a: "asdf" });
|
||||
util.assertEqual<typeof result, Promise<{ a: string }>>(true);
|
||||
});
|
||||
|
||||
// test("assignability", () => {
|
||||
// const createSchemaAndParse = <K extends string, VS extends z.ZodString>(
|
||||
// key: K,
|
||||
// valueSchema: VS,
|
||||
// data: unknown
|
||||
// ) => {
|
||||
// const schema = z.object({
|
||||
// [key]: valueSchema,
|
||||
// } as { [k in K]: VS });
|
||||
// return { [key]: valueSchema };
|
||||
// const parsed = schema.parse(data);
|
||||
// return parsed;
|
||||
// // const inferred: z.infer<z.ZodObject<{ [k in K]: VS }>> = parsed;
|
||||
// // return inferred;
|
||||
// };
|
||||
// const parsed = createSchemaAndParse("foo", z.string(), { foo: "" });
|
||||
// util.assertEqual<typeof parsed, { foo: string }>(true);
|
||||
// });
|
||||
|
||||
test("nested no undefined", () => {
|
||||
const inner = z.string().or(z.array(z.string()));
|
||||
const outer = z.object({ inner });
|
||||
type outerSchema = z.infer<typeof outer>;
|
||||
z.util.assertEqual<outerSchema, { inner: string | string[] }>(true);
|
||||
expect(outer.safeParse({ inner: undefined }).success).toEqual(false);
|
||||
});
|
37
node_modules/zod/src/v3/tests/instanceof.test.ts
generated
vendored
Normal file
37
node_modules/zod/src/v3/tests/instanceof.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("instanceof", async () => {
|
||||
class Test {}
|
||||
class Subtest extends Test {}
|
||||
abstract class AbstractBar {
|
||||
constructor(public val: string) {}
|
||||
}
|
||||
class Bar extends AbstractBar {}
|
||||
|
||||
const TestSchema = z.instanceof(Test);
|
||||
const SubtestSchema = z.instanceof(Subtest);
|
||||
const AbstractSchema = z.instanceof(AbstractBar);
|
||||
const BarSchema = z.instanceof(Bar);
|
||||
|
||||
TestSchema.parse(new Test());
|
||||
TestSchema.parse(new Subtest());
|
||||
SubtestSchema.parse(new Subtest());
|
||||
AbstractSchema.parse(new Bar("asdf"));
|
||||
const bar = BarSchema.parse(new Bar("asdf"));
|
||||
expect(bar.val).toEqual("asdf");
|
||||
|
||||
await expect(() => SubtestSchema.parse(new Test())).toThrow(/Input not instance of Subtest/);
|
||||
await expect(() => TestSchema.parse(12)).toThrow(/Input not instance of Test/);
|
||||
|
||||
util.assertEqual<Test, z.infer<typeof TestSchema>>(true);
|
||||
});
|
||||
|
||||
test("instanceof fatal", () => {
|
||||
const schema = z.instanceof(Date).refine((d) => d.toString());
|
||||
const res = schema.safeParse(null);
|
||||
expect(res.success).toBe(false);
|
||||
});
|
110
node_modules/zod/src/v3/tests/intersection.test.ts
generated
vendored
Normal file
110
node_modules/zod/src/v3/tests/intersection.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
test("object intersection", () => {
|
||||
const BaseTeacher = z.object({
|
||||
subjects: z.array(z.string()),
|
||||
});
|
||||
const HasID = z.object({ id: z.string() });
|
||||
|
||||
const Teacher = z.intersection(BaseTeacher.passthrough(), HasID); // BaseTeacher.merge(HasID);
|
||||
const data = {
|
||||
subjects: ["math"],
|
||||
id: "asdfasdf",
|
||||
};
|
||||
expect(Teacher.parse(data)).toEqual(data);
|
||||
expect(() => Teacher.parse({ subject: data.subjects })).toThrow();
|
||||
expect(Teacher.parse({ ...data, extra: 12 })).toEqual({ ...data, extra: 12 });
|
||||
|
||||
expect(() => z.intersection(BaseTeacher.strict(), HasID).parse({ ...data, extra: 12 })).toThrow();
|
||||
});
|
||||
|
||||
test("deep intersection", () => {
|
||||
const Animal = z.object({
|
||||
properties: z.object({
|
||||
is_animal: z.boolean(),
|
||||
}),
|
||||
});
|
||||
const Cat = z
|
||||
.object({
|
||||
properties: z.object({
|
||||
jumped: z.boolean(),
|
||||
}),
|
||||
})
|
||||
.and(Animal);
|
||||
|
||||
type _Cat = z.infer<typeof Cat>;
|
||||
// const cat:Cat = 'asdf' as any;
|
||||
const cat = Cat.parse({ properties: { is_animal: true, jumped: true } });
|
||||
expect(cat.properties).toEqual({ is_animal: true, jumped: true });
|
||||
});
|
||||
|
||||
test("deep intersection of arrays", async () => {
|
||||
const Author = z.object({
|
||||
posts: z.array(
|
||||
z.object({
|
||||
post_id: z.number(),
|
||||
})
|
||||
),
|
||||
});
|
||||
const Registry = z
|
||||
.object({
|
||||
posts: z.array(
|
||||
z.object({
|
||||
title: z.string(),
|
||||
})
|
||||
),
|
||||
})
|
||||
.and(Author);
|
||||
|
||||
const posts = [
|
||||
{ post_id: 1, title: "Novels" },
|
||||
{ post_id: 2, title: "Fairy tales" },
|
||||
];
|
||||
const cat = Registry.parse({ posts });
|
||||
expect(cat.posts).toEqual(posts);
|
||||
const asyncCat = await Registry.parseAsync({ posts });
|
||||
expect(asyncCat.posts).toEqual(posts);
|
||||
});
|
||||
|
||||
test("invalid intersection types", async () => {
|
||||
const numberIntersection = z.intersection(
|
||||
z.number(),
|
||||
z.number().transform((x) => x + 1)
|
||||
);
|
||||
|
||||
const syncResult = numberIntersection.safeParse(1234);
|
||||
expect(syncResult.success).toEqual(false);
|
||||
if (!syncResult.success) {
|
||||
expect(syncResult.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_intersection_types);
|
||||
}
|
||||
|
||||
const asyncResult = await numberIntersection.spa(1234);
|
||||
expect(asyncResult.success).toEqual(false);
|
||||
if (!asyncResult.success) {
|
||||
expect(asyncResult.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_intersection_types);
|
||||
}
|
||||
});
|
||||
|
||||
test("invalid array merge", async () => {
|
||||
const stringArrInt = z.intersection(
|
||||
z.string().array(),
|
||||
z
|
||||
.string()
|
||||
.array()
|
||||
.transform((val) => [...val, "asdf"])
|
||||
);
|
||||
const syncResult = stringArrInt.safeParse(["asdf", "qwer"]);
|
||||
expect(syncResult.success).toEqual(false);
|
||||
if (!syncResult.success) {
|
||||
expect(syncResult.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_intersection_types);
|
||||
}
|
||||
|
||||
const asyncResult = await stringArrInt.spa(["asdf", "qwer"]);
|
||||
expect(asyncResult.success).toEqual(false);
|
||||
if (!asyncResult.success) {
|
||||
expect(asyncResult.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_intersection_types);
|
||||
}
|
||||
});
|
76
node_modules/zod/src/v3/tests/language-server.source.ts
generated
vendored
Normal file
76
node_modules/zod/src/v3/tests/language-server.source.ts
generated
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
import * as z from "zod/v3";
|
||||
|
||||
export const filePath = __filename;
|
||||
|
||||
// z.object()
|
||||
|
||||
export const Test = z.object({
|
||||
f1: z.number(),
|
||||
});
|
||||
|
||||
export type Test = z.infer<typeof Test>;
|
||||
|
||||
export const instanceOfTest: Test = {
|
||||
f1: 1,
|
||||
};
|
||||
|
||||
// z.object().merge()
|
||||
|
||||
export const TestMerge = z
|
||||
.object({
|
||||
f2: z.string().optional(),
|
||||
})
|
||||
.merge(Test);
|
||||
|
||||
export type TestMerge = z.infer<typeof TestMerge>;
|
||||
|
||||
export const instanceOfTestMerge: TestMerge = {
|
||||
f1: 1,
|
||||
f2: "string",
|
||||
};
|
||||
|
||||
// z.union()
|
||||
|
||||
export const TestUnion = z.union([
|
||||
z.object({
|
||||
f2: z.string().optional(),
|
||||
}),
|
||||
Test,
|
||||
]);
|
||||
|
||||
export type TestUnion = z.infer<typeof TestUnion>;
|
||||
|
||||
export const instanceOfTestUnion: TestUnion = {
|
||||
f1: 1,
|
||||
f2: "string",
|
||||
};
|
||||
|
||||
// z.object().partial()
|
||||
|
||||
export const TestPartial = Test.partial();
|
||||
|
||||
export type TestPartial = z.infer<typeof TestPartial>;
|
||||
|
||||
export const instanceOfTestPartial: TestPartial = {
|
||||
f1: 1,
|
||||
};
|
||||
|
||||
// z.object().pick()
|
||||
|
||||
export const TestPick = TestMerge.pick({ f1: true });
|
||||
|
||||
export type TestPick = z.infer<typeof TestPick>;
|
||||
|
||||
export const instanceOfTestPick: TestPick = {
|
||||
f1: 1,
|
||||
};
|
||||
|
||||
// z.object().omit()
|
||||
|
||||
export const TestOmit = TestMerge.omit({ f2: true });
|
||||
|
||||
export type TestOmit = z.infer<typeof TestOmit>;
|
||||
|
||||
export const instanceOfTestOmit: TestOmit = {
|
||||
f1: 1,
|
||||
};
|
207
node_modules/zod/src/v3/tests/language-server.test.ts
generated
vendored
Normal file
207
node_modules/zod/src/v3/tests/language-server.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,207 @@
|
|||
import { test } from "vitest";
|
||||
// import path from "path";
|
||||
// import { Node, Project, SyntaxKind } from "ts-morph";
|
||||
|
||||
// import { filePath } from "./language-server.source";
|
||||
|
||||
// The following tool is helpful for understanding the TypeScript AST associated with these tests:
|
||||
// https://ts-ast-viewer.com/ (just copy the contents of language-server.source into the viewer)
|
||||
|
||||
test("", () => {});
|
||||
// describe("Executing Go To Definition (and therefore Find Usages and Rename Refactoring) using an IDE works on inferred object properties", () => {
|
||||
// // Compile file developmentEnvironment.source
|
||||
// const project = new Project({
|
||||
// tsConfigFilePath: path.join(__dirname, "..", "..", "tsconfig.json"),
|
||||
// skipAddingFilesFromTsConfig: true,
|
||||
// });
|
||||
// const sourceFile = project.addSourceFileAtPath(filePath);
|
||||
|
||||
// test("works for object properties inferred from z.object()", () => {
|
||||
// // Find usage of Test.f1 property
|
||||
// const instanceVariable =
|
||||
// sourceFile.getVariableDeclarationOrThrow("instanceOfTest");
|
||||
// const propertyBeingAssigned = getPropertyBeingAssigned(
|
||||
// instanceVariable,
|
||||
// "f1"
|
||||
// );
|
||||
|
||||
// // Find definition of Test.f1 property
|
||||
// const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0];
|
||||
// const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind(
|
||||
// SyntaxKind.VariableDeclaration
|
||||
// );
|
||||
|
||||
// // Assert that find definition returned the Zod definition of Test
|
||||
// expect(definitionOfProperty?.getText()).toEqual("f1: z.number()");
|
||||
// expect(parentOfProperty?.getName()).toEqual("Test");
|
||||
// });
|
||||
|
||||
// // test("works for first object properties inferred from z.object().merge()", () => {
|
||||
// // // Find usage of TestMerge.f1 property
|
||||
// // const instanceVariable = sourceFile.getVariableDeclarationOrThrow(
|
||||
// // "instanceOfTestMerge"
|
||||
// // );
|
||||
// // const propertyBeingAssigned = getPropertyBeingAssigned(
|
||||
// // instanceVariable,
|
||||
// // "f1"
|
||||
// // );
|
||||
|
||||
// // // Find definition of TestMerge.f1 property
|
||||
// // const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0];
|
||||
// // const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind(
|
||||
// // SyntaxKind.VariableDeclaration
|
||||
// // );
|
||||
|
||||
// // // Assert that find definition returned the Zod definition of Test
|
||||
// // expect(definitionOfProperty?.getText()).toEqual("f1: z.number()");
|
||||
// // expect(parentOfProperty?.getName()).toEqual("Test");
|
||||
// // });
|
||||
|
||||
// // test("works for second object properties inferred from z.object().merge()", () => {
|
||||
// // // Find usage of TestMerge.f2 property
|
||||
// // const instanceVariable = sourceFile.getVariableDeclarationOrThrow(
|
||||
// // "instanceOfTestMerge"
|
||||
// // );
|
||||
// // const propertyBeingAssigned = getPropertyBeingAssigned(
|
||||
// // instanceVariable,
|
||||
// // "f2"
|
||||
// // );
|
||||
|
||||
// // // Find definition of TestMerge.f2 property
|
||||
// // const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0];
|
||||
// // const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind(
|
||||
// // SyntaxKind.VariableDeclaration
|
||||
// // );
|
||||
|
||||
// // // Assert that find definition returned the Zod definition of TestMerge
|
||||
// // expect(definitionOfProperty?.getText()).toEqual(
|
||||
// // "f2: z.string().optional()"
|
||||
// // );
|
||||
// // expect(parentOfProperty?.getName()).toEqual("TestMerge");
|
||||
// // });
|
||||
|
||||
// test("works for first object properties inferred from z.union()", () => {
|
||||
// // Find usage of TestUnion.f1 property
|
||||
// const instanceVariable = sourceFile.getVariableDeclarationOrThrow(
|
||||
// "instanceOfTestUnion"
|
||||
// );
|
||||
// const propertyBeingAssigned = getPropertyBeingAssigned(
|
||||
// instanceVariable,
|
||||
// "f1"
|
||||
// );
|
||||
|
||||
// // Find definition of TestUnion.f1 property
|
||||
// const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0];
|
||||
// const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind(
|
||||
// SyntaxKind.VariableDeclaration
|
||||
// );
|
||||
|
||||
// // Assert that find definition returned the Zod definition of Test
|
||||
// expect(definitionOfProperty?.getText()).toEqual("f1: z.number()");
|
||||
// expect(parentOfProperty?.getName()).toEqual("Test");
|
||||
// });
|
||||
|
||||
// test("works for second object properties inferred from z.union()", () => {
|
||||
// // Find usage of TestUnion.f2 property
|
||||
// const instanceVariable = sourceFile.getVariableDeclarationOrThrow(
|
||||
// "instanceOfTestUnion"
|
||||
// );
|
||||
// const propertyBeingAssigned = getPropertyBeingAssigned(
|
||||
// instanceVariable,
|
||||
// "f2"
|
||||
// );
|
||||
|
||||
// // Find definition of TestUnion.f2 property
|
||||
// const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0];
|
||||
// const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind(
|
||||
// SyntaxKind.VariableDeclaration
|
||||
// );
|
||||
|
||||
// // Assert that find definition returned the Zod definition of TestUnion
|
||||
// expect(definitionOfProperty?.getText()).toEqual(
|
||||
// "f2: z.string().optional()"
|
||||
// );
|
||||
// expect(parentOfProperty?.getName()).toEqual("TestUnion");
|
||||
// });
|
||||
|
||||
// test("works for object properties inferred from z.object().partial()", () => {
|
||||
// // Find usage of TestPartial.f1 property
|
||||
// const instanceVariable = sourceFile.getVariableDeclarationOrThrow(
|
||||
// "instanceOfTestPartial"
|
||||
// );
|
||||
// const propertyBeingAssigned = getPropertyBeingAssigned(
|
||||
// instanceVariable,
|
||||
// "f1"
|
||||
// );
|
||||
|
||||
// // Find definition of TestPartial.f1 property
|
||||
// const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0];
|
||||
// const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind(
|
||||
// SyntaxKind.VariableDeclaration
|
||||
// );
|
||||
|
||||
// // Assert that find definition returned the Zod definition of Test
|
||||
// expect(definitionOfProperty?.getText()).toEqual("f1: z.number()");
|
||||
// expect(parentOfProperty?.getName()).toEqual("Test");
|
||||
// });
|
||||
|
||||
// test("works for object properties inferred from z.object().pick()", () => {
|
||||
// // Find usage of TestPick.f1 property
|
||||
// const instanceVariable =
|
||||
// sourceFile.getVariableDeclarationOrThrow("instanceOfTestPick");
|
||||
// const propertyBeingAssigned = getPropertyBeingAssigned(
|
||||
// instanceVariable,
|
||||
// "f1"
|
||||
// );
|
||||
|
||||
// // Find definition of TestPick.f1 property
|
||||
// const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0];
|
||||
// const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind(
|
||||
// SyntaxKind.VariableDeclaration
|
||||
// );
|
||||
|
||||
// // Assert that find definition returned the Zod definition of Test
|
||||
// expect(definitionOfProperty?.getText()).toEqual("f1: z.number()");
|
||||
// expect(parentOfProperty?.getName()).toEqual("Test");
|
||||
// });
|
||||
|
||||
// test("works for object properties inferred from z.object().omit()", () => {
|
||||
// // Find usage of TestOmit.f1 property
|
||||
// const instanceVariable =
|
||||
// sourceFile.getVariableDeclarationOrThrow("instanceOfTestOmit");
|
||||
// const propertyBeingAssigned = getPropertyBeingAssigned(
|
||||
// instanceVariable,
|
||||
// "f1"
|
||||
// );
|
||||
|
||||
// // Find definition of TestOmit.f1 property
|
||||
// const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0];
|
||||
// const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind(
|
||||
// SyntaxKind.VariableDeclaration
|
||||
// );
|
||||
|
||||
// // Assert that find definition returned the Zod definition of Test
|
||||
// expect(definitionOfProperty?.getText()).toEqual("f1: z.number()");
|
||||
// expect(parentOfProperty?.getName()).toEqual("Test");
|
||||
// });
|
||||
// });
|
||||
|
||||
// const getPropertyBeingAssigned = (node: Node, name: string) => {
|
||||
// const propertyAssignment = node.forEachDescendant((descendent) =>
|
||||
// Node.isPropertyAssignment(descendent) && descendent.getName() == name
|
||||
// ? descendent
|
||||
// : undefined
|
||||
// );
|
||||
|
||||
// if (propertyAssignment == null)
|
||||
// fail(`Could not find property assignment with name ${name}`);
|
||||
|
||||
// const propertyLiteral = propertyAssignment.getFirstDescendantByKind(
|
||||
// SyntaxKind.Identifier
|
||||
// );
|
||||
|
||||
// if (propertyLiteral == null)
|
||||
// fail(`Could not find property literal with name ${name}`);
|
||||
|
||||
// return propertyLiteral;
|
||||
// };
|
36
node_modules/zod/src/v3/tests/literal.test.ts
generated
vendored
Normal file
36
node_modules/zod/src/v3/tests/literal.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
const literalTuna = z.literal("tuna");
|
||||
const literalFortyTwo = z.literal(42);
|
||||
const literalTrue = z.literal(true);
|
||||
|
||||
const terrificSymbol = Symbol("terrific");
|
||||
const literalTerrificSymbol = z.literal(terrificSymbol);
|
||||
|
||||
test("passing validations", () => {
|
||||
literalTuna.parse("tuna");
|
||||
literalFortyTwo.parse(42);
|
||||
literalTrue.parse(true);
|
||||
literalTerrificSymbol.parse(terrificSymbol);
|
||||
});
|
||||
|
||||
test("failing validations", () => {
|
||||
expect(() => literalTuna.parse("shark")).toThrow();
|
||||
expect(() => literalFortyTwo.parse(43)).toThrow();
|
||||
expect(() => literalTrue.parse(false)).toThrow();
|
||||
expect(() => literalTerrificSymbol.parse(Symbol("terrific"))).toThrow();
|
||||
});
|
||||
|
||||
test("invalid_literal should have `received` field with data", () => {
|
||||
const data = "shark";
|
||||
const result = literalTuna.safeParse(data);
|
||||
if (!result.success) {
|
||||
const issue = result.error.issues[0];
|
||||
if (issue.code === "invalid_literal") {
|
||||
expect(issue.received).toBe(data);
|
||||
}
|
||||
}
|
||||
});
|
110
node_modules/zod/src/v3/tests/map.test.ts
generated
vendored
Normal file
110
node_modules/zod/src/v3/tests/map.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { ZodIssueCode } from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
const stringMap = z.map(z.string(), z.string());
|
||||
type stringMap = z.infer<typeof stringMap>;
|
||||
|
||||
test("type inference", () => {
|
||||
util.assertEqual<stringMap, Map<string, string>>(true);
|
||||
});
|
||||
|
||||
test("valid parse", () => {
|
||||
const result = stringMap.safeParse(
|
||||
new Map([
|
||||
["first", "foo"],
|
||||
["second", "bar"],
|
||||
])
|
||||
);
|
||||
expect(result.success).toEqual(true);
|
||||
if (result.success) {
|
||||
expect(result.data.has("first")).toEqual(true);
|
||||
expect(result.data.has("second")).toEqual(true);
|
||||
expect(result.data.get("first")).toEqual("foo");
|
||||
expect(result.data.get("second")).toEqual("bar");
|
||||
}
|
||||
});
|
||||
|
||||
test("valid parse async", async () => {
|
||||
const result = await stringMap.spa(
|
||||
new Map([
|
||||
["first", "foo"],
|
||||
["second", "bar"],
|
||||
])
|
||||
);
|
||||
expect(result.success).toEqual(true);
|
||||
if (result.success) {
|
||||
expect(result.data.has("first")).toEqual(true);
|
||||
expect(result.data.has("second")).toEqual(true);
|
||||
expect(result.data.get("first")).toEqual("foo");
|
||||
expect(result.data.get("second")).toEqual("bar");
|
||||
}
|
||||
});
|
||||
|
||||
test("throws when a Set is given", () => {
|
||||
const result = stringMap.safeParse(new Set([]));
|
||||
expect(result.success).toEqual(false);
|
||||
if (result.success === false) {
|
||||
expect(result.error.issues.length).toEqual(1);
|
||||
expect(result.error.issues[0].code).toEqual(ZodIssueCode.invalid_type);
|
||||
}
|
||||
});
|
||||
|
||||
test("throws when the given map has invalid key and invalid input", () => {
|
||||
const result = stringMap.safeParse(new Map([[42, Symbol()]]));
|
||||
expect(result.success).toEqual(false);
|
||||
if (result.success === false) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
expect(result.error.issues[0].code).toEqual(ZodIssueCode.invalid_type);
|
||||
expect(result.error.issues[0].path).toEqual([0, "key"]);
|
||||
expect(result.error.issues[1].code).toEqual(ZodIssueCode.invalid_type);
|
||||
expect(result.error.issues[1].path).toEqual([0, "value"]);
|
||||
}
|
||||
});
|
||||
|
||||
test("throws when the given map has multiple invalid entries", () => {
|
||||
// const result = stringMap.safeParse(new Map([[42, Symbol()]]));
|
||||
|
||||
const result = stringMap.safeParse(
|
||||
new Map([
|
||||
[1, "foo"],
|
||||
["bar", 2],
|
||||
] as [any, any][]) as Map<any, any>
|
||||
);
|
||||
|
||||
// const result = stringMap.safeParse(new Map([[42, Symbol()]]));
|
||||
expect(result.success).toEqual(false);
|
||||
if (result.success === false) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
expect(result.error.issues[0].code).toEqual(ZodIssueCode.invalid_type);
|
||||
expect(result.error.issues[0].path).toEqual([0, "key"]);
|
||||
expect(result.error.issues[1].code).toEqual(ZodIssueCode.invalid_type);
|
||||
expect(result.error.issues[1].path).toEqual([1, "value"]);
|
||||
}
|
||||
});
|
||||
|
||||
test("dirty", async () => {
|
||||
const map = z.map(
|
||||
z.string().refine((val) => val === val.toUpperCase(), {
|
||||
message: "Keys must be uppercase",
|
||||
}),
|
||||
z.string()
|
||||
);
|
||||
const result = await map.spa(
|
||||
new Map([
|
||||
["first", "foo"],
|
||||
["second", "bar"],
|
||||
])
|
||||
);
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
expect(result.error.issues[0].code).toEqual(z.ZodIssueCode.custom);
|
||||
expect(result.error.issues[0].message).toEqual("Keys must be uppercase");
|
||||
expect(result.error.issues[1].code).toEqual(z.ZodIssueCode.custom);
|
||||
expect(result.error.issues[1].message).toEqual("Keys must be uppercase");
|
||||
}
|
||||
});
|
4
node_modules/zod/src/v3/tests/masking.test.ts
generated
vendored
Normal file
4
node_modules/zod/src/v3/tests/masking.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
// @ts-ignore TS6133
|
||||
import { test } from "vitest";
|
||||
|
||||
test("masking test", () => {});
|
19
node_modules/zod/src/v3/tests/mocker.test.ts
generated
vendored
Normal file
19
node_modules/zod/src/v3/tests/mocker.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
// @ts-ignore TS6133
|
||||
import { test } from "vitest";
|
||||
|
||||
import { Mocker } from "./Mocker.js";
|
||||
|
||||
test("mocker", () => {
|
||||
const mocker = new Mocker();
|
||||
mocker.string;
|
||||
mocker.number;
|
||||
mocker.boolean;
|
||||
mocker.null;
|
||||
mocker.undefined;
|
||||
mocker.stringOptional;
|
||||
mocker.stringNullable;
|
||||
mocker.numberOptional;
|
||||
mocker.numberNullable;
|
||||
mocker.booleanOptional;
|
||||
mocker.booleanNullable;
|
||||
});
|
21
node_modules/zod/src/v3/tests/nan.test.ts
generated
vendored
Normal file
21
node_modules/zod/src/v3/tests/nan.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
const schema = z.nan();
|
||||
|
||||
test("passing validations", () => {
|
||||
schema.parse(Number.NaN);
|
||||
schema.parse(Number("Not a number"));
|
||||
});
|
||||
|
||||
test("failing validations", () => {
|
||||
expect(() => schema.parse(5)).toThrow();
|
||||
expect(() => schema.parse("John")).toThrow();
|
||||
expect(() => schema.parse(true)).toThrow();
|
||||
expect(() => schema.parse(null)).toThrow();
|
||||
expect(() => schema.parse(undefined)).toThrow();
|
||||
expect(() => schema.parse({})).toThrow();
|
||||
expect(() => schema.parse([])).toThrow();
|
||||
});
|
87
node_modules/zod/src/v3/tests/nativeEnum.test.ts
generated
vendored
Normal file
87
node_modules/zod/src/v3/tests/nativeEnum.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("nativeEnum test with consts", () => {
|
||||
const Fruits: { Apple: "apple"; Banana: "banana" } = {
|
||||
Apple: "apple",
|
||||
Banana: "banana",
|
||||
};
|
||||
const fruitEnum = z.nativeEnum(Fruits);
|
||||
type fruitEnum = z.infer<typeof fruitEnum>;
|
||||
fruitEnum.parse("apple");
|
||||
fruitEnum.parse("banana");
|
||||
fruitEnum.parse(Fruits.Apple);
|
||||
fruitEnum.parse(Fruits.Banana);
|
||||
util.assertEqual<fruitEnum, "apple" | "banana">(true);
|
||||
});
|
||||
|
||||
test("nativeEnum test with real enum", () => {
|
||||
enum Fruits {
|
||||
Apple = "apple",
|
||||
Banana = "banana",
|
||||
}
|
||||
// @ts-ignore
|
||||
const fruitEnum = z.nativeEnum(Fruits);
|
||||
type fruitEnum = z.infer<typeof fruitEnum>;
|
||||
fruitEnum.parse("apple");
|
||||
fruitEnum.parse("banana");
|
||||
fruitEnum.parse(Fruits.Apple);
|
||||
fruitEnum.parse(Fruits.Banana);
|
||||
util.assertIs<fruitEnum extends Fruits ? true : false>(true);
|
||||
});
|
||||
|
||||
test("nativeEnum test with const with numeric keys", () => {
|
||||
const FruitValues = {
|
||||
Apple: 10,
|
||||
Banana: 20,
|
||||
// @ts-ignore
|
||||
} as const;
|
||||
const fruitEnum = z.nativeEnum(FruitValues);
|
||||
type fruitEnum = z.infer<typeof fruitEnum>;
|
||||
fruitEnum.parse(10);
|
||||
fruitEnum.parse(20);
|
||||
fruitEnum.parse(FruitValues.Apple);
|
||||
fruitEnum.parse(FruitValues.Banana);
|
||||
util.assertEqual<fruitEnum, 10 | 20>(true);
|
||||
});
|
||||
|
||||
test("from enum", () => {
|
||||
enum Fruits {
|
||||
Cantaloupe = 0,
|
||||
Apple = "apple",
|
||||
Banana = "banana",
|
||||
}
|
||||
|
||||
const FruitEnum = z.nativeEnum(Fruits as any);
|
||||
type _FruitEnum = z.infer<typeof FruitEnum>;
|
||||
FruitEnum.parse(Fruits.Cantaloupe);
|
||||
FruitEnum.parse(Fruits.Apple);
|
||||
FruitEnum.parse("apple");
|
||||
FruitEnum.parse(0);
|
||||
expect(() => FruitEnum.parse(1)).toThrow();
|
||||
expect(() => FruitEnum.parse("Apple")).toThrow();
|
||||
expect(() => FruitEnum.parse("Cantaloupe")).toThrow();
|
||||
});
|
||||
|
||||
test("from const", () => {
|
||||
const Greek = {
|
||||
Alpha: "a",
|
||||
Beta: "b",
|
||||
Gamma: 3,
|
||||
// @ts-ignore
|
||||
} as const;
|
||||
|
||||
const GreekEnum = z.nativeEnum(Greek);
|
||||
type _GreekEnum = z.infer<typeof GreekEnum>;
|
||||
GreekEnum.parse("a");
|
||||
GreekEnum.parse("b");
|
||||
GreekEnum.parse(3);
|
||||
expect(() => GreekEnum.parse("v")).toThrow();
|
||||
expect(() => GreekEnum.parse("Alpha")).toThrow();
|
||||
expect(() => GreekEnum.parse(2)).toThrow();
|
||||
|
||||
expect(GreekEnum.enum.Alpha).toEqual("a");
|
||||
});
|
42
node_modules/zod/src/v3/tests/nullable.test.ts
generated
vendored
Normal file
42
node_modules/zod/src/v3/tests/nullable.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
function checkErrors(a: z.ZodTypeAny, bad: any) {
|
||||
let expected: any;
|
||||
try {
|
||||
a.parse(bad);
|
||||
} catch (error) {
|
||||
expected = (error as z.ZodError).formErrors;
|
||||
}
|
||||
try {
|
||||
a.nullable().parse(bad);
|
||||
} catch (error) {
|
||||
expect((error as z.ZodError).formErrors).toEqual(expected);
|
||||
}
|
||||
}
|
||||
|
||||
test("Should have error messages appropriate for the underlying type", () => {
|
||||
checkErrors(z.string().min(2), 1);
|
||||
z.string().min(2).nullable().parse(null);
|
||||
checkErrors(z.number().gte(2), 1);
|
||||
z.number().gte(2).nullable().parse(null);
|
||||
checkErrors(z.boolean(), "");
|
||||
z.boolean().nullable().parse(null);
|
||||
checkErrors(z.null(), null);
|
||||
z.null().nullable().parse(null);
|
||||
checkErrors(z.null(), {});
|
||||
z.null().nullable().parse(null);
|
||||
checkErrors(z.object({}), 1);
|
||||
z.object({}).nullable().parse(null);
|
||||
checkErrors(z.tuple([]), 1);
|
||||
z.tuple([]).nullable().parse(null);
|
||||
checkErrors(z.unknown(), 1);
|
||||
z.unknown().nullable().parse(null);
|
||||
});
|
||||
|
||||
test("unwrap", () => {
|
||||
const unwrapped = z.string().nullable().unwrap();
|
||||
expect(unwrapped).toBeInstanceOf(z.ZodString);
|
||||
});
|
176
node_modules/zod/src/v3/tests/number.test.ts
generated
vendored
Normal file
176
node_modules/zod/src/v3/tests/number.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
const gtFive = z.number().gt(5);
|
||||
const gteFive = z.number().gte(-5).gte(5);
|
||||
const minFive = z.number().min(0).min(5);
|
||||
const ltFive = z.number().lte(10).lt(5);
|
||||
const lteFive = z.number().lte(5);
|
||||
const maxFive = z.number().max(10).max(5);
|
||||
const intNum = z.number().int();
|
||||
const positive = z.number().positive();
|
||||
const negative = z.number().negative();
|
||||
const nonpositive = z.number().nonpositive();
|
||||
const nonnegative = z.number().nonnegative();
|
||||
const multipleOfFive = z.number().multipleOf(5);
|
||||
const multipleOfNegativeFive = z.number().multipleOf(-5);
|
||||
const finite = z.number().finite();
|
||||
const safe = z.number().safe();
|
||||
const stepPointOne = z.number().step(0.1);
|
||||
const stepPointZeroZeroZeroOne = z.number().step(0.0001);
|
||||
const stepSixPointFour = z.number().step(6.4);
|
||||
|
||||
test("passing validations", () => {
|
||||
z.number().parse(1);
|
||||
z.number().parse(1.5);
|
||||
z.number().parse(0);
|
||||
z.number().parse(-1.5);
|
||||
z.number().parse(-1);
|
||||
z.number().parse(Number.POSITIVE_INFINITY);
|
||||
z.number().parse(Number.NEGATIVE_INFINITY);
|
||||
gtFive.parse(6);
|
||||
gtFive.parse(Number.POSITIVE_INFINITY);
|
||||
gteFive.parse(5);
|
||||
gteFive.parse(Number.POSITIVE_INFINITY);
|
||||
minFive.parse(5);
|
||||
minFive.parse(Number.POSITIVE_INFINITY);
|
||||
ltFive.parse(4);
|
||||
ltFive.parse(Number.NEGATIVE_INFINITY);
|
||||
lteFive.parse(5);
|
||||
lteFive.parse(Number.NEGATIVE_INFINITY);
|
||||
maxFive.parse(5);
|
||||
maxFive.parse(Number.NEGATIVE_INFINITY);
|
||||
intNum.parse(4);
|
||||
positive.parse(1);
|
||||
positive.parse(Number.POSITIVE_INFINITY);
|
||||
negative.parse(-1);
|
||||
negative.parse(Number.NEGATIVE_INFINITY);
|
||||
nonpositive.parse(0);
|
||||
nonpositive.parse(-1);
|
||||
nonpositive.parse(Number.NEGATIVE_INFINITY);
|
||||
nonnegative.parse(0);
|
||||
nonnegative.parse(1);
|
||||
nonnegative.parse(Number.POSITIVE_INFINITY);
|
||||
multipleOfFive.parse(15);
|
||||
multipleOfFive.parse(-15);
|
||||
multipleOfNegativeFive.parse(-15);
|
||||
multipleOfNegativeFive.parse(15);
|
||||
finite.parse(123);
|
||||
safe.parse(Number.MIN_SAFE_INTEGER);
|
||||
safe.parse(Number.MAX_SAFE_INTEGER);
|
||||
stepPointOne.parse(6);
|
||||
stepPointOne.parse(6.1);
|
||||
stepPointOne.parse(6.1);
|
||||
stepSixPointFour.parse(12.8);
|
||||
stepPointZeroZeroZeroOne.parse(3.01);
|
||||
});
|
||||
|
||||
test("failing validations", () => {
|
||||
expect(() => ltFive.parse(5)).toThrow();
|
||||
expect(() => lteFive.parse(6)).toThrow();
|
||||
expect(() => maxFive.parse(6)).toThrow();
|
||||
expect(() => gtFive.parse(5)).toThrow();
|
||||
expect(() => gteFive.parse(4)).toThrow();
|
||||
expect(() => minFive.parse(4)).toThrow();
|
||||
expect(() => intNum.parse(3.14)).toThrow();
|
||||
expect(() => positive.parse(0)).toThrow();
|
||||
expect(() => positive.parse(-1)).toThrow();
|
||||
expect(() => negative.parse(0)).toThrow();
|
||||
expect(() => negative.parse(1)).toThrow();
|
||||
expect(() => nonpositive.parse(1)).toThrow();
|
||||
expect(() => nonnegative.parse(-1)).toThrow();
|
||||
expect(() => multipleOfFive.parse(7.5)).toThrow();
|
||||
expect(() => multipleOfFive.parse(-7.5)).toThrow();
|
||||
expect(() => multipleOfNegativeFive.parse(-7.5)).toThrow();
|
||||
expect(() => multipleOfNegativeFive.parse(7.5)).toThrow();
|
||||
expect(() => finite.parse(Number.POSITIVE_INFINITY)).toThrow();
|
||||
expect(() => finite.parse(Number.NEGATIVE_INFINITY)).toThrow();
|
||||
expect(() => safe.parse(Number.MIN_SAFE_INTEGER - 1)).toThrow();
|
||||
expect(() => safe.parse(Number.MAX_SAFE_INTEGER + 1)).toThrow();
|
||||
|
||||
expect(() => stepPointOne.parse(6.11)).toThrow();
|
||||
expect(() => stepPointOne.parse(6.1000000001)).toThrow();
|
||||
expect(() => stepSixPointFour.parse(6.41)).toThrow();
|
||||
});
|
||||
|
||||
test("parse NaN", () => {
|
||||
expect(() => z.number().parse(Number.NaN)).toThrow();
|
||||
});
|
||||
|
||||
test("min max getters", () => {
|
||||
expect(z.number().minValue).toBeNull;
|
||||
expect(ltFive.minValue).toBeNull;
|
||||
expect(lteFive.minValue).toBeNull;
|
||||
expect(maxFive.minValue).toBeNull;
|
||||
expect(negative.minValue).toBeNull;
|
||||
expect(nonpositive.minValue).toBeNull;
|
||||
expect(intNum.minValue).toBeNull;
|
||||
expect(multipleOfFive.minValue).toBeNull;
|
||||
expect(finite.minValue).toBeNull;
|
||||
expect(gtFive.minValue).toEqual(5);
|
||||
expect(gteFive.minValue).toEqual(5);
|
||||
expect(minFive.minValue).toEqual(5);
|
||||
expect(minFive.min(10).minValue).toEqual(10);
|
||||
expect(positive.minValue).toEqual(0);
|
||||
expect(nonnegative.minValue).toEqual(0);
|
||||
expect(safe.minValue).toEqual(Number.MIN_SAFE_INTEGER);
|
||||
|
||||
expect(z.number().maxValue).toBeNull;
|
||||
expect(gtFive.maxValue).toBeNull;
|
||||
expect(gteFive.maxValue).toBeNull;
|
||||
expect(minFive.maxValue).toBeNull;
|
||||
expect(positive.maxValue).toBeNull;
|
||||
expect(nonnegative.maxValue).toBeNull;
|
||||
expect(intNum.minValue).toBeNull;
|
||||
expect(multipleOfFive.minValue).toBeNull;
|
||||
expect(finite.minValue).toBeNull;
|
||||
expect(ltFive.maxValue).toEqual(5);
|
||||
expect(lteFive.maxValue).toEqual(5);
|
||||
expect(maxFive.maxValue).toEqual(5);
|
||||
expect(maxFive.max(1).maxValue).toEqual(1);
|
||||
expect(negative.maxValue).toEqual(0);
|
||||
expect(nonpositive.maxValue).toEqual(0);
|
||||
expect(safe.maxValue).toEqual(Number.MAX_SAFE_INTEGER);
|
||||
});
|
||||
|
||||
test("int getter", () => {
|
||||
expect(z.number().isInt).toEqual(false);
|
||||
expect(z.number().multipleOf(1.5).isInt).toEqual(false);
|
||||
expect(gtFive.isInt).toEqual(false);
|
||||
expect(gteFive.isInt).toEqual(false);
|
||||
expect(minFive.isInt).toEqual(false);
|
||||
expect(positive.isInt).toEqual(false);
|
||||
expect(nonnegative.isInt).toEqual(false);
|
||||
expect(finite.isInt).toEqual(false);
|
||||
expect(ltFive.isInt).toEqual(false);
|
||||
expect(lteFive.isInt).toEqual(false);
|
||||
expect(maxFive.isInt).toEqual(false);
|
||||
expect(negative.isInt).toEqual(false);
|
||||
expect(nonpositive.isInt).toEqual(false);
|
||||
expect(safe.isInt).toEqual(false);
|
||||
|
||||
expect(intNum.isInt).toEqual(true);
|
||||
expect(multipleOfFive.isInt).toEqual(true);
|
||||
});
|
||||
|
||||
test("finite getter", () => {
|
||||
expect(z.number().isFinite).toEqual(false);
|
||||
expect(gtFive.isFinite).toEqual(false);
|
||||
expect(gteFive.isFinite).toEqual(false);
|
||||
expect(minFive.isFinite).toEqual(false);
|
||||
expect(positive.isFinite).toEqual(false);
|
||||
expect(nonnegative.isFinite).toEqual(false);
|
||||
expect(ltFive.isFinite).toEqual(false);
|
||||
expect(lteFive.isFinite).toEqual(false);
|
||||
expect(maxFive.isFinite).toEqual(false);
|
||||
expect(negative.isFinite).toEqual(false);
|
||||
expect(nonpositive.isFinite).toEqual(false);
|
||||
|
||||
expect(finite.isFinite).toEqual(true);
|
||||
expect(intNum.isFinite).toEqual(true);
|
||||
expect(multipleOfFive.isFinite).toEqual(true);
|
||||
expect(z.number().min(5).max(10).isFinite).toEqual(true);
|
||||
expect(safe.isFinite).toEqual(true);
|
||||
});
|
29
node_modules/zod/src/v3/tests/object-augmentation.test.ts
generated
vendored
Normal file
29
node_modules/zod/src/v3/tests/object-augmentation.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
test("object augmentation", () => {
|
||||
const Animal = z
|
||||
.object({
|
||||
species: z.string(),
|
||||
})
|
||||
.augment({
|
||||
population: z.number(),
|
||||
});
|
||||
// overwrites `species`
|
||||
const ModifiedAnimal = Animal.augment({
|
||||
species: z.array(z.string()),
|
||||
});
|
||||
ModifiedAnimal.parse({
|
||||
species: ["asd"],
|
||||
population: 1324,
|
||||
});
|
||||
|
||||
const bad = () =>
|
||||
ModifiedAnimal.parse({
|
||||
species: "asdf",
|
||||
population: 1324,
|
||||
} as any);
|
||||
expect(bad).toThrow();
|
||||
});
|
29
node_modules/zod/src/v3/tests/object-in-es5-env.test.ts
generated
vendored
Normal file
29
node_modules/zod/src/v3/tests/object-in-es5-env.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
const RealSet = Set;
|
||||
const RealMap = Map;
|
||||
const RealDate = Date;
|
||||
|
||||
test("doesn’t throw when Date is undefined", () => {
|
||||
delete (globalThis as any).Date;
|
||||
const result = z.object({}).safeParse({});
|
||||
expect(result.success).toEqual(true);
|
||||
globalThis.Date = RealDate;
|
||||
});
|
||||
|
||||
test("doesn’t throw when Set is undefined", () => {
|
||||
delete (globalThis as any).Set;
|
||||
const result = z.object({}).safeParse({});
|
||||
expect(result.success).toEqual(true);
|
||||
globalThis.Set = RealSet;
|
||||
});
|
||||
|
||||
test("doesn’t throw when Map is undefined", () => {
|
||||
delete (globalThis as any).Map;
|
||||
const result = z.object({}).safeParse({});
|
||||
expect(result.success).toEqual(true);
|
||||
globalThis.Map = RealMap;
|
||||
});
|
434
node_modules/zod/src/v3/tests/object.test.ts
generated
vendored
Normal file
434
node_modules/zod/src/v3/tests/object.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,434 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
const Test = z.object({
|
||||
f1: z.number(),
|
||||
f2: z.string().optional(),
|
||||
f3: z.string().nullable(),
|
||||
f4: z.array(z.object({ t: z.union([z.string(), z.boolean()]) })),
|
||||
});
|
||||
|
||||
test("object type inference", () => {
|
||||
type TestType = {
|
||||
f1: number;
|
||||
f2?: string | undefined;
|
||||
f3: string | null;
|
||||
f4: { t: string | boolean }[];
|
||||
};
|
||||
|
||||
util.assertEqual<z.TypeOf<typeof Test>, TestType>(true);
|
||||
});
|
||||
|
||||
test("unknown throw", () => {
|
||||
const asdf: unknown = 35;
|
||||
expect(() => Test.parse(asdf)).toThrow();
|
||||
});
|
||||
|
||||
test("shape() should return schema of particular key", () => {
|
||||
const f1Schema = Test.shape.f1;
|
||||
const f2Schema = Test.shape.f2;
|
||||
const f3Schema = Test.shape.f3;
|
||||
const f4Schema = Test.shape.f4;
|
||||
|
||||
expect(f1Schema).toBeInstanceOf(z.ZodNumber);
|
||||
expect(f2Schema).toBeInstanceOf(z.ZodOptional);
|
||||
expect(f3Schema).toBeInstanceOf(z.ZodNullable);
|
||||
expect(f4Schema).toBeInstanceOf(z.ZodArray);
|
||||
});
|
||||
|
||||
test("correct parsing", () => {
|
||||
Test.parse({
|
||||
f1: 12,
|
||||
f2: "string",
|
||||
f3: "string",
|
||||
f4: [
|
||||
{
|
||||
t: "string",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
Test.parse({
|
||||
f1: 12,
|
||||
f3: null,
|
||||
f4: [
|
||||
{
|
||||
t: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test("incorrect #1", () => {
|
||||
expect(() => Test.parse({} as any)).toThrow();
|
||||
});
|
||||
|
||||
test("nonstrict by default", () => {
|
||||
z.object({ points: z.number() }).parse({
|
||||
points: 2314,
|
||||
unknown: "asdf",
|
||||
});
|
||||
});
|
||||
|
||||
const data = {
|
||||
points: 2314,
|
||||
unknown: "asdf",
|
||||
};
|
||||
|
||||
test("strip by default", () => {
|
||||
const val = z.object({ points: z.number() }).parse(data);
|
||||
expect(val).toEqual({ points: 2314 });
|
||||
});
|
||||
|
||||
test("unknownkeys override", () => {
|
||||
const val = z.object({ points: z.number() }).strict().passthrough().strip().nonstrict().parse(data);
|
||||
|
||||
expect(val).toEqual(data);
|
||||
});
|
||||
|
||||
test("passthrough unknown", () => {
|
||||
const val = z.object({ points: z.number() }).passthrough().parse(data);
|
||||
|
||||
expect(val).toEqual(data);
|
||||
});
|
||||
|
||||
test("strip unknown", () => {
|
||||
const val = z.object({ points: z.number() }).strip().parse(data);
|
||||
|
||||
expect(val).toEqual({ points: 2314 });
|
||||
});
|
||||
|
||||
test("strict", () => {
|
||||
const val = z.object({ points: z.number() }).strict().safeParse(data);
|
||||
|
||||
expect(val.success).toEqual(false);
|
||||
});
|
||||
|
||||
test("catchall inference", () => {
|
||||
const o1 = z
|
||||
.object({
|
||||
first: z.string(),
|
||||
})
|
||||
.catchall(z.number());
|
||||
|
||||
const d1 = o1.parse({ first: "asdf", num: 1243 });
|
||||
util.assertEqual<number, (typeof d1)["asdf"]>(true);
|
||||
util.assertEqual<string, (typeof d1)["first"]>(true);
|
||||
});
|
||||
|
||||
test("catchall overrides strict", () => {
|
||||
const o1 = z.object({ first: z.string().optional() }).strict().catchall(z.number());
|
||||
|
||||
// should run fine
|
||||
// setting a catchall overrides the unknownKeys behavior
|
||||
o1.parse({
|
||||
asdf: 1234,
|
||||
});
|
||||
|
||||
// should only run catchall validation
|
||||
// against unknown keys
|
||||
o1.parse({
|
||||
first: "asdf",
|
||||
asdf: 1234,
|
||||
});
|
||||
});
|
||||
|
||||
test("catchall overrides strict", () => {
|
||||
const o1 = z
|
||||
.object({
|
||||
first: z.string(),
|
||||
})
|
||||
.strict()
|
||||
.catchall(z.number());
|
||||
|
||||
// should run fine
|
||||
// setting a catchall overrides the unknownKeys behavior
|
||||
o1.parse({
|
||||
first: "asdf",
|
||||
asdf: 1234,
|
||||
});
|
||||
});
|
||||
|
||||
test("test that optional keys are unset", async () => {
|
||||
const SNamedEntity = z.object({
|
||||
id: z.string(),
|
||||
set: z.string().optional(),
|
||||
unset: z.string().optional(),
|
||||
});
|
||||
const result = await SNamedEntity.parse({
|
||||
id: "asdf",
|
||||
set: undefined,
|
||||
});
|
||||
// eslint-disable-next-line ban/ban
|
||||
expect(Object.keys(result)).toEqual(["id", "set"]);
|
||||
});
|
||||
|
||||
test("test catchall parsing", async () => {
|
||||
const result = z.object({ name: z.string() }).catchall(z.number()).parse({ name: "Foo", validExtraKey: 61 });
|
||||
|
||||
expect(result).toEqual({ name: "Foo", validExtraKey: 61 });
|
||||
|
||||
const result2 = z
|
||||
.object({ name: z.string() })
|
||||
.catchall(z.number())
|
||||
.safeParse({ name: "Foo", validExtraKey: 61, invalid: "asdf" });
|
||||
|
||||
expect(result2.success).toEqual(false);
|
||||
});
|
||||
|
||||
test("test nonexistent keys", async () => {
|
||||
const Schema = z.union([z.object({ a: z.string() }), z.object({ b: z.number() })]);
|
||||
const obj = { a: "A" };
|
||||
const result = await Schema.spa(obj); // Works with 1.11.10, breaks with 2.0.0-beta.21
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
test("test async union", async () => {
|
||||
const Schema2 = z.union([
|
||||
z.object({
|
||||
ty: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
ty: z.number(),
|
||||
}),
|
||||
]);
|
||||
|
||||
const obj = { ty: "A" };
|
||||
const result = await Schema2.spa(obj); // Works with 1.11.10, breaks with 2.0.0-beta.21
|
||||
expect(result.success).toEqual(true);
|
||||
});
|
||||
|
||||
test("test inferred merged type", async () => {
|
||||
const asdf = z.object({ a: z.string() }).merge(z.object({ a: z.number() }));
|
||||
type asdf = z.infer<typeof asdf>;
|
||||
util.assertEqual<asdf, { a: number }>(true);
|
||||
});
|
||||
|
||||
test("inferred merged object type with optional properties", async () => {
|
||||
const Merged = z
|
||||
.object({ a: z.string(), b: z.string().optional() })
|
||||
.merge(z.object({ a: z.string().optional(), b: z.string() }));
|
||||
type Merged = z.infer<typeof Merged>;
|
||||
util.assertEqual<Merged, { a?: string; b: string }>(true);
|
||||
// todo
|
||||
// util.assertEqual<Merged, { a?: string; b: string }>(true);
|
||||
});
|
||||
|
||||
test("inferred unioned object type with optional properties", async () => {
|
||||
const Unioned = z.union([
|
||||
z.object({ a: z.string(), b: z.string().optional() }),
|
||||
z.object({ a: z.string().optional(), b: z.string() }),
|
||||
]);
|
||||
type Unioned = z.infer<typeof Unioned>;
|
||||
util.assertEqual<Unioned, { a: string; b?: string } | { a?: string; b: string }>(true);
|
||||
});
|
||||
|
||||
test("inferred enum type", async () => {
|
||||
const Enum = z.object({ a: z.string(), b: z.string().optional() }).keyof();
|
||||
|
||||
expect(Enum.Values).toEqual({
|
||||
a: "a",
|
||||
b: "b",
|
||||
});
|
||||
expect(Enum.enum).toEqual({
|
||||
a: "a",
|
||||
b: "b",
|
||||
});
|
||||
expect(Enum._def.values).toEqual(["a", "b"]);
|
||||
type Enum = z.infer<typeof Enum>;
|
||||
util.assertEqual<Enum, "a" | "b">(true);
|
||||
});
|
||||
|
||||
test("inferred partial object type with optional properties", async () => {
|
||||
const Partial = z.object({ a: z.string(), b: z.string().optional() }).partial();
|
||||
type Partial = z.infer<typeof Partial>;
|
||||
util.assertEqual<Partial, { a?: string; b?: string }>(true);
|
||||
});
|
||||
|
||||
test("inferred picked object type with optional properties", async () => {
|
||||
const Picked = z.object({ a: z.string(), b: z.string().optional() }).pick({ b: true });
|
||||
type Picked = z.infer<typeof Picked>;
|
||||
util.assertEqual<Picked, { b?: string }>(true);
|
||||
});
|
||||
|
||||
test("inferred type for unknown/any keys", () => {
|
||||
const myType = z.object({
|
||||
anyOptional: z.any().optional(),
|
||||
anyRequired: z.any(),
|
||||
unknownOptional: z.unknown().optional(),
|
||||
unknownRequired: z.unknown(),
|
||||
});
|
||||
type myType = z.infer<typeof myType>;
|
||||
util.assertEqual<
|
||||
myType,
|
||||
{
|
||||
anyOptional?: any;
|
||||
anyRequired?: any;
|
||||
unknownOptional?: unknown;
|
||||
unknownRequired?: unknown;
|
||||
}
|
||||
>(true);
|
||||
});
|
||||
|
||||
test("setKey", () => {
|
||||
const base = z.object({ name: z.string() });
|
||||
const withNewKey = base.setKey("age", z.number());
|
||||
|
||||
type withNewKey = z.infer<typeof withNewKey>;
|
||||
util.assertEqual<withNewKey, { name: string; age: number }>(true);
|
||||
withNewKey.parse({ name: "asdf", age: 1234 });
|
||||
});
|
||||
|
||||
test("strictcreate", async () => {
|
||||
const strictObj = z.strictObject({
|
||||
name: z.string(),
|
||||
});
|
||||
|
||||
const syncResult = strictObj.safeParse({ name: "asdf", unexpected: 13 });
|
||||
expect(syncResult.success).toEqual(false);
|
||||
|
||||
const asyncResult = await strictObj.spa({ name: "asdf", unexpected: 13 });
|
||||
expect(asyncResult.success).toEqual(false);
|
||||
});
|
||||
|
||||
test("object with refine", async () => {
|
||||
const schema = z
|
||||
.object({
|
||||
a: z.string().default("foo"),
|
||||
b: z.number(),
|
||||
})
|
||||
.refine(() => true);
|
||||
expect(schema.parse({ b: 5 })).toEqual({ b: 5, a: "foo" });
|
||||
const result = await schema.parseAsync({ b: 5 });
|
||||
expect(result).toEqual({ b: 5, a: "foo" });
|
||||
});
|
||||
|
||||
test("intersection of object with date", async () => {
|
||||
const schema = z.object({
|
||||
a: z.date(),
|
||||
});
|
||||
expect(schema.and(schema).parse({ a: new Date(1637353595983) })).toEqual({
|
||||
a: new Date(1637353595983),
|
||||
});
|
||||
const result = await schema.parseAsync({ a: new Date(1637353595983) });
|
||||
expect(result).toEqual({ a: new Date(1637353595983) });
|
||||
});
|
||||
|
||||
test("intersection of object with refine with date", async () => {
|
||||
const schema = z
|
||||
.object({
|
||||
a: z.date(),
|
||||
})
|
||||
.refine(() => true);
|
||||
expect(schema.and(schema).parse({ a: new Date(1637353595983) })).toEqual({
|
||||
a: new Date(1637353595983),
|
||||
});
|
||||
const result = await schema.parseAsync({ a: new Date(1637353595983) });
|
||||
expect(result).toEqual({ a: new Date(1637353595983) });
|
||||
});
|
||||
|
||||
test("constructor key", () => {
|
||||
const person = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
expect(() =>
|
||||
person.parse({
|
||||
name: "bob dylan",
|
||||
constructor: 61,
|
||||
})
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
test("constructor key", () => {
|
||||
const Example = z.object({
|
||||
prop: z.string(),
|
||||
opt: z.number().optional(),
|
||||
arr: z.string().array(),
|
||||
});
|
||||
|
||||
type Example = z.infer<typeof Example>;
|
||||
util.assertEqual<keyof Example, "prop" | "opt" | "arr">(true);
|
||||
});
|
||||
|
||||
test("unknownkeys merging", () => {
|
||||
// This one is "strict"
|
||||
const schemaA = z
|
||||
.object({
|
||||
a: z.string(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
// This one is "strip"
|
||||
const schemaB = z
|
||||
.object({
|
||||
b: z.string(),
|
||||
})
|
||||
.catchall(z.string());
|
||||
|
||||
const mergedSchema = schemaA.merge(schemaB);
|
||||
type mergedSchema = typeof mergedSchema;
|
||||
util.assertEqual<mergedSchema["_def"]["unknownKeys"], "strip">(true);
|
||||
expect(mergedSchema._def.unknownKeys).toEqual("strip");
|
||||
|
||||
util.assertEqual<mergedSchema["_def"]["catchall"], z.ZodString>(true);
|
||||
expect(mergedSchema._def.catchall instanceof z.ZodString).toEqual(true);
|
||||
});
|
||||
|
||||
const personToExtend = z.object({
|
||||
firstName: z.string(),
|
||||
lastName: z.string(),
|
||||
});
|
||||
|
||||
test("extend() should return schema with new key", () => {
|
||||
const PersonWithNickname = personToExtend.extend({ nickName: z.string() });
|
||||
type PersonWithNickname = z.infer<typeof PersonWithNickname>;
|
||||
|
||||
const expected = { firstName: "f", nickName: "n", lastName: "l" };
|
||||
const actual = PersonWithNickname.parse(expected);
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
util.assertEqual<keyof PersonWithNickname, "firstName" | "lastName" | "nickName">(true);
|
||||
util.assertEqual<PersonWithNickname, { firstName: string; lastName: string; nickName: string }>(true);
|
||||
});
|
||||
|
||||
test("extend() should have power to override existing key", () => {
|
||||
const PersonWithNumberAsLastName = personToExtend.extend({
|
||||
lastName: z.number(),
|
||||
});
|
||||
type PersonWithNumberAsLastName = z.infer<typeof PersonWithNumberAsLastName>;
|
||||
|
||||
const expected = { firstName: "f", lastName: 42 };
|
||||
const actual = PersonWithNumberAsLastName.parse(expected);
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
util.assertEqual<PersonWithNumberAsLastName, { firstName: string; lastName: number }>(true);
|
||||
});
|
||||
|
||||
test("passthrough index signature", () => {
|
||||
const a = z.object({ a: z.string() });
|
||||
type a = z.infer<typeof a>;
|
||||
util.assertEqual<{ a: string }, a>(true);
|
||||
const b = a.passthrough();
|
||||
type b = z.infer<typeof b>;
|
||||
util.assertEqual<{ a: string } & { [k: string]: unknown }, b>(true);
|
||||
});
|
||||
|
||||
test("xor", () => {
|
||||
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
|
||||
type XOR<T, U> = T extends object ? (U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : U) : T;
|
||||
|
||||
type A = { name: string; a: number };
|
||||
type B = { name: string; b: number };
|
||||
type C = XOR<A, B>;
|
||||
type Outer = { data: C };
|
||||
|
||||
const _Outer: z.ZodType<Outer> = z.object({
|
||||
data: z.union([z.object({ name: z.string(), a: z.number() }), z.object({ name: z.string(), b: z.number() })]),
|
||||
});
|
||||
});
|
42
node_modules/zod/src/v3/tests/optional.test.ts
generated
vendored
Normal file
42
node_modules/zod/src/v3/tests/optional.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
function checkErrors(a: z.ZodTypeAny, bad: any) {
|
||||
let expected: any;
|
||||
try {
|
||||
a.parse(bad);
|
||||
} catch (error) {
|
||||
expected = (error as z.ZodError).formErrors;
|
||||
}
|
||||
try {
|
||||
a.optional().parse(bad);
|
||||
} catch (error) {
|
||||
expect((error as z.ZodError).formErrors).toEqual(expected);
|
||||
}
|
||||
}
|
||||
|
||||
test("Should have error messages appropriate for the underlying type", () => {
|
||||
checkErrors(z.string().min(2), 1);
|
||||
z.string().min(2).optional().parse(undefined);
|
||||
checkErrors(z.number().gte(2), 1);
|
||||
z.number().gte(2).optional().parse(undefined);
|
||||
checkErrors(z.boolean(), "");
|
||||
z.boolean().optional().parse(undefined);
|
||||
checkErrors(z.undefined(), null);
|
||||
z.undefined().optional().parse(undefined);
|
||||
checkErrors(z.null(), {});
|
||||
z.null().optional().parse(undefined);
|
||||
checkErrors(z.object({}), 1);
|
||||
z.object({}).optional().parse(undefined);
|
||||
checkErrors(z.tuple([]), 1);
|
||||
z.tuple([]).optional().parse(undefined);
|
||||
checkErrors(z.unknown(), 1);
|
||||
z.unknown().optional().parse(undefined);
|
||||
});
|
||||
|
||||
test("unwrap", () => {
|
||||
const unwrapped = z.string().optional().unwrap();
|
||||
expect(unwrapped).toBeInstanceOf(z.ZodString);
|
||||
});
|
23
node_modules/zod/src/v3/tests/parseUtil.test.ts
generated
vendored
Normal file
23
node_modules/zod/src/v3/tests/parseUtil.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import { type SyncParseReturnType, isAborted, isDirty, isValid } from "../helpers/parseUtil.js";
|
||||
|
||||
test("parseUtil isInvalid should use structural typing", () => {
|
||||
// Test for issue #556: https://github.com/colinhacks/zod/issues/556
|
||||
const aborted: SyncParseReturnType = { status: "aborted" };
|
||||
const dirty: SyncParseReturnType = { status: "dirty", value: "whatever" };
|
||||
const valid: SyncParseReturnType = { status: "valid", value: "whatever" };
|
||||
|
||||
expect(isAborted(aborted)).toBe(true);
|
||||
expect(isAborted(dirty)).toBe(false);
|
||||
expect(isAborted(valid)).toBe(false);
|
||||
|
||||
expect(isDirty(aborted)).toBe(false);
|
||||
expect(isDirty(dirty)).toBe(true);
|
||||
expect(isDirty(valid)).toBe(false);
|
||||
|
||||
expect(isValid(aborted)).toBe(false);
|
||||
expect(isValid(dirty)).toBe(false);
|
||||
expect(isValid(valid)).toBe(true);
|
||||
});
|
41
node_modules/zod/src/v3/tests/parser.test.ts
generated
vendored
Normal file
41
node_modules/zod/src/v3/tests/parser.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
test("parse strict object with unknown keys", () => {
|
||||
expect(() =>
|
||||
z
|
||||
.object({ name: z.string() })
|
||||
.strict()
|
||||
.parse({ name: "bill", unknownKey: 12 } as any)
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
test("parse nonstrict object with unknown keys", () => {
|
||||
z.object({ name: z.string() }).nonstrict().parse({ name: "bill", unknownKey: 12 });
|
||||
});
|
||||
|
||||
test("invalid left side of intersection", () => {
|
||||
expect(() => z.intersection(z.string(), z.number()).parse(12 as any)).toThrow();
|
||||
});
|
||||
|
||||
test("invalid right side of intersection", () => {
|
||||
expect(() => z.intersection(z.string(), z.number()).parse("12" as any)).toThrow();
|
||||
});
|
||||
|
||||
test("parsing non-array in tuple schema", () => {
|
||||
expect(() => z.tuple([]).parse("12" as any)).toThrow();
|
||||
});
|
||||
|
||||
test("incorrect num elements in tuple", () => {
|
||||
expect(() => z.tuple([]).parse(["asdf"] as any)).toThrow();
|
||||
});
|
||||
|
||||
test("invalid enum value", () => {
|
||||
expect(() => z.enum(["Blue"]).parse("Red" as any)).toThrow();
|
||||
});
|
||||
|
||||
test("parsing unknown", () => {
|
||||
z.string().parse("Red" as unknown);
|
||||
});
|
243
node_modules/zod/src/v3/tests/partials.test.ts
generated
vendored
Normal file
243
node_modules/zod/src/v3/tests/partials.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,243 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { ZodNullable, ZodOptional } from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
const nested = z.object({
|
||||
name: z.string(),
|
||||
age: z.number(),
|
||||
outer: z.object({
|
||||
inner: z.string(),
|
||||
}),
|
||||
array: z.array(z.object({ asdf: z.string() })),
|
||||
});
|
||||
|
||||
test("shallow inference", () => {
|
||||
const shallow = nested.partial();
|
||||
type shallow = z.infer<typeof shallow>;
|
||||
type correct = {
|
||||
name?: string | undefined;
|
||||
age?: number | undefined;
|
||||
outer?: { inner: string } | undefined;
|
||||
array?: { asdf: string }[];
|
||||
};
|
||||
util.assertEqual<shallow, correct>(true);
|
||||
});
|
||||
|
||||
test("shallow partial parse", () => {
|
||||
const shallow = nested.partial();
|
||||
shallow.parse({});
|
||||
shallow.parse({
|
||||
name: "asdf",
|
||||
age: 23143,
|
||||
});
|
||||
});
|
||||
|
||||
test("deep partial inference", () => {
|
||||
const deep = nested.deepPartial();
|
||||
const asdf = deep.shape.array.unwrap().element.shape.asdf.unwrap();
|
||||
asdf.parse("asdf");
|
||||
type deep = z.infer<typeof deep>;
|
||||
type correct = {
|
||||
array?: { asdf?: string }[];
|
||||
name?: string | undefined;
|
||||
age?: number | undefined;
|
||||
outer?: { inner?: string | undefined } | undefined;
|
||||
};
|
||||
|
||||
util.assertEqual<deep, correct>(true);
|
||||
});
|
||||
|
||||
test("deep partial parse", () => {
|
||||
const deep = nested.deepPartial();
|
||||
|
||||
expect(deep.shape.name instanceof z.ZodOptional).toBe(true);
|
||||
expect(deep.shape.outer instanceof z.ZodOptional).toBe(true);
|
||||
expect(deep.shape.outer._def.innerType instanceof z.ZodObject).toBe(true);
|
||||
expect(deep.shape.outer._def.innerType.shape.inner instanceof z.ZodOptional).toBe(true);
|
||||
expect(deep.shape.outer._def.innerType.shape.inner._def.innerType instanceof z.ZodString).toBe(true);
|
||||
});
|
||||
|
||||
test("deep partial runtime tests", () => {
|
||||
const deep = nested.deepPartial();
|
||||
deep.parse({});
|
||||
deep.parse({
|
||||
outer: {},
|
||||
});
|
||||
deep.parse({
|
||||
name: "asdf",
|
||||
age: 23143,
|
||||
outer: {
|
||||
inner: "adsf",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test("deep partial optional/nullable", () => {
|
||||
const schema = z
|
||||
.object({
|
||||
name: z.string().optional(),
|
||||
age: z.number().nullable(),
|
||||
})
|
||||
.deepPartial();
|
||||
|
||||
expect(schema.shape.name.unwrap()).toBeInstanceOf(ZodOptional);
|
||||
expect(schema.shape.age.unwrap()).toBeInstanceOf(ZodNullable);
|
||||
});
|
||||
|
||||
test("deep partial tuple", () => {
|
||||
const schema = z
|
||||
.object({
|
||||
tuple: z.tuple([
|
||||
z.object({
|
||||
name: z.string().optional(),
|
||||
age: z.number().nullable(),
|
||||
}),
|
||||
]),
|
||||
})
|
||||
.deepPartial();
|
||||
|
||||
expect(schema.shape.tuple.unwrap().items[0].shape.name).toBeInstanceOf(ZodOptional);
|
||||
});
|
||||
|
||||
test("deep partial inference", () => {
|
||||
const mySchema = z.object({
|
||||
name: z.string(),
|
||||
array: z.array(z.object({ asdf: z.string() })),
|
||||
tuple: z.tuple([z.object({ value: z.string() })]),
|
||||
});
|
||||
|
||||
const partialed = mySchema.deepPartial();
|
||||
type partialed = z.infer<typeof partialed>;
|
||||
type expected = {
|
||||
name?: string | undefined;
|
||||
array?:
|
||||
| {
|
||||
asdf?: string | undefined;
|
||||
}[]
|
||||
| undefined;
|
||||
tuple?: [{ value?: string }] | undefined;
|
||||
};
|
||||
util.assertEqual<expected, partialed>(true);
|
||||
});
|
||||
|
||||
test("required", () => {
|
||||
const object = z.object({
|
||||
name: z.string(),
|
||||
age: z.number().optional(),
|
||||
field: z.string().optional().default("asdf"),
|
||||
nullableField: z.number().nullable(),
|
||||
nullishField: z.string().nullish(),
|
||||
});
|
||||
|
||||
const requiredObject = object.required();
|
||||
expect(requiredObject.shape.name).toBeInstanceOf(z.ZodString);
|
||||
expect(requiredObject.shape.age).toBeInstanceOf(z.ZodNumber);
|
||||
expect(requiredObject.shape.field).toBeInstanceOf(z.ZodDefault);
|
||||
expect(requiredObject.shape.nullableField).toBeInstanceOf(z.ZodNullable);
|
||||
expect(requiredObject.shape.nullishField).toBeInstanceOf(z.ZodNullable);
|
||||
});
|
||||
|
||||
test("required inference", () => {
|
||||
const object = z.object({
|
||||
name: z.string(),
|
||||
age: z.number().optional(),
|
||||
field: z.string().optional().default("asdf"),
|
||||
nullableField: z.number().nullable(),
|
||||
nullishField: z.string().nullish(),
|
||||
});
|
||||
|
||||
const requiredObject = object.required();
|
||||
|
||||
type required = z.infer<typeof requiredObject>;
|
||||
type expected = {
|
||||
name: string;
|
||||
age: number;
|
||||
field: string;
|
||||
nullableField: number | null;
|
||||
nullishField: string | null;
|
||||
};
|
||||
util.assertEqual<expected, required>(true);
|
||||
});
|
||||
|
||||
test("required with mask", () => {
|
||||
const object = z.object({
|
||||
name: z.string(),
|
||||
age: z.number().optional(),
|
||||
field: z.string().optional().default("asdf"),
|
||||
country: z.string().optional(),
|
||||
});
|
||||
|
||||
const requiredObject = object.required({ age: true });
|
||||
expect(requiredObject.shape.name).toBeInstanceOf(z.ZodString);
|
||||
expect(requiredObject.shape.age).toBeInstanceOf(z.ZodNumber);
|
||||
expect(requiredObject.shape.field).toBeInstanceOf(z.ZodDefault);
|
||||
expect(requiredObject.shape.country).toBeInstanceOf(z.ZodOptional);
|
||||
});
|
||||
|
||||
test("required with mask -- ignore falsy values", () => {
|
||||
const object = z.object({
|
||||
name: z.string(),
|
||||
age: z.number().optional(),
|
||||
field: z.string().optional().default("asdf"),
|
||||
country: z.string().optional(),
|
||||
});
|
||||
|
||||
// @ts-expect-error
|
||||
const requiredObject = object.required({ age: true, country: false });
|
||||
expect(requiredObject.shape.name).toBeInstanceOf(z.ZodString);
|
||||
expect(requiredObject.shape.age).toBeInstanceOf(z.ZodNumber);
|
||||
expect(requiredObject.shape.field).toBeInstanceOf(z.ZodDefault);
|
||||
expect(requiredObject.shape.country).toBeInstanceOf(z.ZodOptional);
|
||||
});
|
||||
|
||||
test("partial with mask", async () => {
|
||||
const object = z.object({
|
||||
name: z.string(),
|
||||
age: z.number().optional(),
|
||||
field: z.string().optional().default("asdf"),
|
||||
country: z.string(),
|
||||
});
|
||||
|
||||
const masked = object.partial({ age: true, field: true, name: true }).strict();
|
||||
|
||||
expect(masked.shape.name).toBeInstanceOf(z.ZodOptional);
|
||||
expect(masked.shape.age).toBeInstanceOf(z.ZodOptional);
|
||||
expect(masked.shape.field).toBeInstanceOf(z.ZodOptional);
|
||||
expect(masked.shape.country).toBeInstanceOf(z.ZodString);
|
||||
|
||||
masked.parse({ country: "US" });
|
||||
await masked.parseAsync({ country: "US" });
|
||||
});
|
||||
|
||||
test("partial with mask -- ignore falsy values", async () => {
|
||||
const object = z.object({
|
||||
name: z.string(),
|
||||
age: z.number().optional(),
|
||||
field: z.string().optional().default("asdf"),
|
||||
country: z.string(),
|
||||
});
|
||||
|
||||
// @ts-expect-error
|
||||
const masked = object.partial({ name: true, country: false }).strict();
|
||||
|
||||
expect(masked.shape.name).toBeInstanceOf(z.ZodOptional);
|
||||
expect(masked.shape.age).toBeInstanceOf(z.ZodOptional);
|
||||
expect(masked.shape.field).toBeInstanceOf(z.ZodDefault);
|
||||
expect(masked.shape.country).toBeInstanceOf(z.ZodString);
|
||||
|
||||
masked.parse({ country: "US" });
|
||||
await masked.parseAsync({ country: "US" });
|
||||
});
|
||||
|
||||
test("deeppartial array", () => {
|
||||
const schema = z.object({ array: z.string().array().min(42) }).deepPartial();
|
||||
|
||||
// works as expected
|
||||
schema.parse({});
|
||||
|
||||
// should be false, but is true
|
||||
expect(schema.safeParse({ array: [] }).success).toBe(false);
|
||||
});
|
111
node_modules/zod/src/v3/tests/pickomit.test.ts
generated
vendored
Normal file
111
node_modules/zod/src/v3/tests/pickomit.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
const fish = z.object({
|
||||
name: z.string(),
|
||||
age: z.number(),
|
||||
nested: z.object({}),
|
||||
});
|
||||
|
||||
test("pick type inference", () => {
|
||||
const nameonlyFish = fish.pick({ name: true });
|
||||
type nameonlyFish = z.infer<typeof nameonlyFish>;
|
||||
util.assertEqual<nameonlyFish, { name: string }>(true);
|
||||
});
|
||||
|
||||
test("pick parse - success", () => {
|
||||
const nameonlyFish = fish.pick({ name: true });
|
||||
nameonlyFish.parse({ name: "bob" });
|
||||
|
||||
// @ts-expect-error checking runtime picks `name` only.
|
||||
const anotherNameonlyFish = fish.pick({ name: true, age: false });
|
||||
anotherNameonlyFish.parse({ name: "bob" });
|
||||
});
|
||||
|
||||
test("pick parse - fail", () => {
|
||||
fish.pick({ name: true }).parse({ name: "12" } as any);
|
||||
fish.pick({ name: true }).parse({ name: "bob", age: 12 } as any);
|
||||
fish.pick({ age: true }).parse({ age: 12 } as any);
|
||||
|
||||
const nameonlyFish = fish.pick({ name: true }).strict();
|
||||
const bad1 = () => nameonlyFish.parse({ name: 12 } as any);
|
||||
const bad2 = () => nameonlyFish.parse({ name: "bob", age: 12 } as any);
|
||||
const bad3 = () => nameonlyFish.parse({ age: 12 } as any);
|
||||
|
||||
// @ts-expect-error checking runtime picks `name` only.
|
||||
const anotherNameonlyFish = fish.pick({ name: true, age: false }).strict();
|
||||
const bad4 = () => anotherNameonlyFish.parse({ name: "bob", age: 12 } as any);
|
||||
|
||||
expect(bad1).toThrow();
|
||||
expect(bad2).toThrow();
|
||||
expect(bad3).toThrow();
|
||||
expect(bad4).toThrow();
|
||||
});
|
||||
|
||||
test("omit type inference", () => {
|
||||
const nonameFish = fish.omit({ name: true });
|
||||
type nonameFish = z.infer<typeof nonameFish>;
|
||||
util.assertEqual<nonameFish, { age: number; nested: {} }>(true);
|
||||
});
|
||||
|
||||
test("omit parse - success", () => {
|
||||
const nonameFish = fish.omit({ name: true });
|
||||
nonameFish.parse({ age: 12, nested: {} });
|
||||
|
||||
// @ts-expect-error checking runtime omits `name` only.
|
||||
const anotherNonameFish = fish.omit({ name: true, age: false });
|
||||
anotherNonameFish.parse({ age: 12, nested: {} });
|
||||
});
|
||||
|
||||
test("omit parse - fail", () => {
|
||||
const nonameFish = fish.omit({ name: true });
|
||||
const bad1 = () => nonameFish.parse({ name: 12 } as any);
|
||||
const bad2 = () => nonameFish.parse({ age: 12 } as any);
|
||||
const bad3 = () => nonameFish.parse({} as any);
|
||||
|
||||
// @ts-expect-error checking runtime omits `name` only.
|
||||
const anotherNonameFish = fish.omit({ name: true, age: false });
|
||||
const bad4 = () => anotherNonameFish.parse({ nested: {} } as any);
|
||||
|
||||
expect(bad1).toThrow();
|
||||
expect(bad2).toThrow();
|
||||
expect(bad3).toThrow();
|
||||
expect(bad4).toThrow();
|
||||
});
|
||||
|
||||
test("nonstrict inference", () => {
|
||||
const laxfish = fish.pick({ name: true }).catchall(z.any());
|
||||
type laxfish = z.infer<typeof laxfish>;
|
||||
util.assertEqual<laxfish, { name: string } & { [k: string]: any }>(true);
|
||||
});
|
||||
|
||||
test("nonstrict parsing - pass", () => {
|
||||
const laxfish = fish.passthrough().pick({ name: true });
|
||||
laxfish.parse({ name: "asdf", whatever: "asdf" });
|
||||
laxfish.parse({ name: "asdf", age: 12, nested: {} });
|
||||
});
|
||||
|
||||
test("nonstrict parsing - fail", () => {
|
||||
const laxfish = fish.passthrough().pick({ name: true });
|
||||
const bad = () => laxfish.parse({ whatever: "asdf" } as any);
|
||||
expect(bad).toThrow();
|
||||
});
|
||||
|
||||
test("pick/omit/required/partial - do not allow unknown keys", () => {
|
||||
const schema = z.object({
|
||||
name: z.string(),
|
||||
age: z.number(),
|
||||
});
|
||||
|
||||
// @ts-expect-error
|
||||
schema.pick({ $unknown: true });
|
||||
// @ts-expect-error
|
||||
schema.omit({ $unknown: true });
|
||||
// @ts-expect-error
|
||||
schema.required({ $unknown: true });
|
||||
// @ts-expect-error
|
||||
schema.partial({ $unknown: true });
|
||||
});
|
29
node_modules/zod/src/v3/tests/pipeline.test.ts
generated
vendored
Normal file
29
node_modules/zod/src/v3/tests/pipeline.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
|
||||
test("string to number pipeline", () => {
|
||||
const schema = z.string().transform(Number).pipe(z.number());
|
||||
expect(schema.parse("1234")).toEqual(1234);
|
||||
});
|
||||
|
||||
test("string to number pipeline async", async () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.transform(async (val) => Number(val))
|
||||
.pipe(z.number());
|
||||
expect(await schema.parseAsync("1234")).toEqual(1234);
|
||||
});
|
||||
|
||||
test("break if dirty", () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.refine((c) => c === "1234")
|
||||
.transform(async (val) => Number(val))
|
||||
.pipe(z.number().refine((v) => v < 100));
|
||||
const r1: any = schema.safeParse("12345");
|
||||
expect(r1.error.issues.length).toBe(1);
|
||||
const r2: any = schema.safeParse("3");
|
||||
expect(r2.error.issues.length).toBe(1);
|
||||
});
|
186
node_modules/zod/src/v3/tests/preprocess.test.ts
generated
vendored
Normal file
186
node_modules/zod/src/v3/tests/preprocess.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
test("preprocess", () => {
|
||||
const schema = z.preprocess((data) => [data], z.string().array());
|
||||
|
||||
const value = schema.parse("asdf");
|
||||
expect(value).toEqual(["asdf"]);
|
||||
util.assertEqual<(typeof schema)["_input"], unknown>(true);
|
||||
});
|
||||
|
||||
test("async preprocess", async () => {
|
||||
const schema = z.preprocess(async (data) => [data], z.string().array());
|
||||
|
||||
const value = await schema.parseAsync("asdf");
|
||||
expect(value).toEqual(["asdf"]);
|
||||
});
|
||||
|
||||
test("preprocess ctx.addIssue with parse", () => {
|
||||
expect(() => {
|
||||
z.preprocess((data, ctx) => {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `${data} is not one of our allowed strings`,
|
||||
});
|
||||
return data;
|
||||
}, z.string()).parse("asdf");
|
||||
}).toThrow(
|
||||
JSON.stringify(
|
||||
[
|
||||
{
|
||||
code: "custom",
|
||||
message: "asdf is not one of our allowed strings",
|
||||
path: [],
|
||||
},
|
||||
],
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
test("preprocess ctx.addIssue non-fatal by default", () => {
|
||||
try {
|
||||
z.preprocess((data, ctx) => {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `custom error`,
|
||||
});
|
||||
return data;
|
||||
}, z.string()).parse(1234);
|
||||
} catch (err) {
|
||||
z.ZodError.assert(err);
|
||||
expect(err.issues.length).toEqual(2);
|
||||
}
|
||||
});
|
||||
|
||||
test("preprocess ctx.addIssue fatal true", () => {
|
||||
try {
|
||||
z.preprocess((data, ctx) => {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `custom error`,
|
||||
fatal: true,
|
||||
});
|
||||
return data;
|
||||
}, z.string()).parse(1234);
|
||||
} catch (err) {
|
||||
z.ZodError.assert(err);
|
||||
expect(err.issues.length).toEqual(1);
|
||||
}
|
||||
});
|
||||
|
||||
test("async preprocess ctx.addIssue with parse", async () => {
|
||||
const schema = z.preprocess(async (data, ctx) => {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `custom error`,
|
||||
});
|
||||
return data;
|
||||
}, z.string());
|
||||
|
||||
expect(await schema.safeParseAsync("asdf")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "custom error",
|
||||
"path": []
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("preprocess ctx.addIssue with parseAsync", async () => {
|
||||
const result = await z
|
||||
.preprocess(async (data, ctx) => {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `${data} is not one of our allowed strings`,
|
||||
});
|
||||
return data;
|
||||
}, z.string())
|
||||
.safeParseAsync("asdf");
|
||||
|
||||
expect(JSON.parse(JSON.stringify(result))).toEqual({
|
||||
success: false,
|
||||
error: {
|
||||
issues: [
|
||||
{
|
||||
code: "custom",
|
||||
message: "asdf is not one of our allowed strings",
|
||||
path: [],
|
||||
},
|
||||
],
|
||||
name: "ZodError",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test("z.NEVER in preprocess", () => {
|
||||
const foo = z.preprocess((val, ctx) => {
|
||||
if (!val) {
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "bad" });
|
||||
return z.NEVER;
|
||||
}
|
||||
return val;
|
||||
}, z.number());
|
||||
|
||||
type foo = z.infer<typeof foo>;
|
||||
util.assertEqual<foo, number>(true);
|
||||
const arg = foo.safeParse(undefined);
|
||||
expect(arg.error!.issues).toHaveLength(2);
|
||||
expect(arg.error!.issues[0].message).toEqual("bad");
|
||||
});
|
||||
test("preprocess as the second property of object", () => {
|
||||
const schema = z.object({
|
||||
nonEmptyStr: z.string().min(1),
|
||||
positiveNum: z.preprocess((v) => Number(v), z.number().positive()),
|
||||
});
|
||||
const result = schema.safeParse({
|
||||
nonEmptyStr: "",
|
||||
positiveNum: "",
|
||||
});
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
expect(result.error.issues[0].code).toEqual(z.ZodIssueCode.too_small);
|
||||
expect(result.error.issues[1].code).toEqual(z.ZodIssueCode.too_small);
|
||||
}
|
||||
});
|
||||
|
||||
test("preprocess validates with sibling errors", () => {
|
||||
expect(() => {
|
||||
z.object({
|
||||
// Must be first
|
||||
missing: z.string().refine(() => false),
|
||||
preprocess: z.preprocess((data: any) => data?.trim(), z.string().regex(/ asdf/)),
|
||||
}).parse({ preprocess: " asdf" });
|
||||
}).toThrow(
|
||||
JSON.stringify(
|
||||
[
|
||||
{
|
||||
code: "invalid_type",
|
||||
expected: "string",
|
||||
received: "undefined",
|
||||
path: ["missing"],
|
||||
message: "Required",
|
||||
},
|
||||
{
|
||||
validation: "regex",
|
||||
code: "invalid_string",
|
||||
message: "Invalid",
|
||||
path: ["preprocess"],
|
||||
},
|
||||
],
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
});
|
440
node_modules/zod/src/v3/tests/primitive.test.ts
generated
vendored
Normal file
440
node_modules/zod/src/v3/tests/primitive.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,440 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
import { Mocker } from "./Mocker.js";
|
||||
|
||||
const literalStringSchema = z.literal("asdf");
|
||||
const literalNumberSchema = z.literal(12);
|
||||
const literalBooleanSchema = z.literal(true);
|
||||
const literalBigIntSchema = z.literal(BigInt(42));
|
||||
const MySymbol = Symbol("stuff");
|
||||
const literalSymbolSchema = z.literal(MySymbol);
|
||||
const stringSchema = z.string();
|
||||
const numberSchema = z.number();
|
||||
const bigintSchema = z.bigint();
|
||||
const booleanSchema = z.boolean();
|
||||
const dateSchema = z.date();
|
||||
const symbolSchema = z.symbol();
|
||||
|
||||
const nullSchema = z.null();
|
||||
const undefinedSchema = z.undefined();
|
||||
const stringSchemaOptional = z.string().optional();
|
||||
const stringSchemaNullable = z.string().nullable();
|
||||
const numberSchemaOptional = z.number().optional();
|
||||
const numberSchemaNullable = z.number().nullable();
|
||||
const bigintSchemaOptional = z.bigint().optional();
|
||||
const bigintSchemaNullable = z.bigint().nullable();
|
||||
const booleanSchemaOptional = z.boolean().optional();
|
||||
const booleanSchemaNullable = z.boolean().nullable();
|
||||
const dateSchemaOptional = z.date().optional();
|
||||
const dateSchemaNullable = z.date().nullable();
|
||||
const symbolSchemaOptional = z.symbol().optional();
|
||||
const symbolSchemaNullable = z.symbol().nullable();
|
||||
|
||||
const val = new Mocker();
|
||||
|
||||
test("literal string correct", () => {
|
||||
expect(literalStringSchema.parse("asdf")).toBe("asdf");
|
||||
});
|
||||
|
||||
test("literal string incorrect", () => {
|
||||
const f = () => literalStringSchema.parse("not_asdf");
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal string number", () => {
|
||||
const f = () => literalStringSchema.parse(123);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal string boolean", () => {
|
||||
const f = () => literalStringSchema.parse(true);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal string boolean", () => {
|
||||
const f = () => literalStringSchema.parse(true);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal string object", () => {
|
||||
const f = () => literalStringSchema.parse({});
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal number correct", () => {
|
||||
expect(literalNumberSchema.parse(12)).toBe(12);
|
||||
});
|
||||
|
||||
test("literal number incorrect", () => {
|
||||
const f = () => literalNumberSchema.parse(13);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal number number", () => {
|
||||
const f = () => literalNumberSchema.parse(val.string);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal number boolean", () => {
|
||||
const f = () => literalNumberSchema.parse(val.boolean);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal number object", () => {
|
||||
const f = () => literalStringSchema.parse({});
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal boolean correct", () => {
|
||||
expect(literalBooleanSchema.parse(true)).toBe(true);
|
||||
});
|
||||
|
||||
test("literal boolean incorrect", () => {
|
||||
const f = () => literalBooleanSchema.parse(false);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal boolean number", () => {
|
||||
const f = () => literalBooleanSchema.parse("asdf");
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal boolean boolean", () => {
|
||||
const f = () => literalBooleanSchema.parse(123);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal boolean object", () => {
|
||||
const f = () => literalBooleanSchema.parse({});
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal bigint correct", () => {
|
||||
expect(literalBigIntSchema.parse(BigInt(42))).toBe(BigInt(42));
|
||||
});
|
||||
|
||||
test("literal bigint incorrect", () => {
|
||||
const f = () => literalBigIntSchema.parse(BigInt(43));
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal bigint number", () => {
|
||||
const f = () => literalBigIntSchema.parse("asdf");
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal bigint boolean", () => {
|
||||
const f = () => literalBigIntSchema.parse(123);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal bigint object", () => {
|
||||
const f = () => literalBigIntSchema.parse({});
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("literal symbol", () => {
|
||||
util.assertEqual<z.infer<typeof literalSymbolSchema>, typeof MySymbol>(true);
|
||||
literalSymbolSchema.parse(MySymbol);
|
||||
expect(() => literalSymbolSchema.parse(Symbol("asdf"))).toThrow();
|
||||
});
|
||||
|
||||
test("parse stringSchema string", () => {
|
||||
stringSchema.parse(val.string);
|
||||
});
|
||||
|
||||
test("parse stringSchema number", () => {
|
||||
const f = () => stringSchema.parse(val.number);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse stringSchema boolean", () => {
|
||||
const f = () => stringSchema.parse(val.boolean);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse stringSchema undefined", () => {
|
||||
const f = () => stringSchema.parse(val.undefined);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse stringSchema null", () => {
|
||||
const f = () => stringSchema.parse(val.null);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse numberSchema string", () => {
|
||||
const f = () => numberSchema.parse(val.string);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse numberSchema number", () => {
|
||||
numberSchema.parse(val.number);
|
||||
});
|
||||
|
||||
test("parse numberSchema bigint", () => {
|
||||
const f = () => numberSchema.parse(val.bigint);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse numberSchema boolean", () => {
|
||||
const f = () => numberSchema.parse(val.boolean);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse numberSchema undefined", () => {
|
||||
const f = () => numberSchema.parse(val.undefined);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse numberSchema null", () => {
|
||||
const f = () => numberSchema.parse(val.null);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse bigintSchema string", () => {
|
||||
const f = () => bigintSchema.parse(val.string);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse bigintSchema number", () => {
|
||||
const f = () => bigintSchema.parse(val.number);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse bigintSchema bigint", () => {
|
||||
bigintSchema.parse(val.bigint);
|
||||
});
|
||||
|
||||
test("parse bigintSchema boolean", () => {
|
||||
const f = () => bigintSchema.parse(val.boolean);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse bigintSchema undefined", () => {
|
||||
const f = () => bigintSchema.parse(val.undefined);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse bigintSchema null", () => {
|
||||
const f = () => bigintSchema.parse(val.null);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse booleanSchema string", () => {
|
||||
const f = () => booleanSchema.parse(val.string);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse booleanSchema number", () => {
|
||||
const f = () => booleanSchema.parse(val.number);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse booleanSchema boolean", () => {
|
||||
booleanSchema.parse(val.boolean);
|
||||
});
|
||||
|
||||
test("parse booleanSchema undefined", () => {
|
||||
const f = () => booleanSchema.parse(val.undefined);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse booleanSchema null", () => {
|
||||
const f = () => booleanSchema.parse(val.null);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
// ==============
|
||||
|
||||
test("parse dateSchema string", () => {
|
||||
const f = () => dateSchema.parse(val.string);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse dateSchema number", () => {
|
||||
const f = () => dateSchema.parse(val.number);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse dateSchema boolean", () => {
|
||||
const f = () => dateSchema.parse(val.boolean);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse dateSchema date", () => {
|
||||
dateSchema.parse(val.date);
|
||||
});
|
||||
|
||||
test("parse dateSchema undefined", () => {
|
||||
const f = () => dateSchema.parse(val.undefined);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse dateSchema null", () => {
|
||||
const f = () => dateSchema.parse(val.null);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse dateSchema invalid date", async () => {
|
||||
try {
|
||||
await dateSchema.parseAsync(new Date("invalid"));
|
||||
} catch (err) {
|
||||
expect((err as z.ZodError).issues[0].code).toEqual(z.ZodIssueCode.invalid_date);
|
||||
}
|
||||
});
|
||||
// ==============
|
||||
|
||||
test("parse symbolSchema string", () => {
|
||||
const f = () => symbolSchema.parse(val.string);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse symbolSchema number", () => {
|
||||
const f = () => symbolSchema.parse(val.number);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse symbolSchema boolean", () => {
|
||||
const f = () => symbolSchema.parse(val.boolean);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse symbolSchema date", () => {
|
||||
const f = () => symbolSchema.parse(val.date);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse symbolSchema symbol", () => {
|
||||
symbolSchema.parse(val.symbol);
|
||||
});
|
||||
|
||||
test("parse symbolSchema undefined", () => {
|
||||
const f = () => symbolSchema.parse(val.undefined);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse symbolSchema null", () => {
|
||||
const f = () => symbolSchema.parse(val.null);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
// ==============
|
||||
|
||||
test("parse undefinedSchema string", () => {
|
||||
const f = () => undefinedSchema.parse(val.string);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse undefinedSchema number", () => {
|
||||
const f = () => undefinedSchema.parse(val.number);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse undefinedSchema boolean", () => {
|
||||
const f = () => undefinedSchema.parse(val.boolean);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse undefinedSchema undefined", () => {
|
||||
undefinedSchema.parse(val.undefined);
|
||||
});
|
||||
|
||||
test("parse undefinedSchema null", () => {
|
||||
const f = () => undefinedSchema.parse(val.null);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse nullSchema string", () => {
|
||||
const f = () => nullSchema.parse(val.string);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse nullSchema number", () => {
|
||||
const f = () => nullSchema.parse(val.number);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse nullSchema boolean", () => {
|
||||
const f = () => nullSchema.parse(val.boolean);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse nullSchema undefined", () => {
|
||||
const f = () => nullSchema.parse(val.undefined);
|
||||
expect(f).toThrow();
|
||||
});
|
||||
|
||||
test("parse nullSchema null", () => {
|
||||
nullSchema.parse(val.null);
|
||||
});
|
||||
|
||||
test("primitive inference", () => {
|
||||
util.assertEqual<z.TypeOf<typeof literalStringSchema>, "asdf">(true);
|
||||
util.assertEqual<z.TypeOf<typeof literalNumberSchema>, 12>(true);
|
||||
util.assertEqual<z.TypeOf<typeof literalBooleanSchema>, true>(true);
|
||||
util.assertEqual<z.TypeOf<typeof literalBigIntSchema>, bigint>(true);
|
||||
util.assertEqual<z.TypeOf<typeof stringSchema>, string>(true);
|
||||
util.assertEqual<z.TypeOf<typeof numberSchema>, number>(true);
|
||||
util.assertEqual<z.TypeOf<typeof bigintSchema>, bigint>(true);
|
||||
util.assertEqual<z.TypeOf<typeof booleanSchema>, boolean>(true);
|
||||
util.assertEqual<z.TypeOf<typeof dateSchema>, Date>(true);
|
||||
util.assertEqual<z.TypeOf<typeof symbolSchema>, symbol>(true);
|
||||
|
||||
util.assertEqual<z.TypeOf<typeof nullSchema>, null>(true);
|
||||
util.assertEqual<z.TypeOf<typeof undefinedSchema>, undefined>(true);
|
||||
util.assertEqual<z.TypeOf<typeof stringSchemaOptional>, string | undefined>(true);
|
||||
util.assertEqual<z.TypeOf<typeof stringSchemaNullable>, string | null>(true);
|
||||
util.assertEqual<z.TypeOf<typeof numberSchemaOptional>, number | undefined>(true);
|
||||
util.assertEqual<z.TypeOf<typeof numberSchemaNullable>, number | null>(true);
|
||||
util.assertEqual<z.TypeOf<typeof bigintSchemaOptional>, bigint | undefined>(true);
|
||||
util.assertEqual<z.TypeOf<typeof bigintSchemaNullable>, bigint | null>(true);
|
||||
util.assertEqual<z.TypeOf<typeof booleanSchemaOptional>, boolean | undefined>(true);
|
||||
util.assertEqual<z.TypeOf<typeof booleanSchemaNullable>, boolean | null>(true);
|
||||
util.assertEqual<z.TypeOf<typeof dateSchemaOptional>, Date | undefined>(true);
|
||||
util.assertEqual<z.TypeOf<typeof dateSchemaNullable>, Date | null>(true);
|
||||
util.assertEqual<z.TypeOf<typeof symbolSchemaOptional>, symbol | undefined>(true);
|
||||
util.assertEqual<z.TypeOf<typeof symbolSchemaNullable>, symbol | null>(true);
|
||||
|
||||
// [
|
||||
// literalStringSchemaTest,
|
||||
// literalNumberSchemaTest,
|
||||
// literalBooleanSchemaTest,
|
||||
// literalBigIntSchemaTest,
|
||||
// stringSchemaTest,
|
||||
// numberSchemaTest,
|
||||
// bigintSchemaTest,
|
||||
// booleanSchemaTest,
|
||||
// dateSchemaTest,
|
||||
// symbolSchemaTest,
|
||||
|
||||
// nullSchemaTest,
|
||||
// undefinedSchemaTest,
|
||||
// stringSchemaOptionalTest,
|
||||
// stringSchemaNullableTest,
|
||||
// numberSchemaOptionalTest,
|
||||
// numberSchemaNullableTest,
|
||||
// bigintSchemaOptionalTest,
|
||||
// bigintSchemaNullableTest,
|
||||
// booleanSchemaOptionalTest,
|
||||
// booleanSchemaNullableTest,
|
||||
// dateSchemaOptionalTest,
|
||||
// dateSchemaNullableTest,
|
||||
// symbolSchemaOptionalTest,
|
||||
// symbolSchemaNullableTest,
|
||||
|
||||
// ];
|
||||
});
|
||||
|
||||
test("get literal value", () => {
|
||||
expect(literalStringSchema.value).toEqual("asdf");
|
||||
});
|
||||
|
||||
test("optional convenience method", () => {
|
||||
z.ostring().parse(undefined);
|
||||
z.onumber().parse(undefined);
|
||||
z.oboolean().parse(undefined);
|
||||
});
|
90
node_modules/zod/src/v3/tests/promise.test.ts
generated
vendored
Normal file
90
node_modules/zod/src/v3/tests/promise.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
const promSchema = z.promise(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
age: z.number(),
|
||||
})
|
||||
);
|
||||
|
||||
test("promise inference", () => {
|
||||
type promSchemaType = z.infer<typeof promSchema>;
|
||||
util.assertEqual<promSchemaType, Promise<{ name: string; age: number }>>(true);
|
||||
});
|
||||
|
||||
test("promise parsing success", async () => {
|
||||
const pr = promSchema.parse(Promise.resolve({ name: "Bobby", age: 10 }));
|
||||
expect(pr).toBeInstanceOf(Promise);
|
||||
const result = await pr;
|
||||
expect(typeof result).toBe("object");
|
||||
expect(typeof result.age).toBe("number");
|
||||
expect(typeof result.name).toBe("string");
|
||||
});
|
||||
|
||||
test("promise parsing success 2", () => {
|
||||
const fakePromise = {
|
||||
then() {
|
||||
return this;
|
||||
},
|
||||
catch() {
|
||||
return this;
|
||||
},
|
||||
};
|
||||
promSchema.parse(fakePromise);
|
||||
});
|
||||
|
||||
test("promise parsing fail", async () => {
|
||||
const bad = promSchema.parse(Promise.resolve({ name: "Bobby", age: "10" }));
|
||||
// return await expect(bad).resolves.toBe({ name: 'Bobby', age: '10' });
|
||||
return await expect(bad).rejects.toBeInstanceOf(z.ZodError);
|
||||
// done();
|
||||
});
|
||||
|
||||
test("promise parsing fail 2", async () => {
|
||||
const failPromise = promSchema.parse(Promise.resolve({ name: "Bobby", age: "10" }));
|
||||
await expect(failPromise).rejects.toBeInstanceOf(z.ZodError);
|
||||
// done();/z
|
||||
});
|
||||
|
||||
test("promise parsing fail", () => {
|
||||
const bad = () => promSchema.parse({ then: () => {}, catch: {} });
|
||||
expect(bad).toThrow();
|
||||
});
|
||||
|
||||
// test('sync promise parsing', () => {
|
||||
// expect(() => z.promise(z.string()).parse(Promise.resolve('asfd'))).toThrow();
|
||||
// });
|
||||
|
||||
const asyncFunction = z.function(z.tuple([]), promSchema);
|
||||
|
||||
test("async function pass", async () => {
|
||||
const validatedFunction = asyncFunction.implement(async () => {
|
||||
return { name: "jimmy", age: 14 };
|
||||
});
|
||||
await expect(validatedFunction()).resolves.toEqual({
|
||||
name: "jimmy",
|
||||
age: 14,
|
||||
});
|
||||
});
|
||||
|
||||
test("async function fail", async () => {
|
||||
const validatedFunction = asyncFunction.implement(() => {
|
||||
return Promise.resolve("asdf" as any);
|
||||
});
|
||||
await expect(validatedFunction()).rejects.toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
test("async promise parsing", () => {
|
||||
const res = z.promise(z.number()).parseAsync(Promise.resolve(12));
|
||||
expect(res).toBeInstanceOf(Promise);
|
||||
});
|
||||
|
||||
test("resolves", () => {
|
||||
const foo = z.literal("foo");
|
||||
const res = z.promise(foo);
|
||||
expect(res.unwrap()).toEqual(foo);
|
||||
});
|
194
node_modules/zod/src/v3/tests/readonly.test.ts
generated
vendored
Normal file
194
node_modules/zod/src/v3/tests/readonly.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,194 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
enum testEnum {
|
||||
A = 0,
|
||||
B = 1,
|
||||
}
|
||||
|
||||
const schemas = [
|
||||
z.string().readonly(),
|
||||
z.number().readonly(),
|
||||
z.nan().readonly(),
|
||||
z.bigint().readonly(),
|
||||
z.boolean().readonly(),
|
||||
z.date().readonly(),
|
||||
z.undefined().readonly(),
|
||||
z.null().readonly(),
|
||||
z.any().readonly(),
|
||||
z.unknown().readonly(),
|
||||
z.void().readonly(),
|
||||
z.function().args(z.string(), z.number()).readonly(),
|
||||
|
||||
z.array(z.string()).readonly(),
|
||||
z.tuple([z.string(), z.number()]).readonly(),
|
||||
z.map(z.string(), z.date()).readonly(),
|
||||
z.set(z.promise(z.string())).readonly(),
|
||||
z.record(z.string()).readonly(),
|
||||
z.record(z.string(), z.number()).readonly(),
|
||||
z.object({ a: z.string(), 1: z.number() }).readonly(),
|
||||
z.nativeEnum(testEnum).readonly(),
|
||||
z.promise(z.string()).readonly(),
|
||||
] as const;
|
||||
|
||||
test("flat inference", () => {
|
||||
util.assertEqual<z.infer<(typeof schemas)[0]>, string>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[1]>, number>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[2]>, number>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[3]>, bigint>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[4]>, boolean>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[5]>, Date>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[6]>, undefined>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[7]>, null>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[8]>, any>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[9]>, Readonly<unknown>>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[10]>, void>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[11]>, (args_0: string, args_1: number, ...args_2: unknown[]) => unknown>(
|
||||
true
|
||||
);
|
||||
util.assertEqual<z.infer<(typeof schemas)[12]>, readonly string[]>(true);
|
||||
|
||||
util.assertEqual<z.infer<(typeof schemas)[13]>, readonly [string, number]>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[14]>, ReadonlyMap<string, Date>>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[15]>, ReadonlySet<Promise<string>>>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[16]>, Readonly<Record<string, string>>>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[17]>, Readonly<Record<string, number>>>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[18]>, { readonly a: string; readonly 1: number }>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[19]>, Readonly<testEnum>>(true);
|
||||
util.assertEqual<z.infer<(typeof schemas)[20]>, Promise<string>>(true);
|
||||
});
|
||||
|
||||
// test("deep inference", () => {
|
||||
// util.assertEqual<z.infer<(typeof deepReadonlySchemas_0)[0]>, string>(true);
|
||||
// util.assertEqual<z.infer<(typeof deepReadonlySchemas_0)[1]>, number>(true);
|
||||
// util.assertEqual<z.infer<(typeof deepReadonlySchemas_0)[2]>, number>(true);
|
||||
// util.assertEqual<z.infer<(typeof deepReadonlySchemas_0)[3]>, bigint>(true);
|
||||
// util.assertEqual<z.infer<(typeof deepReadonlySchemas_0)[4]>, boolean>(true);
|
||||
// util.assertEqual<z.infer<(typeof deepReadonlySchemas_0)[5]>, Date>(true);
|
||||
// util.assertEqual<z.infer<(typeof deepReadonlySchemas_0)[6]>, undefined>(true);
|
||||
// util.assertEqual<z.infer<(typeof deepReadonlySchemas_0)[7]>, null>(true);
|
||||
// util.assertEqual<z.infer<(typeof deepReadonlySchemas_0)[8]>, any>(true);
|
||||
// util.assertEqual<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[9]>,
|
||||
// Readonly<unknown>
|
||||
// >(true);
|
||||
// util.assertEqual<z.infer<(typeof deepReadonlySchemas_0)[10]>, void>(true);
|
||||
// util.assertEqual<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[11]>,
|
||||
// (args_0: string, args_1: number, ...args_2: unknown[]) => unknown
|
||||
// >(true);
|
||||
// util.assertEqual<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[12]>,
|
||||
// readonly string[]
|
||||
// >(true);
|
||||
// util.assertEqual<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[13]>,
|
||||
// readonly [string, number]
|
||||
// >(true);
|
||||
// util.assertEqual<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[14]>,
|
||||
// ReadonlyMap<string, Date>
|
||||
// >(true);
|
||||
// util.assertEqual<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[15]>,
|
||||
// ReadonlySet<Promise<string>>
|
||||
// >(true);
|
||||
// util.assertEqual<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[16]>,
|
||||
// Readonly<Record<string, string>>
|
||||
// >(true);
|
||||
// util.assertEqual<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[17]>,
|
||||
// Readonly<Record<string, number>>
|
||||
// >(true);
|
||||
// util.assertEqual<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[18]>,
|
||||
// { readonly a: string; readonly 1: number }
|
||||
// >(true);
|
||||
// util.assertEqual<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[19]>,
|
||||
// Readonly<testEnum>
|
||||
// >(true);
|
||||
// util.assertEqual<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[20]>,
|
||||
// Promise<string>
|
||||
// >(true);
|
||||
|
||||
// util.assertEqual<
|
||||
// z.infer<typeof crazyDeepReadonlySchema>,
|
||||
// ReadonlyMap<
|
||||
// ReadonlySet<readonly [string, number]>,
|
||||
// {
|
||||
// readonly a: {
|
||||
// readonly [x: string]: readonly any[];
|
||||
// };
|
||||
// readonly b: {
|
||||
// readonly c: {
|
||||
// readonly d: {
|
||||
// readonly e: {
|
||||
// readonly f: {
|
||||
// readonly g?: {};
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
// }
|
||||
// >
|
||||
// >(true);
|
||||
// });
|
||||
|
||||
test("object freezing", () => {
|
||||
expect(Object.isFrozen(z.array(z.string()).readonly().parse(["a"]))).toBe(true);
|
||||
expect(Object.isFrozen(z.tuple([z.string(), z.number()]).readonly().parse(["a", 1]))).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(
|
||||
z
|
||||
.map(z.string(), z.date())
|
||||
.readonly()
|
||||
.parse(new Map([["a", new Date()]]))
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(
|
||||
z
|
||||
.set(z.promise(z.string()))
|
||||
.readonly()
|
||||
.parse(new Set([Promise.resolve("a")]))
|
||||
)
|
||||
).toBe(true);
|
||||
expect(Object.isFrozen(z.record(z.string()).readonly().parse({ a: "b" }))).toBe(true);
|
||||
expect(Object.isFrozen(z.record(z.string(), z.number()).readonly().parse({ a: 1 }))).toBe(true);
|
||||
expect(Object.isFrozen(z.object({ a: z.string(), 1: z.number() }).readonly().parse({ a: "b", 1: 2 }))).toBe(true);
|
||||
expect(Object.isFrozen(z.promise(z.string()).readonly().parse(Promise.resolve("a")))).toBe(true);
|
||||
});
|
||||
|
||||
test("async object freezing", async () => {
|
||||
expect(Object.isFrozen(await z.array(z.string()).readonly().parseAsync(["a"]))).toBe(true);
|
||||
expect(Object.isFrozen(await z.tuple([z.string(), z.number()]).readonly().parseAsync(["a", 1]))).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(
|
||||
await z
|
||||
.map(z.string(), z.date())
|
||||
.readonly()
|
||||
.parseAsync(new Map([["a", new Date()]]))
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(
|
||||
await z
|
||||
.set(z.promise(z.string()))
|
||||
.readonly()
|
||||
.parseAsync(new Set([Promise.resolve("a")]))
|
||||
)
|
||||
).toBe(true);
|
||||
expect(Object.isFrozen(await z.record(z.string()).readonly().parseAsync({ a: "b" }))).toBe(true);
|
||||
expect(Object.isFrozen(await z.record(z.string(), z.number()).readonly().parseAsync({ a: 1 }))).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(await z.object({ a: z.string(), 1: z.number() }).readonly().parseAsync({ a: "b", 1: 2 }))
|
||||
).toBe(true);
|
||||
expect(Object.isFrozen(await z.promise(z.string()).readonly().parseAsync(Promise.resolve("a")))).toBe(true);
|
||||
});
|
171
node_modules/zod/src/v3/tests/record.test.ts
generated
vendored
Normal file
171
node_modules/zod/src/v3/tests/record.test.ts
generated
vendored
Normal file
|
@ -0,0 +1,171 @@
|
|||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
const booleanRecord = z.record(z.boolean());
|
||||
type booleanRecord = z.infer<typeof booleanRecord>;
|
||||
|
||||
const recordWithEnumKeys = z.record(z.enum(["Tuna", "Salmon"]), z.string());
|
||||
type recordWithEnumKeys = z.infer<typeof recordWithEnumKeys>;
|
||||
|
||||
const recordWithLiteralKeys = z.record(z.union([z.literal("Tuna"), z.literal("Salmon")]), z.string());
|
||||
type recordWithLiteralKeys = z.infer<typeof recordWithLiteralKeys>;
|
||||
|
||||
test("type inference", () => {
|
||||
util.assertEqual<booleanRecord, Record<string, boolean>>(true);
|
||||
|
||||
util.assertEqual<recordWithEnumKeys, Partial<Record<"Tuna" | "Salmon", string>>>(true);
|
||||
|
||||
util.assertEqual<recordWithLiteralKeys, Partial<Record<"Tuna" | "Salmon", string>>>(true);
|
||||
});
|
||||
|
||||
test("methods", () => {
|
||||
booleanRecord.optional();
|
||||
booleanRecord.nullable();
|
||||
});
|
||||
|
||||
test("string record parse - pass", () => {
|
||||
booleanRecord.parse({
|
||||
k1: true,
|
||||
k2: false,
|
||||
1234: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("string record parse - fail", () => {
|
||||
const badCheck = () =>
|
||||
booleanRecord.parse({
|
||||
asdf: 1234,
|
||||
} as any);
|
||||
expect(badCheck).toThrow();
|
||||
|
||||
expect(() => booleanRecord.parse("asdf")).toThrow();
|
||||
});
|
||||
|
||||
test("string record parse - fail", () => {
|
||||
const badCheck = () =>
|
||||
booleanRecord.parse({
|
||||
asdf: {},
|
||||
} as any);
|
||||
expect(badCheck).toThrow();
|
||||
});
|
||||
|
||||
test("string record parse - fail", () => {
|
||||
const badCheck = () =>
|
||||
booleanRecord.parse({
|
||||
asdf: [],
|
||||
} as any);
|
||||
expect(badCheck).toThrow();
|
||||
});
|
||||
|
||||
test("key schema", () => {
|
||||
const result1 = recordWithEnumKeys.parse({
|
||||
Tuna: "asdf",
|
||||
Salmon: "asdf",
|
||||
});
|
||||
expect(result1).toEqual({
|
||||
Tuna: "asdf",
|
||||
Salmon: "asdf",
|
||||
});
|
||||
|
||||
const result2 = recordWithLiteralKeys.parse({
|
||||
Tuna: "asdf",
|
||||
Salmon: "asdf",
|
||||
});
|
||||
expect(result2).toEqual({
|
||||
Tuna: "asdf",
|
||||
Salmon: "asdf",
|
||||
});
|
||||
|
||||
// shouldn't require us to specify all props in record
|
||||
const result3 = recordWithEnumKeys.parse({
|
||||
Tuna: "abcd",
|
||||
});
|
||||
expect(result3).toEqual({
|
||||
Tuna: "abcd",
|
||||
});
|
||||
|
||||
// shouldn't require us to specify all props in record
|
||||
const result4 = recordWithLiteralKeys.parse({
|
||||
Salmon: "abcd",
|
||||
});
|
||||
expect(result4).toEqual({
|
||||
Salmon: "abcd",
|
||||
});
|
||||
|
||||
expect(() =>
|
||||
recordWithEnumKeys.parse({
|
||||
Tuna: "asdf",
|
||||
Salmon: "asdf",
|
||||
Trout: "asdf",
|
||||
})
|
||||
).toThrow();
|
||||
|
||||
expect(() =>
|
||||
recordWithLiteralKeys.parse({
|
||||
Tuna: "asdf",
|
||||
Salmon: "asdf",
|
||||
|
||||
Trout: "asdf",
|
||||
})
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
// test("record element", () => {
|
||||
// expect(booleanRecord.element).toBeInstanceOf(z.ZodBoolean);
|
||||
// });
|
||||
|
||||
test("key and value getters", () => {
|
||||
const rec = z.record(z.string(), z.number());
|
||||
|
||||
rec.keySchema.parse("asdf");
|
||||
rec.valueSchema.parse(1234);
|
||||
rec.element.parse(1234);
|
||||
});
|
||||
|
||||
test("is not vulnerable to prototype pollution", async () => {
|
||||
const rec = z.record(
|
||||
z.object({
|
||||
a: z.string(),
|
||||
})
|
||||
);
|
||||
|
||||
const data = JSON.parse(`
|
||||
{
|
||||
"__proto__": {
|
||||
"a": "evil"
|
||||
},
|
||||
"b": {
|
||||
"a": "good"
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const obj1 = rec.parse(data);
|
||||
expect(obj1.a).toBeUndefined();
|
||||
|
||||
const obj2 = rec.safeParse(data);
|
||||
expect(obj2.success).toBe(true);
|
||||
if (obj2.success) {
|
||||
expect(obj2.data.a).toBeUndefined();
|
||||
}
|
||||
|
||||
const obj3 = await rec.parseAsync(data);
|
||||
expect(obj3.a).toBeUndefined();
|
||||
|
||||
const obj4 = await rec.safeParseAsync(data);
|
||||
expect(obj4.success).toBe(true);
|
||||
if (obj4.success) {
|
||||
expect(obj4.data.a).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
test("dont parse undefined values", () => {
|
||||
const result1 = z.record(z.any()).parse({ foo: undefined });
|
||||
|
||||
expect(result1).toEqual({
|
||||
foo: undefined,
|
||||
});
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue