diff --git a/apps/demo/src/app/examples/with-material-ui/dictionary/date.component.tsx b/apps/demo/src/app/examples/with-material-ui/dictionary/date.component.tsx index 1d2023e..59a892f 100644 --- a/apps/demo/src/app/examples/with-material-ui/dictionary/date.component.tsx +++ b/apps/demo/src/app/examples/with-material-ui/dictionary/date.component.tsx @@ -1,12 +1,10 @@ import { Ref, useMemo } from 'react'; import { FieldErrors, Path, FieldValues } from 'react-hook-form'; -import { - getValidationRulesHints, - Validations -} from '@bedrockstreaming/form-builder'; +import { Validations } from '@bedrockstreaming/form-builder'; import { checkRules, - withValidationRuleList + withValidationRuleList, + getValidationRulesHints } from '@bedrockstreaming/form-validation-rule-list'; import { TextField } from '@mui/material'; import _ from 'lodash'; diff --git a/apps/demo/src/app/examples/with-material-ui/dictionary/password.component.tsx b/apps/demo/src/app/examples/with-material-ui/dictionary/password.component.tsx index 47f1eff..94b4b05 100644 --- a/apps/demo/src/app/examples/with-material-ui/dictionary/password.component.tsx +++ b/apps/demo/src/app/examples/with-material-ui/dictionary/password.component.tsx @@ -1,10 +1,8 @@ import { Ref, useMemo } from 'react'; import { FieldErrors } from 'react-hook-form'; +import { Validations } from '@bedrockstreaming/form-builder'; import { getValidationRulesHints, - Validations -} from '@bedrockstreaming/form-builder'; -import { checkRules, withValidationRuleList } from '@bedrockstreaming/form-validation-rule-list'; diff --git a/apps/demo/src/app/examples/with-styled-components/dictionary/date.component.tsx b/apps/demo/src/app/examples/with-styled-components/dictionary/date.component.tsx index cb68280..fb41c4f 100644 --- a/apps/demo/src/app/examples/with-styled-components/dictionary/date.component.tsx +++ b/apps/demo/src/app/examples/with-styled-components/dictionary/date.component.tsx @@ -1,9 +1,9 @@ import { FieldErrors, Path, FieldValues } from 'react-hook-form'; +import { Validations } from '@bedrockstreaming/form-builder'; import { getValidationRulesHints, - Validations -} from '@bedrockstreaming/form-builder'; -import { checkRules } from '@bedrockstreaming/form-validation-rule-list'; + checkRules +} from '@bedrockstreaming/form-validation-rule-list'; import { ValidatedTextField } from '@forms/examples/styled-inputs'; import { BirthdateInput } from '@forms/examples/birthdate'; diff --git a/apps/demo/src/app/examples/with-styled-components/dictionary/password.component.tsx b/apps/demo/src/app/examples/with-styled-components/dictionary/password.component.tsx index 3d89cd9..058b400 100644 --- a/apps/demo/src/app/examples/with-styled-components/dictionary/password.component.tsx +++ b/apps/demo/src/app/examples/with-styled-components/dictionary/password.component.tsx @@ -1,9 +1,9 @@ import { FieldErrors } from 'react-hook-form'; +import { Validations } from '@bedrockstreaming/form-builder'; import { getValidationRulesHints, - Validations -} from '@bedrockstreaming/form-builder'; -import { checkRules } from '@bedrockstreaming/form-validation-rule-list'; + checkRules +} from '@bedrockstreaming/form-validation-rule-list'; import { ValidatedPasswordTextField } from '@forms/examples/styled-inputs'; diff --git a/apps/docsite/docs/form-validation-rule-list.md b/apps/docsite/docs/form-validation-rule-list.md index bf5b9c4..07d510e 100644 --- a/apps/docsite/docs/form-validation-rule-list.md +++ b/apps/docsite/docs/form-validation-rule-list.md @@ -56,8 +56,8 @@ const schema = { Dictionary ```jsx -import { getValidationRulesHints } from '@bedrockstreaming/form-builder'; import { + getValidationRulesHints, checkRules, withValidationRuleList, } from '@bedrockstreaming/form-validation-rule-list'; diff --git a/apps/docsite/src/form/dictionary/date.component.jsx b/apps/docsite/src/form/dictionary/date.component.jsx index 8ce0301..527f11e 100644 --- a/apps/docsite/src/form/dictionary/date.component.jsx +++ b/apps/docsite/src/form/dictionary/date.component.jsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; -import { getValidationRulesHints } from '@bedrockstreaming/form-builder'; import { + getValidationRulesHints, checkRules, withValidationRuleList } from '@bedrockstreaming/form-validation-rule-list'; diff --git a/apps/docsite/src/form/dictionary/password.component.jsx b/apps/docsite/src/form/dictionary/password.component.jsx index 4c51448..46bc00f 100644 --- a/apps/docsite/src/form/dictionary/password.component.jsx +++ b/apps/docsite/src/form/dictionary/password.component.jsx @@ -1,8 +1,6 @@ import React, { useMemo } from 'react'; import { getValidationRulesHints, -} from '@bedrockstreaming/form-builder'; -import { checkRules, withValidationRuleList } from '@bedrockstreaming/form-validation-rule-list'; diff --git a/libs/form-builder/README.md b/libs/form-builder/README.md index 33c5833..cbdd79e 100644 --- a/libs/form-builder/README.md +++ b/libs/form-builder/README.md @@ -236,7 +236,7 @@ When we need more personalization in our validation for a special type of field const schema = { fields: { - BIRTHDATE: { + birthDate: { ... meta: { ... @@ -244,12 +244,12 @@ When we need more personalization in our validation for a special type of field validation: { customValidationFunction1: { // <-- this is a custom validation key: 'customValidationFunction1', - message: 'forms.register.birthdate.minAgeError', + message: 'some.translated.message.minAgeError', value: 13, }, required: { // <-- this is a default validation (native to react-hook-form) key: 'required', - message: 'forms.required.error', + message: 'some.translated.message.requiredError', value: true, }, }, diff --git a/libs/form-builder/src/index.ts b/libs/form-builder/src/index.ts index 9e73e01..ae4ab9a 100644 --- a/libs/form-builder/src/index.ts +++ b/libs/form-builder/src/index.ts @@ -1,4 +1,3 @@ export * from './lib/formBuilder'; export * from './lib/types'; export * from './lib/constants'; -export { getValidationRulesHints } from './lib/utils/validation.utils'; diff --git a/libs/form-builder/src/lib/utils/__tests__/validation.utils.spec.js b/libs/form-builder/src/lib/utils/__tests__/validation.utils.spec.js index 7a3d961..39f82c7 100644 --- a/libs/form-builder/src/lib/utils/__tests__/validation.utils.spec.js +++ b/libs/form-builder/src/lib/utils/__tests__/validation.utils.spec.js @@ -1,7 +1,4 @@ -import { rule } from '../rule.utils'; -import { getFieldRules, getValidationRulesHints } from '../validation.utils'; - -jest.mock('../rule.utils'); +import { getFieldRules } from '../validation.utils'; describe('getFieldRules', () => { describe('extraValidation', () => { @@ -52,58 +49,4 @@ describe('getFieldRules', () => { expect(rules.validate.func2).toBeUndefined(); }); }); - - describe('getValidationRulesHints', () => { - const validation = { - foo: { - key: 'foo', - message: 'foo message' - }, - bar: { - key: 'bar', - message: 'bar message' - }, - required: { - key: 'required', - message: 'required message' - } - }; - - const config = {}; - - const t = jest.fn().mockImplementation((x) => x); - - rule.mockImplementation((x, y) => ({ - key: x, - check: y - })); - - beforeEach(() => { - t.mockClear(); - rule.mockClear(); - }); - - it('should pick the custom rules only', () => { - expect(getValidationRulesHints({ t, validation })).toEqual([ - { check: expect.any(Function), key: validation.foo.message }, - { check: expect.any(Function), key: validation.bar.message } - ]); - }); - - it('should assign a callback that evaluates to false when key is found in errors types', () => { - const result = getValidationRulesHints({ - t, - validation, - errors: { types: { foo: true } } - }); - expect(result[0].check()).toBeFalsy(); - expect(result[1].check()).toBeTruthy(); - }); - - it('should translate the message of each rule', () => { - getValidationRulesHints({ t, validation, config }); - expect(t).toBeCalledWith(validation.foo.message, config); - expect(t).toBeCalledWith(validation.bar.message, config); - }); - }); }); diff --git a/libs/form-builder/src/lib/utils/rule.utils.ts b/libs/form-builder/src/lib/utils/rule.utils.ts deleted file mode 100644 index 9efac68..0000000 --- a/libs/form-builder/src/lib/utils/rule.utils.ts +++ /dev/null @@ -1,27 +0,0 @@ -export const DEFAULT_STATE = 0; -export const COMPLETE_STATE = 1; -export const INCOMPLETE_STATE = 2; - -export type RuleCheck = (value: string | number) => boolean; - -export interface RuleObject { - key: string; - check: (value: any) => 0 | 1 | 2; -} - -export type Rule = (key: string, check: RuleCheck) => RuleObject; - -export const rule = (key: string, check: RuleCheck) => ({ - key, - check: (value: any) => { - if (typeof value === 'undefined' || !value.length) { - return DEFAULT_STATE; - } - - if (!check) { - return DEFAULT_STATE; - } - - return check(value) ? COMPLETE_STATE : INCOMPLETE_STATE; - } -}); diff --git a/libs/form-builder/src/lib/utils/validation.utils.ts b/libs/form-builder/src/lib/utils/validation.utils.ts index a99ae4c..88997b8 100644 --- a/libs/form-builder/src/lib/utils/validation.utils.ts +++ b/libs/form-builder/src/lib/utils/validation.utils.ts @@ -1,7 +1,6 @@ -import { FieldErrors, RegisterOptions } from 'react-hook-form'; +import { RegisterOptions } from 'react-hook-form'; import _ from 'lodash'; -import { RuleObject, rule } from './rule.utils'; import { DEFAULT_RULES_NAMES } from '../constants'; import { ExtraValidation, Validations } from '../types'; @@ -36,30 +35,3 @@ export const getFieldRules = ({ ...(hasExtraRules && { validate: extraRules }) }; }; - -interface AbstractMapOfString { - [key: string]: string; -} - -export interface GetValidationRulesHintsArgs { - t?: (value: string, config?: AbstractMapOfString) => string; - errors: FieldErrors; - validation: Validations; - config?: AbstractMapOfString; -} - -export const getValidationRulesHints = ({ - t = _.identity, - errors, - validation, - config -}: GetValidationRulesHintsArgs) => { - return Object.values(validation).reduce((acc, { message, key }) => { - return DEFAULT_RULES_NAMES[key] - ? acc - : [ - ...acc, - rule(t(message, config), () => !_.get(errors, ['types', key])) - ]; - }, [] as Array); -}; diff --git a/libs/form-validation-rule-list/README.md b/libs/form-validation-rule-list/README.md index 66a561f..d73510a 100644 --- a/libs/form-validation-rule-list/README.md +++ b/libs/form-validation-rule-list/README.md @@ -53,8 +53,8 @@ const schema = { Dictionary ```jsx -import { getValidationRulesHints } from '@bedrockstreaming/form-builder'; import { + getValidationRulesHints, checkRules, withValidationRuleList, } from '@bedrockstreaming/form-validation-rule-list'; diff --git a/libs/form-validation-rule-list/src/index.ts b/libs/form-validation-rule-list/src/index.ts index ca31eb6..95443d1 100644 --- a/libs/form-validation-rule-list/src/index.ts +++ b/libs/form-validation-rule-list/src/index.ts @@ -1,6 +1,7 @@ export * from './lib/rule'; export * from './lib/utils'; export * from './lib/constants'; +export * from './lib/getValidationRulesHints'; export * from './lib/components/dotText.component'; export * from './lib/components/dotTextList.component'; export * from './lib/components/validationRuleList.component'; diff --git a/libs/form-validation-rule-list/src/lib/__tests__/getValidationRulesHints.spec.ts b/libs/form-validation-rule-list/src/lib/__tests__/getValidationRulesHints.spec.ts new file mode 100644 index 0000000..8ce1022 --- /dev/null +++ b/libs/form-validation-rule-list/src/lib/__tests__/getValidationRulesHints.spec.ts @@ -0,0 +1,60 @@ +import { getValidationRulesHints } from '../getValidationRulesHints'; +import { rule } from '../rule'; + +jest.mock('../rule', () => ({ rule: jest.fn() })); + +const ruleMock = rule as unknown as jest.Mock; + +describe('getValidationRulesHints', () => { + const validation = { + foo: { + key: 'foo', + message: 'foo message' + }, + bar: { + key: 'bar', + message: 'bar message' + }, + required: { + key: 'required', + message: 'required message' + } + }; + + const config = {}; + + const t = jest.fn().mockImplementation((x) => x); + + ruleMock.mockImplementation((x, y) => ({ + key: x, + check: y + })); + + beforeEach(() => { + t.mockClear(); + ruleMock.mockClear(); + }); + + it('should pick the custom rules only', () => { + expect(getValidationRulesHints({ t, validation, errors: {} })).toEqual([ + { check: expect.any(Function), key: validation.foo.message }, + { check: expect.any(Function), key: validation.bar.message } + ]); + }); + + it('should assign a callback that evaluates to false when key is found in errors types', () => { + const result = getValidationRulesHints({ + t, + validation, + errors: { types: { foo: true } } + }); + expect(result[0].check()).toBeFalsy(); + expect(result[1].check()).toBeTruthy(); + }); + + it('should translate the message of each rule', () => { + getValidationRulesHints({ t, validation, config, errors: {} }); + expect(t).toBeCalledWith(validation.foo.message, config); + expect(t).toBeCalledWith(validation.bar.message, config); + }); +}); diff --git a/libs/form-validation-rule-list/src/lib/getValidationRulesHints.ts b/libs/form-validation-rule-list/src/lib/getValidationRulesHints.ts new file mode 100644 index 0000000..97224c7 --- /dev/null +++ b/libs/form-validation-rule-list/src/lib/getValidationRulesHints.ts @@ -0,0 +1,35 @@ +import { + Validations, + DEFAULT_RULES_NAMES +} from '@bedrockstreaming/form-builder'; +import { FieldErrors } from 'react-hook-form'; +import _ from 'lodash'; + +import { rule, RuleObject } from './rule'; + +interface AbstractMapOfString { + [key: string]: string; +} + +export interface GetValidationRulesHintsArgs { + t?: (value: string, config?: AbstractMapOfString) => string; + errors: FieldErrors; + validation: Validations; + config?: AbstractMapOfString; +} + +export const getValidationRulesHints = ({ + t = _.identity, + errors, + validation, + config +}: GetValidationRulesHintsArgs) => { + return Object.values(validation).reduce((acc, { message, key }) => { + return DEFAULT_RULES_NAMES[key] + ? acc + : [ + ...acc, + rule(t(message, config), () => !_.get(errors, ['types', key])) + ]; + }, [] as Array); +};