Skip to content

Commit

Permalink
feat: add field-level support to global rules
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Nov 25, 2023
1 parent 58b470f commit 43561e2
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 21 deletions.
40 changes: 26 additions & 14 deletions packages/rules/src/toTypedSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,12 @@ export function toTypedSchema<TOutput = any, TInput extends Optional<TOutput> =
};
},
describe(path) {
if (isObject(rawSchema) && path in rawSchema) {
const rules = (rawSchema as any)[path];
if (typeof rules === 'string') {
return {
exists: true,
required: rules.includes('required'),
};
}
if (!path) {
return getDescriptionFromExpression(rawSchema);
}

if (isObject(rules)) {
return {
exists: true,
required: !!rules.required,
};
}
if (isObject(rawSchema) && path in rawSchema) {
return getDescriptionFromExpression((rawSchema as any)[path]);
}

return {
Expand All @@ -61,3 +52,24 @@ export function toTypedSchema<TOutput = any, TInput extends Optional<TOutput> =

return schema;
}

function getDescriptionFromExpression(rules: string | Record<string, any>) {
if (typeof rules === 'string') {
return {
exists: true,
required: rules.includes('required'),
};
}

if (isObject(rules)) {
return {
exists: true,
required: !!rules.required,
};
}

return {
required: false,
exists: true,
};
}
55 changes: 54 additions & 1 deletion packages/rules/tests/toTypedSchema.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ test('reports required state on fields', async () => {
);
});

test('reports required state on fields', async () => {
test('reports required false for non-existent fields', async () => {
const metaSpy = vi.fn();
mountWithHoc({
setup() {
Expand Down Expand Up @@ -177,3 +177,56 @@ test('reports required state on fields', async () => {
}),
);
});

test('reports required state for field-level schemas', async () => {
const metaSpy = vi.fn();
mountWithHoc({
setup() {
useForm();
const { meta: req } = useField('req', toTypedSchema('required'));
const { meta: nreq } = useField('nreq', toTypedSchema('email'));

metaSpy({
req: req.required,
nreq: nreq.required,
});

return {};
},
template: `<div></div>`,
});

await flushPromises();
await expect(metaSpy).toHaveBeenLastCalledWith(
expect.objectContaining({
req: true,
nreq: false,
}),
);
});

test('reports required state for field-level schemas without a form context', async () => {
const metaSpy = vi.fn();
mountWithHoc({
setup() {
const { meta: req } = useField('req', toTypedSchema('required'));
const { meta: nreq } = useField('nreq', toTypedSchema('email'));

metaSpy({
req: req.required,
nreq: nreq.required,
});

return {};
},
template: `<div></div>`,
});

await flushPromises();
await expect(metaSpy).toHaveBeenLastCalledWith(
expect.objectContaining({
req: true,
nreq: false,
}),
);
});
4 changes: 2 additions & 2 deletions packages/valibot/tests/valibot.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ test('reports required false for non-existent fields', async () => {
);
});

test('reports required state single field schemas', async () => {
test('reports required state for field-level schemas', async () => {
const metaSpy = vi.fn();
mountWithHoc({
setup() {
Expand All @@ -500,7 +500,7 @@ test('reports required state single field schemas', async () => {
);
});

test('reports required state single field schemas without a form context', async () => {
test('reports required state for field-level schemas without a form context', async () => {
const metaSpy = vi.fn();
mountWithHoc({
setup() {
Expand Down
4 changes: 2 additions & 2 deletions packages/yup/tests/yup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ test('reports required false for non-existent fields', async () => {
);
});

test('reports required state single field schemas', async () => {
test('reports required state for field-level schemas', async () => {
const metaSpy = vi.fn();
mountWithHoc({
setup() {
Expand All @@ -457,7 +457,7 @@ test('reports required state single field schemas', async () => {
);
});

test('reports required state single field schemas without a form context', async () => {
test('reports required state for field-level schemas without a form context', async () => {
const metaSpy = vi.fn();
mountWithHoc({
setup() {
Expand Down
4 changes: 2 additions & 2 deletions packages/zod/tests/zod.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ test('reports required false for non-existent fields', async () => {
);
});

test('reports required state single field schemas', async () => {
test('reports required state for field-level schemas', async () => {
const metaSpy = vi.fn();
mountWithHoc({
setup() {
Expand All @@ -551,7 +551,7 @@ test('reports required state single field schemas', async () => {
);
});

test('reports required state single field schemas without a form context', async () => {
test('reports required state for field-level schemas without a form context', async () => {
const metaSpy = vi.fn();
mountWithHoc({
setup() {
Expand Down

0 comments on commit 43561e2

Please sign in to comment.