Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changeset/fix-5110-arktype-compat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"vee-validate": patch
---

Fix standard schema validation compatibility with arktype (#5110)
6 changes: 5 additions & 1 deletion packages/vee-validate/src/utils/assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ export function isLocator(value: unknown): value is Locator {
}

export function isStandardSchema(value: unknown): value is StandardSchemaV1 {
return isObject(value) && '~standard' in (value as unknown as StandardSchemaV1);
return (
!!value &&
(typeof value === 'object' || typeof value === 'function') &&
'~standard' in (value as Record<PropertyKey, unknown>)
);
}

export function hasCheckedAttr(type: unknown) {
Expand Down
59 changes: 58 additions & 1 deletion packages/vee-validate/tests/utils/assertions.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isEqual } from 'packages/vee-validate/src/utils';
import { isEqual, isStandardSchema } from 'packages/vee-validate/src/utils';

describe('assertions', () => {
test('equal objects are equal', () => {
Expand Down Expand Up @@ -229,3 +229,60 @@ describe('assertions', () => {
expect(isEqual(a6, b2)).toBe(false);
});
});

// #5110 - arktype compatibility
describe('isStandardSchema', () => {
test('detects a plain object with ~standard property as a standard schema', () => {
const schema = {
'~standard': {
version: 1,
vendor: 'test',
validate: (value: unknown) => ({ value }),
},
};

expect(isStandardSchema(schema)).toBe(true);
});

test('detects a callable object with ~standard property as a standard schema (like arktype)', () => {
// Arktype schemas are functions that also have the ~standard property
const callableSchema = Object.assign(
function (value: unknown) {
return value;
},
{
'~standard': {
version: 1,
vendor: 'arktype',
validate: (value: unknown) => ({ value }),
},
},
);

expect(isStandardSchema(callableSchema)).toBe(true);
});

test('returns false for a plain function without ~standard', () => {
const fn = (value: unknown) => value;
expect(isStandardSchema(fn)).toBe(false);
});

test('returns false for primitive values', () => {
expect(isStandardSchema(null)).toBe(false);
expect(isStandardSchema(undefined)).toBe(false);
expect(isStandardSchema('')).toBe(false);
expect(isStandardSchema('required')).toBe(false);
expect(isStandardSchema(0)).toBe(false);
expect(isStandardSchema(true)).toBe(false);
});

test('returns false for arrays', () => {
expect(isStandardSchema([])).toBe(false);
expect(isStandardSchema([() => true])).toBe(false);
});

test('returns false for plain objects without ~standard', () => {
expect(isStandardSchema({})).toBe(false);
expect(isStandardSchema({ required: true })).toBe(false);
});
});
Loading