diff --git a/.ncurc.js b/.ncurc.js index c82608aec..352cbcbb2 100644 --- a/.ncurc.js +++ b/.ncurc.js @@ -7,7 +7,6 @@ module.exports = { if ( (name === "@types/node" && parseInt(upgradedVersionSemver?.major, 10) >= 22) || - (name === "zod" && parseInt(upgradedVersionSemver?.major, 10) >= 4) || (name === "@hookform/resolvers" && parseInt(upgradedVersionSemver?.major, 10) >= 4) ) { diff --git a/packages/app-elements/package.json b/packages/app-elements/package.json index e457a9083..28fe17a79 100644 --- a/packages/app-elements/package.json +++ b/packages/app-elements/package.json @@ -75,10 +75,10 @@ "swr": "^2.4.0", "ts-invariant": "^0.10.3", "type-fest": "^5.4.4", - "zod": "^3.25.76" + "zod": "^4.0.5" }, "devDependencies": { - "@hookform/resolvers": "^3.10.0", + "@hookform/resolvers": "^5.1.1", "@phosphor-icons/react": "v2.1.10", "@tailwindcss/forms": "^0.5.11", "@tailwindcss/postcss": "^4.2.1", diff --git a/packages/app-elements/src/ui/resources/ResourceAddress/ResourceAddressFormFields.tsx b/packages/app-elements/src/ui/resources/ResourceAddress/ResourceAddressFormFields.tsx index 62962ccf1..57e4f1e86 100644 --- a/packages/app-elements/src/ui/resources/ResourceAddress/ResourceAddressFormFields.tsx +++ b/packages/app-elements/src/ui/resources/ResourceAddress/ResourceAddressFormFields.tsx @@ -14,8 +14,8 @@ import type { ResourceAddressProps } from "./ResourceAddress" const zodRequiredField = z .string({ - required_error: "Required field", - invalid_type_error: "Invalid format", + error: (iss) => + iss.input === undefined ? "Required field" : "Invalid format", }) .min(1, { message: "Required field", @@ -37,12 +37,19 @@ export const getResourceAddressFormFieldsSchema = ({ state_code: zodRequiredField, country_code: zodRequiredField, phone: zodRequiredField, - billing_info: requiresBillingInfo - ? zodRequiredField - : z.string().nullish(), + billing_info: z.string().nullish(), notes: z.string().nullish(), }) .superRefine((data, ctx) => { + if (requiresBillingInfo) { + if (data.billing_info == null || data.billing_info.length === 0) { + ctx.addIssue({ + code: "custom", + path: ["billing_info"], + message: t("common.forms.required_field"), + }) + } + } if (data.business === true) { if (data.company == null || data.company.length === 0) { ctx.addIssue({ diff --git a/packages/app-elements/src/ui/resources/useResourceFilters/adaptFormValuesToSdk.ts b/packages/app-elements/src/ui/resources/useResourceFilters/adaptFormValuesToSdk.ts index 656174809..b8054fe08 100644 --- a/packages/app-elements/src/ui/resources/useResourceFilters/adaptFormValuesToSdk.ts +++ b/packages/app-elements/src/ui/resources/useResourceFilters/adaptFormValuesToSdk.ts @@ -66,7 +66,7 @@ export function adaptFormValuesToSdk< if (predicateWhitelist.includes(key)) { return { ...acc, - [key]: formValues[key], + [key]: formValues[key] ?? undefined, } } @@ -80,7 +80,8 @@ export function adaptFormValuesToSdk< ) { return { ...acc, - [key]: instructionItem.sdk.parseFormValue(formValues[key]), + [key]: + instructionItem.sdk.parseFormValue(formValues[key]) ?? undefined, } } @@ -90,7 +91,7 @@ export function adaptFormValuesToSdk< ) { return { ...acc, - [key]: castArray(formValues[key]).join(","), + [key]: castArray(formValues[key]).join(",") ?? undefined, } } diff --git a/packages/app-elements/src/ui/resources/useResourceFilters/timeUtils.ts b/packages/app-elements/src/ui/resources/useResourceFilters/timeUtils.ts index 3b6410139..6ed6c793b 100644 --- a/packages/app-elements/src/ui/resources/useResourceFilters/timeUtils.ts +++ b/packages/app-elements/src/ui/resources/useResourceFilters/timeUtils.ts @@ -102,7 +102,6 @@ export const timeRangeValidationSchema = z timeTo: z.date().optional().nullable(), timePreset: z.enum(filterableTimeRangePreset).optional().nullable(), }) - .passthrough() .superRefine((data, ctx) => { if (data.timePreset === "custom" && data.timeFrom == null) { ctx.addIssue({ @@ -125,7 +124,9 @@ export const timeRangeValidationSchema = z data.timeFrom > data.timeTo ) { ctx.addIssue({ - code: "invalid_date", + code: "invalid_type", + expected: "date", + input: data.timeTo, path: ["timeTo"], message: 'The "To" date must be greater than the "From" date', }) diff --git a/packages/app-elements/src/ui/resources/useResourceFilters/types.ts b/packages/app-elements/src/ui/resources/useResourceFilters/types.ts index 3d1766784..4e70f027f 100644 --- a/packages/app-elements/src/ui/resources/useResourceFilters/types.ts +++ b/packages/app-elements/src/ui/resources/useResourceFilters/types.ts @@ -11,7 +11,13 @@ export const filterableTimeRangePreset = [ ] as const export type UiFilterName = string -export type UiFilterValue = string | string[] | boolean | Date | undefined +export type UiFilterValue = + | string + | string[] + | boolean + | Date + | undefined + | null export type TimeRangePreset = (typeof filterableTimeRangePreset)[number] diff --git a/packages/docs/package.json b/packages/docs/package.json index 1e41338b8..a1c62b453 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -50,7 +50,7 @@ "typescript": "~5.9.3", "vite": "^7.3.1", "vite-tsconfig-paths": "^5.1.4", - "zod": "^3.25.76" + "zod": "^4.0.5" }, "msw": { "workerDirectory": "public" diff --git a/packages/docs/src/stories/resources/ResourceAddress.stories.tsx b/packages/docs/src/stories/resources/ResourceAddress.stories.tsx index 9d3a10e4a..3dc128ebf 100644 --- a/packages/docs/src/stories/resources/ResourceAddress.stories.tsx +++ b/packages/docs/src/stories/resources/ResourceAddress.stories.tsx @@ -182,8 +182,8 @@ export const ReuseTheAddressForm: StoryFn = () => { z.object({ name: z .string({ - required_error: "Required field", - invalid_type_error: "Invalid format", + error: (iss) => + iss.input === undefined ? "Required field" : "Invalid format", }) .min(1, { message: "Required field", @@ -228,8 +228,8 @@ export const ShowNameOrCompany: StoryFn = () => { z.object({ name: z .string({ - required_error: "Required field", - invalid_type_error: "Invalid format", + error: (iss) => + iss.input === undefined ? "Required field" : "Invalid format", }) .min(1, { message: "Required field", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ec14ce2f5..9d316ebd5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -115,12 +115,12 @@ importers: specifier: ^5.4.4 version: 5.4.4 zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: ^4.0.5 + version: 4.0.5 devDependencies: '@hookform/resolvers': - specifier: ^3.10.0 - version: 3.10.0(react-hook-form@7.62.0(react@19.2.4)) + specifier: ^5.1.1 + version: 5.1.1(react-hook-form@7.62.0(react@19.2.4)) '@phosphor-icons/react': specifier: v2.1.10 version: 2.1.10(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -291,8 +291,8 @@ importers: specifier: ^5.1.4 version: 5.1.4(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.33)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(yaml@2.8.2)) zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: ^4.0.5 + version: 4.0.5 packages: @@ -892,28 +892,24 @@ packages: engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - libc: [musl] '@biomejs/cli-linux-arm64@2.4.4': resolution: {integrity: sha512-V/NFfbWhsUU6w+m5WYbBenlEAz8eYnSqRMDMAW3K+3v0tYVkNyZn8VU0XPxk/lOqNXLSCCrV7FmV/u3SjCBShg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - libc: [glibc] '@biomejs/cli-linux-x64-musl@2.4.4': resolution: {integrity: sha512-gGvFTGpOIQDb5CQ2VC0n9Z2UEqlP46c4aNgHmAMytYieTGEcfqhfCFnhs6xjt0S3igE6q5GLuIXtdQt3Izok+g==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - libc: [musl] '@biomejs/cli-linux-x64@2.4.4': resolution: {integrity: sha512-R4+ZCDtG9kHArasyBO+UBD6jr/FcFCTH8QkNTOCu0pRJzCWyWC4EtZa2AmUZB5h3e0jD7bRV2KvrENcf8rndBg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - libc: [glibc] '@biomejs/cli-win32-arm64@2.4.4': resolution: {integrity: sha512-trzCqM7x+Gn832zZHgr28JoYagQNX4CZkUZhMUac2YxvvyDRLJDrb5m9IA7CaZLlX6lTQmADVfLEKP1et1Ma4Q==} @@ -1370,6 +1366,11 @@ packages: peerDependencies: react-hook-form: ^7.0.0 + '@hookform/resolvers@5.1.1': + resolution: {integrity: sha512-J/NVING3LMAEvexJkyTLjruSm7aOFx7QX21pzkiJfMoNG0wl5aFEjLTl7ay7IQb9EWY6AkrBy7tHL2Alijpdcg==} + peerDependencies: + react-hook-form: ^7.55.0 + '@hutson/parse-repository-url@3.0.2': resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} engines: {node: '>=6.9.0'} @@ -1735,25 +1736,21 @@ packages: resolution: {integrity: sha512-D+tPXB0tkSuDPsuXvyQIsF3f3PBWfAwIe9FkBWtVoDVYqE+jbz+tVGsjQMNWGafLE4sC8ZQdjhsxyT8I53Anbw==} cpu: [arm64] os: [linux] - libc: [glibc] '@nx/nx-linux-arm64-musl@22.5.2': resolution: {integrity: sha512-UbO527qqa8KLBi13uXto5SmxcZv1Smer7sPexJonshDlmrJsyvx5m8nm6tcSv04W5yQEL90vPlTux8dNvEDWrw==} cpu: [arm64] os: [linux] - libc: [musl] '@nx/nx-linux-x64-gnu@22.5.2': resolution: {integrity: sha512-wR6596Vr/Z+blUAmjLHG2TCQMs4O1oi9JXK1J/PoPeO9UqdHwStCJBAd61zDFSUYJe0x+dkeRQu96fE5BW8Kcg==} cpu: [x64] os: [linux] - libc: [glibc] '@nx/nx-linux-x64-musl@22.5.2': resolution: {integrity: sha512-MBXOw4AH4FWl4orwVykj/e75awTNDePogrl3pXNX9NcQLdj6JzS4e2jaALQeRBQLxQzeFvFQV/W4PBzoPV6/NA==} cpu: [x64] os: [linux] - libc: [musl] '@nx/nx-win32-arm64-msvc@22.5.2': resolution: {integrity: sha512-SaWSZkRH5uV8vP2lj6RRv+kw2IzaIDXkutReOXpooshIWZl9KjrQELNTCZTYyhLDsMlcyhSvLFlTiA4NkZ8udw==} @@ -1886,79 +1883,66 @@ packages: resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.59.0': resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] - libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.59.0': resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.59.0': resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] - libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.59.0': resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.59.0': resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] os: [linux] - libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.59.0': resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.59.0': resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] os: [linux] - libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.59.0': resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.59.0': resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] - libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.59.0': resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.59.0': resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-musl@4.59.0': resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] - libc: [musl] '@rollup/rollup-openbsd-x64@4.59.0': resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} @@ -2051,6 +2035,9 @@ packages: resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} + '@standard-schema/utils@0.3.0': + resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + '@storybook/addon-docs@9.1.19': resolution: {integrity: sha512-kRK3oIq4wlyH5Zr7Dpr44zzk3nhJdegKSNe6b4wi0a1vnIhnuuxgJc0KXqgiyP2jb1GfUTB/1IRfDqUsQEw+vg==} peerDependencies: @@ -2170,28 +2157,24 @@ packages: engines: {node: '>= 20'} cpu: [arm64] os: [linux] - libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.2.1': resolution: {integrity: sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] - libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.2.1': resolution: {integrity: sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==} engines: {node: '>= 20'} cpu: [x64] os: [linux] - libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.2.1': resolution: {integrity: sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==} engines: {node: '>= 20'} cpu: [x64] os: [linux] - libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.2.1': resolution: {integrity: sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==} @@ -3990,28 +3973,24 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [glibc] lightningcss-linux-arm64-musl@1.31.1: resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [musl] lightningcss-linux-x64-gnu@1.31.1: resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [glibc] lightningcss-linux-x64-musl@1.31.1: resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [musl] lightningcss-win32-arm64-msvc@1.31.1: resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} @@ -6002,8 +5981,8 @@ packages: resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} engines: {node: '>=18'} - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.0.5: + resolution: {integrity: sha512-/5UuuRPStvHXu7RS+gmvRf4NXrNxpSllGwDnCBcJZtQsKrviYXm54yDGV2KYNLT5kq0lHGcl7lqWJLgSaG+tgA==} zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -7088,6 +7067,11 @@ snapshots: dependencies: react-hook-form: 7.62.0(react@19.2.4) + '@hookform/resolvers@5.1.1(react-hook-form@7.62.0(react@19.2.4))': + dependencies: + '@standard-schema/utils': 0.3.0 + react-hook-form: 7.62.0(react@19.2.4) + '@hutson/parse-repository-url@3.0.2': {} '@inquirer/ansi@1.0.2': {} @@ -7868,6 +7852,8 @@ snapshots: '@sindresorhus/merge-streams@2.3.0': {} + '@standard-schema/utils@0.3.0': {} + '@storybook/addon-docs@9.1.19(@types/react@19.2.13)(storybook@9.1.19(@testing-library/dom@10.4.1)(msw@2.12.10(@types/node@20.19.33)(typescript@5.9.3))(prettier@3.8.1)(vite@7.3.1(@types/node@20.19.33)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(yaml@2.8.2)))': dependencies: '@mdx-js/react': 3.1.1(@types/react@19.2.13)(react@19.2.4) @@ -12252,6 +12238,6 @@ snapshots: yoctocolors-cjs@2.1.3: {} - zod@3.25.76: {} + zod@4.0.5: {} zwitch@2.0.4: {}