diff --git a/bun.lock b/bun.lock index b6d9c48..53d1226 100644 --- a/bun.lock +++ b/bun.lock @@ -9,6 +9,7 @@ "devDependencies": { "@sinclair/typebox": "^0.34.15", "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.2.0", @@ -412,6 +413,8 @@ "@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="], + "@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="], + "@surma/rollup-plugin-off-main-thread": ["@surma/rollup-plugin-off-main-thread@2.2.3", "", { "dependencies": { "ejs": "^3.1.6", "json5": "^2.2.0", "magic-string": "^0.25.0", "string.prototype.matchall": "^4.0.6" } }, "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ=="], "@testing-library/dom": ["@testing-library/dom@10.4.0", "", { "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", "chalk": "^4.1.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "pretty-format": "^27.0.2" } }, "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ=="], diff --git a/package.json b/package.json index 55b9500..9553d97 100644 --- a/package.json +++ b/package.json @@ -269,6 +269,7 @@ "devDependencies": { "@sinclair/typebox": "^0.34.15", "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.2.0", diff --git a/standard-schema/package.json b/standard-schema/package.json index de255f3..b67ce00 100644 --- a/standard-schema/package.json +++ b/standard-schema/package.json @@ -13,6 +13,7 @@ "peerDependencies": { "react-hook-form": "^7.0.0", "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", "@hookform/resolvers": "^2.0.0" } } diff --git a/standard-schema/src/__tests__/__fixtures__/data.ts b/standard-schema/src/__tests__/__fixtures__/data.ts index e37f521..a71f4c5 100644 --- a/standard-schema/src/__tests__/__fixtures__/data.ts +++ b/standard-schema/src/__tests__/__fixtures__/data.ts @@ -1,3 +1,4 @@ +import { StandardSchemaV1 } from '@standard-schema/spec'; import { Field, InternalFieldName } from 'react-hook-form'; import { z } from 'zod'; @@ -86,3 +87,25 @@ export const fields: Record = { name: 'birthday', }, }; + +export const customSchema: StandardSchemaV1< + StandardSchemaV1.InferInput, + StandardSchemaV1.InferOutput +> = { + '~standard': { + version: 1, + vendor: 'custom', + validate: () => ({ + issues: [ + { + path: [{ key: 'username' }], + message: 'Custom error', + }, + { + path: [{ key: 'like' }, { key: 0 }, { key: 'id' }], + message: 'Custom error', + }, + ], + }), + }, +}; diff --git a/standard-schema/src/__tests__/__snapshots__/standard-schema.ts.snap b/standard-schema/src/__tests__/__snapshots__/standard-schema.ts.snap index f8a68ff..2dba659 100644 --- a/standard-schema/src/__tests__/__snapshots__/standard-schema.ts.snap +++ b/standard-schema/src/__tests__/__snapshots__/standard-schema.ts.snap @@ -1,5 +1,29 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`standardSchemaResolver > should correctly handle path segments that are objects 1`] = ` +{ + "errors": { + "like": [ + { + "id": { + "message": "Custom error", + "ref": undefined, + "type": "", + }, + }, + ], + "username": { + "message": "Custom error", + "ref": { + "name": "username", + }, + "type": "", + }, + }, + "values": {}, +} +`; + exports[`standardSchemaResolver > should return a single error from standardSchemaResolver when validation fails 1`] = ` { "errors": { diff --git a/standard-schema/src/__tests__/standard-schema.ts b/standard-schema/src/__tests__/standard-schema.ts index b99bfc1..46186b6 100644 --- a/standard-schema/src/__tests__/standard-schema.ts +++ b/standard-schema/src/__tests__/standard-schema.ts @@ -1,5 +1,11 @@ import { standardSchemaResolver } from '..'; -import { fields, invalidData, schema, validData } from './__fixtures__/data'; +import { + customSchema, + fields, + invalidData, + schema, + validData, +} from './__fixtures__/data'; const shouldUseNativeValidation = false; @@ -53,4 +59,16 @@ describe('standardSchemaResolver', () => { expect(validateSpy).toHaveBeenCalledTimes(1); expect(result).toMatchSnapshot(); }); + it('should correctly handle path segments that are objects', async () => { + const result = await standardSchemaResolver(customSchema)( + validData, + undefined, + { + fields, + shouldUseNativeValidation, + }, + ); + + expect(result).toMatchSnapshot(); + }); }); diff --git a/standard-schema/src/standard-schema.ts b/standard-schema/src/standard-schema.ts index 5059915..8d216ba 100644 --- a/standard-schema/src/standard-schema.ts +++ b/standard-schema/src/standard-schema.ts @@ -1,5 +1,6 @@ import { toNestErrors, validateFieldsNatively } from '@hookform/resolvers'; import { StandardSchemaV1 } from '@standard-schema/spec'; +import { getDotPath } from '@standard-schema/utils'; import { FieldError, FieldValues, Resolver } from 'react-hook-form'; function parseIssues( @@ -10,7 +11,7 @@ function parseIssues( for (let i = 0; i < issues.length; i++) { const error = issues[i]; - const path = error.path?.join('.'); + const path = getDotPath(error); if (path) { if (!errors[path]) {