feat: MAC address validation in v4 and mini#5440
Conversation
WalkthroughThis PR introduces MAC address validation support to Zod. The changes add a new public API method Pre-merge checks❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/zod/src/v4/core/schemas.ts (1)
4305-4328: Wire MAC into the string format type unionNice job on the constructor, but the
$ZodStringFormatTypesunion still doesn’t list$ZodMAC, so the new schema never shows up in the exported type surface. Let’s drop it into that union right next to the other network formats.| $ZodIPv4 | $ZodIPv6 | $ZodCIDRv4 | $ZodCIDRv6 + | $ZodMAC | $ZodBase64
🧹 Nitpick comments (3)
packages/zod/src/v4/core/regexes.ts (1)
62-63: MAC regex looks solidEnforces 6 octets, consistent separator, and consistent letter case. Anchors and backrefs are correct. Nice.
Optional: add a short comment explaining the two-branch approach and backref group numbers to prevent accidental breakage later:
export const ipv6: RegExp = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/; +// MAC (48‑bit): either all‑upper or all‑lower hex pairs, with a consistent ":" or "-" separator. +// Note: group numbering matters — upper branch uses \3, lower branch uses \6 for the separator backref. export const mac: RegExp = /^(([0-9A-F]{2}([-:])[0-9A-F]{2}(\3[0-9A-F]{2}){4})|([0-9a-f]{2}([-:])[0-9a-f]{2}(\6[0-9a-f]{2}){4}))$/;packages/zod/src/v4/mini/tests/string.test.ts (1)
244-256: Mini mac tests cover the essentialsValid (colon/hyphen, mixed case variants) and invalid (separator/case mix, wrong type) are well covered.
Optional: add one more negative like "001A.2B3C.4D5E" (Cisco dotted) to assert nonstandard formats are rejected, or a digits-only positive like "00:11:22:33:44:55" to ensure case-consistency logic doesn't trip on numerals.
Also applies to: 503-505
packages/zod/src/v4/core/api.ts (1)
348-363: Factory looks right; consider trimming “version” from MAC paramsThe _mac() factory mirrors other formats. Minor: $ZodMACParams/$ZodCheckMACParams omit "version", which isn’t applicable to MAC; you can drop it for a tighter public type.
-export type $ZodMACParams = StringFormatParams<schemas.$ZodMAC, "pattern" | "when" | "version">; -export type $ZodCheckMACParams = CheckStringFormatParams<schemas.$ZodMAC, "pattern" | "when" | "version">; +export type $ZodMACParams = StringFormatParams<schemas.$ZodMAC, "pattern" | "when">; +export type $ZodCheckMACParams = CheckStringFormatParams<schemas.$ZodMAC, "pattern" | "when">;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
packages/docs/content/api.mdx(2 hunks)packages/docs/content/json-schema.mdx(1 hunks)packages/zod/src/v4/classic/schemas.ts(1 hunks)packages/zod/src/v4/classic/tests/continuability.test.ts(1 hunks)packages/zod/src/v4/classic/tests/string.test.ts(2 hunks)packages/zod/src/v4/classic/tests/template-literal.test.ts(5 hunks)packages/zod/src/v4/classic/tests/to-json-schema.test.ts(2 hunks)packages/zod/src/v4/core/api.ts(1 hunks)packages/zod/src/v4/core/regexes.ts(1 hunks)packages/zod/src/v4/core/schemas.ts(1 hunks)packages/zod/src/v4/locales/en.ts(1 hunks)packages/zod/src/v4/mini/schemas.ts(1 hunks)packages/zod/src/v4/mini/tests/string.test.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.{js,jsx,ts,tsx,mjs,cjs,json}
📄 CodeRabbit inference engine (CLAUDE.md)
Enforce line width of 120 characters via Biome formatting
Files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/core/regexes.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/core/api.tspackages/zod/src/v4/classic/tests/string.test.tspackages/zod/src/v4/locales/en.tspackages/zod/src/v4/core/schemas.ts
**/*.{js,jsx,ts,tsx,mjs,cjs}
📄 CodeRabbit inference engine (CLAUDE.md)
Use ES5-style trailing commas in JavaScript/TypeScript code
Files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/core/regexes.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/core/api.tspackages/zod/src/v4/classic/tests/string.test.tspackages/zod/src/v4/locales/en.tspackages/zod/src/v4/core/schemas.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Allow the any type in TypeScript (noExplicitAny off)
Allow non-null assertions in TypeScript (noNonNullAssertion off)
Write TypeScript to pass strict mode with exactOptionalPropertyTypes enabled
Use NodeNext module resolution semantics for imports in TypeScript
Target ES2020 language features in TypeScript source
Files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/core/regexes.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/core/api.tspackages/zod/src/v4/classic/tests/string.test.tspackages/zod/src/v4/locales/en.tspackages/zod/src/v4/core/schemas.ts
**/*.{ts,tsx,js,jsx,mjs,cjs}
📄 CodeRabbit inference engine (CLAUDE.md)
Allow parameter reassignment for performance-sensitive code (noParameterAssign off)
Files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/core/regexes.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/core/api.tspackages/zod/src/v4/classic/tests/string.test.tspackages/zod/src/v4/locales/en.tspackages/zod/src/v4/core/schemas.ts
**/*.{js,mjs,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)
**/*.{js,mjs,ts,tsx}: Use .js extensions in import specifiers (e.g., import { z } from "./index.js")
Don’t use require(); use ESM import statements
Files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/core/regexes.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/core/api.tspackages/zod/src/v4/classic/tests/string.test.tspackages/zod/src/v4/locales/en.tspackages/zod/src/v4/core/schemas.ts
**/*.{js,mjs,cjs,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Do not leave log statements (e.g., console.log, debugger) in tests or production code
Files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/core/regexes.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/core/api.tspackages/zod/src/v4/classic/tests/string.test.tspackages/zod/src/v4/locales/en.tspackages/zod/src/v4/core/schemas.ts
packages/**/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/zod-project-guide.mdc)
Write source code in TypeScript (TypeScript-first codebase)
Files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/core/regexes.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/core/api.tspackages/zod/src/v4/classic/tests/string.test.tspackages/zod/src/v4/locales/en.tspackages/zod/src/v4/core/schemas.ts
packages/zod/**
📄 CodeRabbit inference engine (.cursor/rules/zod-project-guide.mdc)
Make core Zod library changes in the main package at packages/zod/
Files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/core/regexes.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/core/api.tspackages/zod/src/v4/classic/tests/string.test.tspackages/zod/src/v4/locales/en.tspackages/zod/src/v4/core/schemas.ts
packages/**/*.test.ts
📄 CodeRabbit inference engine (.cursor/rules/zod-project-guide.mdc)
Use Vitest for tests and place test cases in .test.ts files
Files:
packages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.ts
packages/zod/src/{v4/classic/tests,v4/core/tests,v3/tests}/**/*
📄 CodeRabbit inference engine (.cursor/rules/testing-guidelines.mdc)
Place all test files under packages/zod/src/v4/classic/tests, packages/zod/src/v4/core/tests, or packages/zod/src/v3/tests
Files:
packages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.ts
packages/zod/src/{v4/classic/tests,v4/core/tests,v3/tests}/**/*.test.ts
📄 CodeRabbit inference engine (.cursor/rules/testing-guidelines.mdc)
packages/zod/src/{v4/classic/tests,v4/core/tests,v3/tests}/**/*.test.ts: Test files must use the .test.ts extension (TypeScript), not JavaScript
Use import type for type-only imports in tests (e.g.,import type { ... })
Permanent, regression, API validation, edge-case coverage, and performance benchmark tests must be in the test suite (not play.ts)
Use Vitest as the framework in tests and import from it asimport { expect, test } from "vitest"
Import Zod in tests asimport * as z from "zod/v4"
Write tests with clear, descriptive names and cover both success and failure cases
Keep test suites concise while maintaining adequate coverage
Do not skip tests due to type issues; fix the types instead
Use descriptive file names like string.test.ts, object.test.ts, url-validation.test.ts and group related functionality together
Files:
packages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.ts
packages/zod/src/v4/{classic,core}/tests/**/*.test.ts
📄 CodeRabbit inference engine (.cursor/rules/testing-workflow.mdc)
packages/zod/src/v4/{classic,core}/tests/**/*.test.ts: Use Vitest for all testing (Vitest APIs in test files)
Place tests under packages/zod/src/v4/classic/tests/ or packages/zod/src/v4/core/tests/
Name test files with the *.test.ts suffix
Use test() for individual test cases
Use describe() for test groups
Use expect() for assertions
Files:
packages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.ts
packages/zod/src/v4/core/{schemas.ts,core.ts}
📄 CodeRabbit inference engine (.cursor/rules/zod-internals.mdc)
Use the custom constructor system via core.$constructor() and initialize instances with $ZodType.init() when creating schemas
Files:
packages/zod/src/v4/core/schemas.ts
packages/zod/src/v4/core/schemas.ts
📄 CodeRabbit inference engine (.cursor/rules/zod-internals.mdc)
packages/zod/src/v4/core/schemas.ts: Wrapper schemas (e.g., $ZodOptional, $ZodNullable, $ZodReadonly) must pass through internal properties from their inner type using util.defineLazy for propValues, values, optin, and optout
Define computed internal properties using util.defineLazy() to avoid circular dependencies
Implement schema parse functions following the standard structure: type check, push invalid_type issue on mismatch, optionally coerce/transform, and return payload
For $ZodDiscriminatedUnion, compute and merge propValues lazily from options; ensure each option provides the discriminator key and that values are unique
Ensure readonly wrapper types (e.g., $ZodReadonly) pass through values for discriminator support in unions
Files:
packages/zod/src/v4/core/schemas.ts
packages/zod/src/v4/core/{schemas.ts,checks.ts}
📄 CodeRabbit inference engine (.cursor/rules/zod-internals.mdc)
When adding issues, push well-formed payload.issues entries including code, expected (when applicable), input, inst, and optional path/message/continue
Files:
packages/zod/src/v4/core/schemas.ts
🧠 Learnings (19)
📚 Learning: 2025-10-21T17:27:32.492Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/zod-internals.mdc:0-0
Timestamp: 2025-10-21T17:27:32.492Z
Learning: Applies to packages/zod/src/v4/core/{schemas.ts,core.ts} : Use the custom constructor system via core.$constructor() and initialize instances with $ZodType.init() when creating schemas
Applied to files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/core/api.tspackages/zod/src/v4/core/schemas.ts
📚 Learning: 2025-10-21T17:27:32.492Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/zod-internals.mdc:0-0
Timestamp: 2025-10-21T17:27:32.492Z
Learning: Applies to packages/zod/src/v4/core/schemas.ts : Wrapper schemas (e.g., $ZodOptional, $ZodNullable, $ZodReadonly) must pass through internal properties from their inner type using util.defineLazy for propValues, values, optin, and optout
Applied to files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/core/schemas.ts
📚 Learning: 2025-10-21T17:27:32.492Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/zod-internals.mdc:0-0
Timestamp: 2025-10-21T17:27:32.492Z
Learning: Applies to packages/zod/src/v4/core/schemas.ts : Define computed internal properties using util.defineLazy() to avoid circular dependencies
Applied to files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/core/schemas.ts
📚 Learning: 2025-10-21T17:27:32.492Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/zod-internals.mdc:0-0
Timestamp: 2025-10-21T17:27:32.492Z
Learning: Applies to packages/zod/src/v4/core/schemas.ts : Implement schema parse functions following the standard structure: type check, push invalid_type issue on mismatch, optionally coerce/transform, and return payload
Applied to files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/classic/schemas.ts
📚 Learning: 2025-10-21T17:27:32.492Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/zod-internals.mdc:0-0
Timestamp: 2025-10-21T17:27:32.492Z
Learning: Applies to packages/zod/src/v4/core/errors.ts : Define and use canonical error types/codes as declared in errors.ts (e.g., invalid_type, TooBig/TooSmall, InvalidStringFormat, InvalidUnion, Custom)
Applied to files:
packages/zod/src/v4/mini/schemas.tspackages/zod/src/v4/locales/en.ts
📚 Learning: 2025-10-21T17:26:08.288Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-guidelines.mdc:0-0
Timestamp: 2025-10-21T17:26:08.288Z
Learning: Applies to packages/zod/src/{v4/classic/tests,v4/core/tests,v3/tests}/**/*.test.ts : Use descriptive file names like string.test.ts, object.test.ts, url-validation.test.ts and group related functionality together
Applied to files:
packages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.ts
📚 Learning: 2025-10-21T17:26:08.288Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-guidelines.mdc:0-0
Timestamp: 2025-10-21T17:26:08.288Z
Learning: Applies to packages/zod/src/{v4/classic/tests,v4/core/tests,v3/tests}/**/*.test.ts : Write tests with clear, descriptive names and cover both success and failure cases
Applied to files:
packages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.ts
📚 Learning: 2025-10-21T17:26:08.288Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-guidelines.mdc:0-0
Timestamp: 2025-10-21T17:26:08.288Z
Learning: Applies to packages/zod/src/{v4/classic/tests,v4/core/tests,v3/tests}/**/*.test.ts : Permanent, regression, API validation, edge-case coverage, and performance benchmark tests must be in the test suite (not play.ts)
Applied to files:
packages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.ts
📚 Learning: 2025-10-21T17:26:08.288Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-guidelines.mdc:0-0
Timestamp: 2025-10-21T17:26:08.288Z
Learning: Applies to packages/zod/src/{v4/classic/tests,v4/core/tests,v3/tests}/**/*.test.ts : Keep test suites concise while maintaining adequate coverage
Applied to files:
packages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.ts
📚 Learning: 2025-10-21T17:26:08.288Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-guidelines.mdc:0-0
Timestamp: 2025-10-21T17:26:08.288Z
Learning: Applies to packages/zod/src/{v4/classic/tests,v4/core/tests,v3/tests}/**/*.test.ts : Import Zod in tests as `import * as z from "zod/v4"`
Applied to files:
packages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.tspackages/zod/src/v4/core/schemas.ts
📚 Learning: 2025-10-21T17:26:08.288Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-guidelines.mdc:0-0
Timestamp: 2025-10-21T17:26:08.288Z
Learning: Applies to packages/zod/src/{v4/classic/tests,v4/core/tests,v3/tests}/**/*.test.ts : Do not skip tests due to type issues; fix the types instead
Applied to files:
packages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.ts
📚 Learning: 2025-10-21T17:26:08.288Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-guidelines.mdc:0-0
Timestamp: 2025-10-21T17:26:08.288Z
Learning: Applies to packages/zod/src/{v4/classic/tests,v4/core/tests,v3/tests}/**/*.test.ts : Use import type for type-only imports in tests (e.g., `import type { ... }`)
Applied to files:
packages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.ts
📚 Learning: 2025-10-21T17:26:32.924Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-workflow.mdc:0-0
Timestamp: 2025-10-21T17:26:32.924Z
Learning: Applies to packages/zod/src/v4/{classic,core}/tests/**/*.test.ts : Name test files with the *.test.ts suffix
Applied to files:
packages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.ts
📚 Learning: 2025-10-21T17:26:32.924Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-workflow.mdc:0-0
Timestamp: 2025-10-21T17:26:32.924Z
Learning: Applies to packages/zod/src/v4/{classic,core}/tests/**/*.test.ts : Use test() for individual test cases
Applied to files:
packages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/string.test.ts
📚 Learning: 2025-10-21T17:26:08.288Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-guidelines.mdc:0-0
Timestamp: 2025-10-21T17:26:08.288Z
Learning: Applies to packages/zod/src/{v4/classic/tests,v4/core/tests,v3/tests}/**/*.test.ts : Use Vitest as the framework in tests and import from it as `import { expect, test } from "vitest"`
Applied to files:
packages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/tests/string.test.ts
📚 Learning: 2025-10-21T17:26:32.924Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-workflow.mdc:0-0
Timestamp: 2025-10-21T17:26:32.924Z
Learning: Applies to packages/zod/src/v4/{classic,core}/tests/**/*.test.ts : Use expect() for assertions
Applied to files:
packages/zod/src/v4/mini/tests/string.test.tspackages/zod/src/v4/classic/tests/template-literal.test.tspackages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.ts
📚 Learning: 2025-10-21T17:28:01.210Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/zod-project-guide.mdc:0-0
Timestamp: 2025-10-21T17:28:01.210Z
Learning: Applies to packages/zod/** : Make core Zod library changes in the main package at packages/zod/
Applied to files:
packages/zod/src/v4/classic/schemas.ts
📚 Learning: 2025-10-21T17:26:32.924Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-workflow.mdc:0-0
Timestamp: 2025-10-21T17:26:32.924Z
Learning: Applies to packages/zod/src/v4/{classic,core}/tests/**/*.test.ts : Place tests under packages/zod/src/v4/classic/tests/ or packages/zod/src/v4/core/tests/
Applied to files:
packages/zod/src/v4/classic/schemas.tspackages/zod/src/v4/classic/tests/to-json-schema.test.tspackages/zod/src/v4/classic/tests/string.test.ts
📚 Learning: 2025-10-21T17:26:08.288Z
Learnt from: CR
Repo: colinhacks/zod PR: 0
File: .cursor/rules/testing-guidelines.mdc:0-0
Timestamp: 2025-10-21T17:26:08.288Z
Learning: Applies to packages/zod/src/{v4/classic/tests,v4/core/tests,v3/tests}/**/*.test.ts : Test files must use the .test.ts extension (TypeScript), not JavaScript
Applied to files:
packages/zod/src/v4/classic/tests/continuability.test.tspackages/zod/src/v4/classic/tests/to-json-schema.test.ts
🧬 Code graph analysis (7)
packages/zod/src/v4/mini/schemas.ts (5)
packages/zod/src/v4/core/schemas.ts (1)
$ZodMACInternals(790-792)packages/zod/src/v4/core/core.ts (2)
$constructor(7-10)$constructor(17-77)packages/zod/src/v4/core/regexes.ts (1)
mac(62-63)packages/zod/src/v4/classic/schemas.ts (1)
mac(626-628)packages/zod/src/v4/core/api.ts (1)
$ZodMACParams(349-349)
packages/zod/src/v4/classic/tests/template-literal.test.ts (3)
packages/zod/src/v4/mini/schemas.ts (1)
mac(378-380)packages/zod/src/v4/core/regexes.ts (1)
mac(62-63)packages/zod/src/v4/classic/schemas.ts (1)
mac(626-628)
packages/zod/src/v4/classic/schemas.ts (5)
packages/zod/src/v4/core/schemas.ts (1)
$ZodMACInternals(790-792)packages/zod/src/v4/core/core.ts (2)
$constructor(7-10)$constructor(17-77)packages/zod/src/v4/mini/schemas.ts (1)
mac(378-380)packages/zod/src/v4/core/regexes.ts (1)
mac(62-63)packages/zod/src/v4/core/api.ts (1)
$ZodMACParams(349-349)
packages/zod/src/v4/core/regexes.ts (2)
packages/zod/src/v4/mini/schemas.ts (1)
mac(378-380)packages/zod/src/v4/classic/schemas.ts (1)
mac(626-628)
packages/zod/src/v4/core/api.ts (2)
packages/zod/src/v4/core/schemas.ts (2)
$ZodMAC(794-796)$ZodMAC(798-803)packages/zod/src/v4/core/util.ts (1)
SchemaClass(164-166)
packages/zod/src/v4/classic/tests/string.test.ts (3)
packages/zod/src/v4/mini/schemas.ts (1)
mac(378-380)packages/zod/src/v4/core/regexes.ts (1)
mac(62-63)packages/zod/src/v4/classic/schemas.ts (1)
mac(626-628)
packages/zod/src/v4/core/schemas.ts (1)
packages/zod/src/v4/core/core.ts (2)
$constructor(7-10)$constructor(17-77)
🔇 Additional comments (8)
packages/docs/content/json-schema.mdx (1)
84-84: Docs update LGTMz.mac() correctly listed under pattern-based formats.
packages/zod/src/v4/classic/tests/continuability.test.ts (1)
198-219: Continuability snapshot for mac looks goodMatches existing pattern for invalid_format + custom issue; regex string is escaped consistently.
packages/zod/src/v4/classic/tests/template-literal.test.ts (1)
46-46: Template literal integration for mac is consistentConstructor, type inference, success/failure cases, and pattern snapshot align with other string formats.
Also applies to: 141-142, 366-367, 503-505, 576-578
packages/zod/src/v4/classic/tests/to-json-schema.test.ts (1)
135-142: JSON Schema mapping for mac looks rightProduces
{ type: "string", format: "mac", pattern: ... }consistently. Snapshots read clean.Also applies to: 368-376
packages/zod/src/v4/locales/en.ts (1)
63-63: Good noun mappingAdds "MAC address" for nicer invalid_format messages.
packages/docs/content/api.mdx (1)
262-262: API docs read well
- z.mac() listed among string formats.
- MAC section clearly explains accepted formats and constraints with examples.
Also applies to: 519-531
packages/zod/src/v4/classic/schemas.ts (1)
617-629: MAC classic constructor is correctly wiredInit sequence mirrors other formats; no issues spotted. Please just confirm it’s re-exported from the v4 entry so tests import z.mac() cleanly.
packages/zod/src/v4/classic/tests/string.test.ts (1)
778-780: LGTM: format is exposed as "mac"Assertion matches other string formats.
| // ZodMiniMAC | ||
| export interface ZodMiniMAC extends _ZodMiniString<core.$ZodMACInternals> { | ||
| // _zod: core.$ZodMACInternals; | ||
| } | ||
| export const ZodMiniMAC: core.$constructor<ZodMiniMAC> = /*@__PURE__*/ core.$constructor("ZodMiniMAC", (inst, def) => { | ||
| core.$ZodMAC.init(inst, def); | ||
| ZodMiniStringFormat.init(inst, def); | ||
| }); | ||
|
|
||
| export function mac(params?: string | core.$ZodMACParams): ZodMiniMAC { | ||
| return core._mac(ZodMiniMAC, params); | ||
| } | ||
|
|
There was a problem hiding this comment.
Regex backref bug will make z.mac() reject valid inputs
Wiring looks good, but core regex uses self-references (\3, \6) instead of the separator group, so valid MACs won’t match. Fix the pattern to backref the right capture.
Apply in packages/zod/src/v4/core/regexes.ts:
-export const mac: RegExp =
- /^(([0-9A-F]{2}([-:])[0-9A-F]{2}(\3[0-9A-F]{2}){4})|([0-9a-f]{2}([-:])[0-9a-f]{2}(\6[0-9a-f]{2}){4}))$/;
+export const mac: RegExp =
+ /^(([0-9A-F]{2}([-:])[0-9A-F]{2}(\2[0-9A-F]{2}){4})|([0-9a-f]{2}([-:])[0-9a-f]{2}(\5[0-9a-f]{2}){4}))$/;Committable suggestion skipped: line range outside the PR's diff.
|
Implemented coderabbit's suggestions, except:
|
|
Love it! Make some tweaks.
Gonna merge this eagerly but feel free to comment if you think any of these changes are egregious and we can fix before publishing this in Zod 4.2 |
|
@colinhacks To double-check, did you mean to include the .cursor/agent changes in your commit? |
Description
This PR adds
z.mac()for validating standard 48-bit MAC addresses in Zod 4 and Zod Mini. Closes #3970.This PR is essentially a rewrite from scratch (using v4) of PR #3972, a proposed implementation for v3 that went stale (if this PR is merged I recommend it be closed). Credit to its author (@sumit6499) for most of the test cases.
Decisions
Changes