Switch to zshy (#4777)

* Initial move

* Move files

* WIP

* WIP

* WIP

* WIP

* Add rolldown.cjs.js

* WIP

* WIP

* Clean package.json

* WIP

* WIP

* WIP

* WIP

* WIP

* Add tsdown

* WIP

* WIP

* WIP

* WIP

* Rename zbuild

* Rename zbuild

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* Improve zshy

* WIP

* WIP

* WIP

* Tweak

* Remove old build files

* Add resolution tests

* Fix all noUncheckedIndexedAccess issues

* WIP

* Clean up

* Fix lint

* Add ATTW test

* Update snaps

* Update snaps

* Update snaps
This commit is contained in:
Colin McDonnell
2025-07-02 00:43:43 -07:00
committed by GitHub
parent 4512c08911
commit 55b6ed1b1b
285 changed files with 1105 additions and 761 deletions
+5 -4
View File
@@ -8,11 +8,12 @@
"strict": true,
"alwaysStrict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"noUnusedLocals": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitAny": true,
"noImplicitReturns": true,
@@ -29,7 +30,7 @@
"downlevelIteration": true,
"isolatedModules": true,
"pretty": true,
"customConditions": ["@zod/source"]
}
"pretty": true
},
"exclude": ["node_modules"]
}
+1
View File
@@ -27,6 +27,7 @@ jobs:
- run: pnpm add typescript@${{ matrix.typescript }} -w
- run: pnpm build
- run: pnpm test
- run: pnpm run --filter @zod/resolution test
lint:
runs-on: ubuntu-latest
+3
View File
@@ -1,3 +1,4 @@
.env
**/.DS_Store
node_modules
/lib
@@ -21,3 +22,5 @@ packages/tsc-perf
tsconfig.vitest-temp.json
*.tgz
+2
View File
@@ -11,6 +11,8 @@
"files.exclude": {
"./scratch": false,
"**/.tshy-build": true,
"**/*.{js,cjs,mjs}": true,
"**/*.d.{ts,cts,mts}": true,
"**/dist": true,
"**/lib": true
},
+7
View File
@@ -60,7 +60,14 @@
}
},
"files": {
"include": ["**/*.ts", "**/*.mts", "**/*.cts"],
"ignore": [
"*.js",
"*.mjs",
"*.cjs",
"*.d.ts",
"*.d.cts",
"*.d.mts",
"lib",
"coverage",
"dist",
+8 -3
View File
@@ -24,6 +24,7 @@
"benchmark": "^2.1.4",
"chalk": "^5.4.1",
"console-table-printer": "^2.12.1",
"esbuild": "^0.25.5",
"execa": "^9.5.2",
"globby": "^14.1.0",
"husky": "^9.1.7",
@@ -33,17 +34,19 @@
"prettier": "^3.5.3",
"recheck": "^4.5.0",
"rolldown": "1.0.0-beta.18",
"rollup": "^4.39.0",
"semver": "^7.7.2",
"supershy": "^1.0.0",
"tinybench": "^2.9.0",
"ts-morph": "^14.0.0",
"tsdown": "^0.11.9",
"tsdown": "^0.12.8",
"tslib": "^2.8.1",
"tsx": "^4.19.3",
"typescript": "^5.5.4",
"vitest": "^2.1.9",
"zod": "workspace:*",
"zod3": "npm:zod@^3.0.0"
"zod3": "npm:zod@~3.24.0",
"zshy": "^0.0.12"
},
"lint-staged": {
"packages/*/src/**/*.ts": [
@@ -54,7 +57,9 @@
"biome format --no-errors-on-unmatched --write",
"biome lint --no-errors-on-unmatched --write"
],
"packages/*/**/*.md": ["prettier --ignore-unknown --write"]
"packages/*/**/*.md": [
"prettier --ignore-unknown --write"
]
},
"scripts": {
"fix": "pnpm run format && pnpm run lint",
+1
View File
@@ -0,0 +1 @@
package-lock.json
+7
View File
@@ -0,0 +1,7 @@
# Zod perftesting
`node generateRandomSchemas.js` to generate some random Zod schemas (pregenerated ones already exist in `src/index.ts`)
`npm run build-bench` to run `tsc` with `extendedDiagnostics`
Either modify zod's typings in `node_modules/zod` or `npm link` a local copy and do modifications there. Remember to build `zod` in between!
+107
View File
@@ -0,0 +1,107 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import { execa } from "execa";
import { describe, expect, it } from "vitest";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
describe("Are The Types Wrong (attw) tests", () => {
it("should run attw --pack node_modules/zod and check output", async () => {
const result = await execa("pnpm", ["attw", "--pack", "node_modules/zod", "--format", "ascii"], {
cwd: __dirname,
reject: false, // Don't throw on non-zero exit codes
});
// Combine stdout and stderr for comprehensive output
const output = result.stdout + (result.stderr ? "\n" + result.stderr : "");
expect(output.trim()).toMatchInlineSnapshot(`
"zod v3.25.67
🎭 Import resolved to a CommonJS type declaration file, but an ESM JavaScript file. https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md
"zod/package.json"
node10: 🟢 (JSON)
node16 (from CJS): 🟢 (JSON)
node16 (from ESM): 🟢 (JSON)
bundler: 🟢 (JSON)
***********************************
"zod"
node10: 🟢
node16 (from CJS): 🟢 (CJS)
node16 (from ESM): 🎭 Masquerading as CJS
bundler: 🟢
***********************************
"zod/v3"
node10: 🟢
node16 (from CJS): 🟢 (CJS)
node16 (from ESM): 🎭 Masquerading as CJS
bundler: 🟢
***********************************
"zod/v4"
node10: 🟢
node16 (from CJS): 🟢 (CJS)
node16 (from ESM): 🎭 Masquerading as CJS
bundler: 🟢
***********************************
"zod/v4-mini"
node10: 🟢
node16 (from CJS): 🟢 (CJS)
node16 (from ESM): 🎭 Masquerading as CJS
bundler: 🟢
***********************************
"zod/v4/mini"
node10: 🟢
node16 (from CJS): 🟢 (CJS)
node16 (from ESM): 🎭 Masquerading as CJS
bundler: 🟢
***********************************
"zod/v4/core"
node10: 🟢
node16 (from CJS): 🟢 (CJS)
node16 (from ESM): 🎭 Masquerading as CJS
bundler: 🟢
***********************************
"zod/v4/locales"
node10: 🟢
node16 (from CJS): 🟢 (CJS)
node16 (from ESM): 🎭 Masquerading as CJS
bundler: 🟢
***********************************
"zod/v4/locales/*"
node10: (wildcard)
node16 (from CJS): (wildcard)
node16 (from ESM): (wildcard)
bundler: (wildcard)
***********************************"
`);
}, 30000); // 30 second timeout for the command
});
+35
View File
@@ -0,0 +1,35 @@
{
"name": "@zod/resolution",
"type": "module",
"private": true,
"version": "1.0.0",
"main": "./dist/index.cjs",
"license": "MIT",
"devDependencies": {
"@types/node": "^22.13.13",
"execa": "^9.5.2",
"typescript": "^5.8.2"
},
"files": [
"./bin/*",
"./lib/*"
],
"typings": "./lib/index.d.ts",
"scripts": {
"test": "pnpm vitest run && tsx test-resolution.ts",
"test:vitest": "vitest"
},
"zshy": "./src/index.ts",
"module": "./dist/index.js",
"types": "./dist/index.d.cts",
"exports": {
".": {
"types": "./dist/index.d.cts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
},
"dependencies": {
"zod": "workspace:*"
}
}
+35
View File
@@ -0,0 +1,35 @@
import * as z1 from "zod";
import z2 from "zod";
import { z as z3 } from "zod";
import * as z5 from "zod/v3";
import * as z4 from "zod/v4";
import * as z7 from "zod/v4-mini";
import fr from "zod/v4/locales/fr.cjs";
import * as z6 from "zod/v4/mini";
console.log(z1.string().parse("Hello, world!"));
console.log(z2.string().parse("Hello, world!"));
console.log(z3.string().parse("Hello, world!"));
console.log(z4.string().parse("Hello, world!"));
console.log(z5.string().parse("Hello, world!"));
console.log(z6.string().parse("Hello, world!"));
console.log(z7.string().parse("Hello, world!"));
z4.config(fr());
const schema = z4.object({
name: z4.string(),
});
const success = JSON.stringify(schema.safeParse({ name: "John Doe" }));
if (success !== `{"success":true,"data":{"name":"John Doe"}}`) {
throw new Error();
}
const failure = JSON.stringify(schema.safeParse({ name: 123 }));
if (
failure !==
'{"success":false,"error":{"name":"ZodError","message":"[\\n {\\n \\"expected\\": \\"string\\",\\n \\"code\\": \\"invalid_type\\",\\n \\"path\\": [\\n \\"name\\"\\n ],\\n \\"message\\": \\"Entrée invalide : string attendu, nombre reçu\\"\\n }\\n]"}}'
) {
throw new Error();
}
console.log("Success!");
+35
View File
@@ -0,0 +1,35 @@
import * as z1 from "zod";
import z2 from "zod";
import { z as z3 } from "zod";
import * as z5 from "zod/v3";
import * as z4 from "zod/v4";
import * as z7 from "zod/v4-mini";
import fr from "zod/v4/locales/fr.js";
import * as z6 from "zod/v4/mini";
console.log(z1.string().parse("Hello, world!"));
console.log(z2.string().parse("Hello, world!"));
console.log(z3.string().parse("Hello, world!"));
console.log(z4.string().parse("Hello, world!"));
console.log(z5.string().parse("Hello, world!"));
console.log(z6.string().parse("Hello, world!"));
console.log(z7.string().parse("Hello, world!"));
z4.config(fr());
const schema = z4.object({
name: z4.string(),
});
const success = JSON.stringify(schema.safeParse({ name: "John Doe" }));
if (success !== `{"success":true,"data":{"name":"John Doe"}}`) {
throw new Error();
}
const failure = JSON.stringify(schema.safeParse({ name: 123 }));
if (
failure !==
'{"success":false,"error":{"name":"ZodError","message":"[\\n {\\n \\"expected\\": \\"string\\",\\n \\"code\\": \\"invalid_type\\",\\n \\"path\\": [\\n \\"name\\"\\n ],\\n \\"message\\": \\"Entrée invalide : string attendu, nombre reçu\\"\\n }\\n]"}}'
) {
throw new Error();
}
console.log("Success!");
+35
View File
@@ -0,0 +1,35 @@
import * as z1 from "zod";
import z2 from "zod";
import { z as z3 } from "zod";
import * as z5 from "zod/v3";
import * as z4 from "zod/v4";
import * as z7 from "zod/v4-mini";
import fr from "zod/v4/locales/fr.js";
import * as z6 from "zod/v4/mini";
console.log(z1.string().parse("Hello, world!"));
console.log(z2.string().parse("Hello, world!"));
console.log(z3.string().parse("Hello, world!"));
console.log(z4.string().parse("Hello, world!"));
console.log(z5.string().parse("Hello, world!"));
console.log(z6.string().parse("Hello, world!"));
console.log(z7.string().parse("Hello, world!"));
z4.config(fr());
const schema = z4.object({
name: z4.string(),
});
const success = JSON.stringify(schema.safeParse({ name: "John Doe" }));
if (success !== `{"success":true,"data":{"name":"John Doe"}}`) {
throw new Error();
}
const failure = JSON.stringify(schema.safeParse({ name: 123 }));
if (
failure !==
'{"success":false,"error":{"name":"ZodError","message":"[\\n {\\n \\"expected\\": \\"string\\",\\n \\"code\\": \\"invalid_type\\",\\n \\"path\\": [\\n \\"name\\"\\n ],\\n \\"message\\": \\"Entrée invalide : string attendu, nombre reçu\\"\\n }\\n]"}}'
) {
throw new Error();
}
console.log("Tests are passing");
+98
View File
@@ -0,0 +1,98 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import { execa } from "execa";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
async function buildZshy() {
console.log("🔨 Building project with zshy...");
try {
await execa("zshy", [], {
cwd: __dirname,
stdio: "inherit",
});
// console.log('✅ Build completed successfully!');
} catch (error) {
console.error("❌ Error building project:", error);
process.exit(1);
}
}
async function buildTsc() {
console.log("🔨 Building project with tsc...");
try {
await execa("tsc", ["--project", "tsconfig.build.json"], {
cwd: __dirname,
stdio: "inherit",
});
// console.log('✅ Build completed successfully!');
} catch (error) {
console.error("❌ Error building project:", error);
process.exit(1);
}
}
async function testCjs() {
console.log("🧪 Testing CommonJS build...");
try {
await execa("node", ["./dist/index.cjs"], {
cwd: __dirname,
stdio: "inherit",
});
console.log("✅ CommonJS test passed!");
} catch (error) {
console.error("❌ CommonJS test failed:", error);
process.exit(1);
}
}
async function testMjs() {
console.log("🧪 Testing CommonJS build...");
try {
await execa("node", ["./dist/index.mjs"], {
cwd: __dirname,
stdio: "inherit",
});
console.log("✅ CommonJS test passed!");
} catch (error) {
console.error("❌ CommonJS test failed:", error);
process.exit(1);
}
}
async function testJs() {
console.log("🧪 Testing ES Module build...");
try {
await execa("node", ["./dist/index.js"], {
cwd: __dirname,
stdio: "inherit",
});
console.log("✅ ES Module test passed!");
} catch (error) {
console.error("❌ ES Module test failed:", error);
process.exit(1);
}
}
async function runAllTests() {
console.log("🚀 Starting comprehensive resolution tests...\n");
try {
await buildZshy();
await testCjs();
await testJs();
await buildTsc();
await testMjs();
await testCjs();
console.log("🎉 All tests passed successfully!");
} catch (error) {
console.error("💥 Test suite failed:", error);
process.exit(1);
}
}
// Run the test suite
runAllTests();
+11
View File
@@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"target": "es6",
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"emitDeclarationOnly": false
},
"include": ["src/*.ts", "src/*.mts", "src/*.cts"],
}
+8
View File
@@ -0,0 +1,8 @@
{
"extends": "../../.configs/tsconfig.base.json",
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler",
},
"include": ["**/*.ts", "**/*.mts", "**/*.cts"],
}
+8
View File
@@ -0,0 +1,8 @@
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
globals: true,
environment: "node",
},
});
+2 -2
View File
@@ -337,14 +337,14 @@ function generateFields(
// keys.push(key);
const randomTypeIndex = Math.floor(Math.random() * params.valueTypes.length);
const randomChainMethodIndex = Math.floor(Math.random() * methods.length);
const randomType = params.valueTypes[randomTypeIndex];
const randomType = params.valueTypes[randomTypeIndex]!;
// const randomChance = Math.random();
// if (randomChance > 0.98) {
// const { schema: nestedSchema } = generateRandomZodSchema();
// schema += ` ${key}: ${nestedSchema},`;
// continue;
// }
const type = randomType + methods[randomChainMethodIndex];
const type = randomType + methods[randomChainMethodIndex]!;
fields.push({ key, schema: type });
// schema += ` ${key}: ${type},`;
+7
View File
@@ -0,0 +1,7 @@
_virtual
**/*.js
**/*.mjs
**/*.cjs
**/*.d.ts
**/*.d.mts
**/*.d.cts
-123
View File
@@ -1,123 +0,0 @@
// import * as fs from "node:fs";
// import * as path from "node:path";
import * as fs from "node:fs";
import * as path from "node:path";
import { execaSync } from "execa";
// import { globbySync } from "globby";
const $ = execaSync({ stdio: "inherit" });
$`rm -rf ./dist`;
function writePackageJson(dir: string, fields: Record<string, any>) {
const packageJsonPath = path.join(path.resolve(dir), "package.json");
fs.mkdirSync(dir, {
recursive: true,
});
console.log(`writing package.json to ${packageJsonPath}...`);
fs.writeFileSync(packageJsonPath, JSON.stringify(fields, null, 2));
return packageJsonPath;
}
console.log("building ESM...");
const esmPkg = writePackageJson("./src", { type: "module" });
$`pnpm tsc -p tsconfig.esm.json`;
fs.rmSync(esmPkg, { force: true });
// const esmDistDir = path.resolve("./dist/esm");
// const esmPackageJsonPath = path.join(esmDistDir, "package.json");
// fs.mkdirSync(esmDistDir, { recursive: true });
// fs.writeFileSync(esmPackageJsonPath, JSON.stringify({ type: "module" }, null, 2));
writePackageJson("./dist/esm", { type: "module" });
console.log("building CJS...");
const cjsPkg = writePackageJson("./src", { type: "commonjs" });
$`pnpm tsc -p tsconfig.cjs.json`;
fs.rmSync(cjsPkg, { force: true });
// const cjsPath = "./dist/cjs";
// const cjsDistDir = path.resolve(cjsPath);
// const cjsPackageJsonPath = path.join(path.resolve(cjsPath), "package.json");
// fs.mkdirSync(cjsDistDir, { recursive: true });
// fs.writeFileSync(cjsPackageJsonPath, JSON.stringify({ type: "commonjs" }, null, 2));
writePackageJson("./dist/cjs", { type: "commonjs" });
console.log("building types...");
$`pnpm tsc -p tsconfig.types.json`;
// const typesPath = "./dist/types";
// const typesDistDir = path.resolve(typesPath);
// const typesPackageJsonPath = path.join(path.resolve(typesPath), "package.json");
// fs.mkdirSync(typesDistDir, { recursive: true });
// fs.writeFileSync(typesPackageJsonPath, JSON.stringify({ type: "module" }, null, 2));
writePackageJson("./dist/types", { type: "commonjs" });
console.log("DONE.");
// /**
// * Synchronously builds TypeScript projects (ESM and CommonJS)
// * and recursively renames all .js files in the dist directory to .mjs.
// * Uses execa's $.sync for shell commands and globbySync for file finding.
// * Pipes subprocess logs (stdout/stderr) to the main process.
// */
// // Resolve the absolute path to the 'dist' directory
// const distDir = path.resolve("./dist");
// // Check if the 'dist' directory exists and remove it if it does
// // The 'recursive' and 'force' options ensure it works for non-empty directories
// // and doesn't throw an error if the directory doesn't exist.
// console.log("Cleaning up old dist directory..."); // Added log for clarity
// if (fs.existsSync(distDir)) {
// // Use rmdirSync instead of rmSync for compatibility
// fs.rmSync(distDir, { recursive: true });
// console.log("Dist directory cleaned."); // Added log for clarity
// } else {
// console.log("Dist directory does not exist, skipping clean-up."); // Added log for clarity
// }
// console.log("Compiling ES modules..."); // Added log for clarity
// // Compile ES modules using pnpm tsc with the specified tsconfig
// // $.sync executes the command synchronously and waits for it to complete.
// // stdio: 'inherit' pipes the subprocess's stdout and stderr to the main process's console.
// $`pnpm tsc -p tsconfig.esm.json`;
// console.log("ES modules compiled."); // Added log for clarity
// {
// console.log("Renaming .js files to .mjs in dist directory..."); // Added log for clarity
// const tsFiles = globbySync(`${distDir}/**/*.js`, {
// onlyFiles: true,
// });
// // Iterate over each found .js file and rename it to .mjs
// for (const file of tsFiles) {
// if (file.endsWith(".mjs")) continue; // skip if already .mjs
// // Create the new path by replacing the .js extension with .mjs
// const newPath = file.replace(/\.js$/, ".mjs");
// // Execute the 'mv' command synchronously to rename the file
// // Using $.sync for this shell command as well, with stdio inherited.
// fs.renameSync(file, newPath);
// }
// console.log("Files renamed to .mjs."); // Added log for clarity
// }
// console.log("Compiling CommonJS modules..."); // Added log for clarity
// // Compile CommonJS modules using pnpm tsc with the specified tsconfig
// // stdio: 'inherit' pipes the subprocess's stdout and stderr to the main process's console.
// $`pnpm tsc -p tsconfig.cjs.json`;
// console.log("CommonJS modules compiled."); // Added log for clarity
// console.log("Build process completed successfully!"); // Added log for clarity
// {
// console.log("Renaming .js files to .mjs in dist directory..."); // Added log for clarity
// const tsFiles = globbySync(`${distDir}/**/*.js`, {
// onlyFiles: true,
// });
// // Iterate over each found .js file and rename it to .mjs
// for (const file of tsFiles) {
// if (file.endsWith(".cjs")) continue; // skip if already .mjs
// // Create the new path by replacing the .js extension with .mjs
// const newPath = file.replace(/\.js$/, ".cjs");
// // Execute the 'mv' command synchronously to rename the file
// // Using $.sync for this shell command as well, with stdio inherited.
// fs.renameSync(file, newPath);
// }
// console.log("Files renamed to .cjs."); // Added log for clarity
// }
+4
View File
@@ -0,0 +1,4 @@
import * as z from "./v3/index.js";
export * from "./v3/index.js";
export { z };
export default z;
+84 -86
View File
@@ -4,97 +4,94 @@
"type": "module",
"author": "Colin McDonnell <[email protected]>",
"description": "TypeScript-first schema declaration and validation library with static type inference",
"files": ["dist", "v3", "v4", "v4-mini"],
"files": [
"**/*.js",
"**/*.mjs",
"**/*.cjs",
"**/*.d.ts",
"**/*.d.mts",
"**/*.d.cts"
],
"funding": "https://github.com/sponsors/colinhacks",
"homepage": "https://zod.dev",
"keywords": ["typescript", "schema", "validation", "type", "inference"],
"keywords": [
"typescript",
"schema",
"validation",
"type",
"inference"
],
"license": "MIT",
"sideEffects": false,
"main": "./dist/cjs/index.js",
"types": "./dist/types/index.d.ts",
"module": "./dist/esm/index.js",
"exports": {
".": {
"import": {
"@zod/source": "./src/index.ts",
"types": "./dist/types/index.d.ts",
"default": "./dist/esm/index.js"
},
"require": {
"@zod/source": "./src/index.ts",
"types": "./dist/types/index.d.ts",
"default": "./dist/cjs/index.js"
}
},
"./v3": {
"import": {
"@zod/source": "./src/index.ts",
"types": "./dist/types/index.d.ts",
"default": "./dist/esm/index.js"
},
"require": {
"@zod/source": "./src/index.ts",
"types": "./dist/types/index.d.ts",
"default": "./dist/cjs/index.js"
}
},
"./v4": {
"import": {
"@zod/source": "./src/v4/index.ts",
"types": "./dist/types/v4/index.d.ts",
"default": "./dist/esm/v4/index.js"
},
"require": {
"@zod/source": "./src/v4/index.ts",
"types": "./dist/types/v4/index.d.ts",
"default": "./dist/cjs/v4/index.js"
}
},
"./v4-mini": {
"@zod/source": "./src/v4/mini/index.ts",
"types": "./dist/types/v4/mini/index.d.ts",
"import": "./dist/esm/v4/mini/index.js",
"require": "./dist/cjs/v4/mini/index.js"
},
"./v4/mini": {
"@zod/source": "./src/v4/mini/index.ts",
"types": "./dist/types/v4/mini/index.d.ts",
"import": "./dist/esm/v4/mini/index.js",
"require": "./dist/cjs/v4/mini/index.js"
},
"./v4/core": {
"@zod/source": "./src/v4/core/index.ts",
"types": "./dist/types/v4/core/index.d.ts",
"import": "./dist/esm/v4/core/index.js",
"require": "./dist/cjs/v4/core/index.js"
},
"./v4/locales": {
"@zod/source": "./src/v4/locales/index.ts",
"types": "./dist/types/v4/locales/index.d.ts",
"import": "./dist/esm/v4/locales/index.js",
"require": "./dist/cjs/v4/locales/index.js"
},
"./v4/locales/*": {
"@zod/source": "./src/v4/locales/*",
"types": "./dist/types/v4/locales/*",
"import": "./dist/esm/v4/locales/*",
"require": "./dist/cjs/v4/locales/*"
},
"./package.json": "./package.json"
},
"tshy": {
"main": "./index.cjs",
"types": "./index.d.cts",
"module": "./index.js",
"zshy": {
"exports": {
"./package.json": "./package.json",
".": "./src/index.ts",
"./v3": "./src/v3/index.ts",
"./v4": "./src/v4/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/*"
".": "./index.ts",
"./v3": "./v3/index.ts",
"./v4": "./v4/index.ts",
"./v4-mini": "./v4-mini/index.ts",
"./v4/mini": "./v4/mini/index.ts",
"./v4/core": "./v4/core/index.ts",
"./v4/locales": "./v4/locales/index.ts",
"./v4/locales/*": "./v4/locales/*"
},
"sourceDialects": ["@zod/source"],
"exclude": ["./src/**/*.test.ts"]
"sourceDialects": [
"@zod/source"
]
},
"exports": {
"./package.json": "./package.json",
".": {
"@zod/source": "./index.ts",
"types": "./index.d.cts",
"import": "./index.js",
"require": "./index.cjs"
},
"./v3": {
"@zod/source": "./v3/index.ts",
"types": "./v3/index.d.cts",
"import": "./v3/index.js",
"require": "./v3/index.cjs"
},
"./v4": {
"@zod/source": "./v4/index.ts",
"types": "./v4/index.d.cts",
"import": "./v4/index.js",
"require": "./v4/index.cjs"
},
"./v4-mini": {
"@zod/source": "./v4-mini/index.ts",
"types": "./v4-mini/index.d.cts",
"import": "./v4-mini/index.js",
"require": "./v4-mini/index.cjs"
},
"./v4/mini": {
"@zod/source": "./v4/mini/index.ts",
"types": "./v4/mini/index.d.cts",
"import": "./v4/mini/index.js",
"require": "./v4/mini/index.cjs"
},
"./v4/core": {
"@zod/source": "./v4/core/index.ts",
"types": "./v4/core/index.d.cts",
"import": "./v4/core/index.js",
"require": "./v4/core/index.cjs"
},
"./v4/locales": {
"@zod/source": "./v4/locales/index.ts",
"types": "./v4/locales/index.d.cts",
"import": "./v4/locales/index.js",
"require": "./v4/locales/index.cjs"
},
"./v4/locales/*": {
"@zod/source": "./v4/locales/*",
"types": "./v4/locales/*",
"import": "./v4/locales/*",
"require": "./v4/locales/*"
}
},
"repository": {
"type": "git",
@@ -109,11 +106,12 @@
}
},
"scripts": {
"clean": "rm -rf dist",
"build": "tsx ./build.mts",
"clean": "rm -rf dist && git clean -qxdf . -e node_modules",
"build": "pnpm clean && zshy",
"postbuild": "pnpm biome check --write .",
"test:watch": "pnpm vitest",
"test": "pnpm vitest run",
"test:resolution": "pnpm build && pnpm attw --pack . && pnpm run --filter @zod/resolution test",
"bump:beta": "pnpm version \"v$(pnpm pkg get version | jq -r)-beta.$(date +%Y%m%dT%H%M%S)\"",
"pub:beta": "pnpm bump:beta && pnpm publish --tag next --publish-branch v4 --no-git-checks --dry-run"
}
-25
View File
@@ -1,25 +0,0 @@
// rolldown.config.ts
import { defineConfig } from "rolldown";
export default defineConfig({
// 1. point at your entry modules (could be a glob or single file)
input: ["v3/index.ts", "v4/index.ts", "v4/mini/index.ts"],
// 2. tell Rolldown to emit one .js file per module, preserving your src tree
output: {
dir: ".",
format: "esm", // TS “module”: "esnext" → ESM
preserveModules: true, // no bundling; one output per input
preserveModulesRoot: "src",
// use .mts for all emitted files
entryFileNames: "[name].mts",
chunkFileNames: "[name].mts",
},
// 3. have it pick up your tsconfig base + customConditions
// tsconfigFilename: "./tsconfig.json", // will extend your base config
resolve: {
tsconfigFilename: "./tsconfig.json", // will extend your base config
// conditions: ["@zod/source"], // customConditions ↔ resolve.conditions :contentReference[oaicite:1]{index=1}
},
});
-4
View File
@@ -1,4 +0,0 @@
import z3 from "./v3/index.js";
export * from "./v3/index.js";
export default z3;
-1
View File
@@ -1 +0,0 @@
export { parse, safeParse, parseAsync, safeParseAsync } from "zod/v4/core";
-12
View File
@@ -1,12 +0,0 @@
{
"extends": "../../.configs/tsconfig.base.json",
"compilerOptions": {
"rootDir": "./src",
"module": "Node16",
"moduleResolution": "node16",
"customConditions": ["@zod/source"],
"outDir": "./dist/cjs"
},
"include": ["src"],
"exclude": ["**/tests/**"]
}
-12
View File
@@ -1,12 +0,0 @@
{
"extends": "../../.configs/tsconfig.base.json",
"compilerOptions": {
"rootDir": "./src",
"module": "esnext",
"moduleResolution": "bundler",
"customConditions": ["@zod/source"],
"outDir": "./dist/esm"
},
"include": ["src"],
"exclude": ["**/tests/**"]
}
+7 -4
View File
@@ -1,9 +1,12 @@
{
"extends": "../../.configs/tsconfig.base.json",
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "nodenext",
"customConditions": ["@zod/source"]
"module": "node16",
"moduleResolution": "node16",
"customConditions": ["@zod/source"],
"esModuleInterop": true,
"rootDir": ".",
"outDir": "."
},
"exclude": ["vitest.config.ts"]
"include": ["**/*.ts"]
}
-15
View File
@@ -1,15 +0,0 @@
{
"extends": "../../.configs/tsconfig.base.json",
"compilerOptions": {
"rootDir": "./src",
"module": "Node16",
"moduleResolution": "node16",
"customConditions": ["@zod/source"],
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "./dist/types",
"removeComments": false
},
"include": ["src"],
"exclude": ["**/tests/**"]
}
@@ -235,7 +235,7 @@ export class ZodError<T = any> extends Error {
let curr: any = fieldErrors;
let i = 0;
while (i < issue.path.length) {
const el = issue.path[i];
const el = issue.path[i]!;
const terminal = i === issue.path.length - 1;
if (!terminal) {
@@ -300,8 +300,9 @@ export class ZodError<T = any> extends Error {
const formErrors: U[] = [];
for (const sub of this.issues) {
if (sub.path.length > 0) {
fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];
fieldErrors[sub.path[0]].push(mapper(sub));
const firstEl = sub.path[0]!;
fieldErrors[firstEl] = fieldErrors[firstEl] || [];
fieldErrors[firstEl].push(mapper(sub));
} else {
formErrors.push(mapper(sub));
}
-3
View File
@@ -1,3 +0,0 @@
export * from "../dist/types/v3/index.js";
import z from "../dist/types/v3/index.js";
export default z;
-1
View File
@@ -1 +0,0 @@
export * from "../dist/esm/v3/index.js";
@@ -83,19 +83,18 @@ test("async preprocess ctx.addIssue with parse", async () => {
return data;
}, z.string());
expect(schema.parseAsync("asdf")).rejects.toThrow(
JSON.stringify(
[
{
code: "custom",
message: "custom error",
path: [],
},
],
null,
2
)
);
expect(await schema.safeParseAsync("asdf")).toMatchInlineSnapshot(`
{
"error": [ZodError: [
{
"code": "custom",
"message": "custom error",
"path": []
}
]],
"success": false,
}
`);
});
test("preprocess ctx.addIssue with parseAsync", async () => {

Some files were not shown because too many files have changed in this diff Show More