Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions bun.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -412,6 +413,8 @@

"@standard-schema/spec": ["@standard-schema/[email protected]", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],

"@standard-schema/utils": ["@standard-schema/[email protected]", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="],

"@surma/rollup-plugin-off-main-thread": ["@surma/[email protected]", "", { "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/[email protected]", "", { "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=="],
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions standard-schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
23 changes: 23 additions & 0 deletions standard-schema/src/__tests__/__fixtures__/data.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { StandardSchemaV1 } from '@standard-schema/spec';
import { Field, InternalFieldName } from 'react-hook-form';
import { z } from 'zod';

Expand Down Expand Up @@ -86,3 +87,25 @@ export const fields: Record<InternalFieldName, Field['_f']> = {
name: 'birthday',
},
};

export const customSchema: StandardSchemaV1<
StandardSchemaV1.InferInput<typeof schema>,
StandardSchemaV1.InferOutput<typeof schema>
> = {
'~standard': {
version: 1,
vendor: 'custom',
validate: () => ({
issues: [
{
path: [{ key: 'username' }],
message: 'Custom error',
},
{
path: [{ key: 'like' }, { key: 0 }, { key: 'id' }],
message: 'Custom error',
},
],
}),
},
};
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
20 changes: 19 additions & 1 deletion standard-schema/src/__tests__/standard-schema.ts
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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();
});
});
10 changes: 5 additions & 5 deletions standard-schema/src/standard-schema.ts
Original file line number Diff line number Diff line change
@@ -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(
Expand All @@ -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]) {
Expand Down Expand Up @@ -52,15 +53,14 @@ function parseIssues(
* ```
*/
export function standardSchemaResolver<
TFieldValues extends FieldValues,
Schema extends StandardSchemaV1<TFieldValues, any>,
Schema extends StandardSchemaV1<FieldValues>,
>(
schema: Schema,
resolverOptions: {
raw?: boolean;
} = {},
): Resolver<NonNullable<(typeof schema)['~standard']['types']>['output']> {
return async (values: TFieldValues, _, options) => {
): Resolver<StandardSchemaV1.InferOutput<Schema>> {
return async (values, _, options) => {
let result = schema['~standard'].validate(values);
if (result instanceof Promise) {
result = await result;
Expand Down
Loading