From ad35cab93bb83cce33b01d02f4cb796efcf21cdd Mon Sep 17 00:00:00 2001 From: Victor Garcia Date: Mon, 9 Dec 2024 15:59:20 +0100 Subject: [PATCH] chore: code cleanup --- .prettierrc | 2 +- README.md | 3 +- .../core/src/core/createRule/createRule.ts | 1 - packages/core/src/core/defaultValidators.ts | 28 +- packages/core/src/core/defineRegleConfig.ts | 12 +- .../useRegle/guards/rule.status.guards.ts | 12 +- .../core/useRegle/guards/ruleDef.guards.ts | 18 +- packages/core/src/core/useRegle/inferRules.ts | 16 +- packages/core/src/core/useRegle/useRegle.ts | 11 +- .../createReactiveCollectionElement.ts | 74 +++++ .../createReactiveCollectionRoot.ts} | 124 ++------ .../useStateProperties/common/common-types.ts | 28 ++ .../createReactiveFieldStatus.ts | 90 ++---- .../createReactiveNestedStatus.ts | 289 +++++++----------- .../createReactiveRuleStatus.ts | 14 +- .../useStateProperties/useStateProperties.ts | 5 +- .../core/src/core/useStorage/useStorage.ts | 9 +- packages/core/src/types/core/options.types.ts | 13 +- .../core/src/types/core/useRegle.types.ts | 52 ++-- .../src/types/rules/rule.declaration.types.ts | 19 +- .../src/types/rules/rule.definition.type.ts | 43 +-- .../core/src/types/rules/rule.errors.types.ts | 24 +- .../core/src/types/rules/rule.init.types.ts | 32 +- .../src/types/rules/rule.internal.types.ts | 14 +- .../core/src/types/rules/rule.params.types.ts | 4 +- .../core/src/types/rules/rule.status.types.ts | 33 +- packages/core/src/types/utils/groups.ts | 5 +- packages/core/src/types/utils/misc.types.ts | 18 +- packages/core/src/types/utils/props.types.ts | 14 +- packages/core/src/utils/object.utils.ts | 6 +- packages/core/src/utils/version-compare.ts | 3 +- packages/nuxt/package.json | 3 +- 32 files changed, 364 insertions(+), 655 deletions(-) create mode 100644 packages/core/src/core/useRegle/useStateProperties/collections/createReactiveCollectionElement.ts rename packages/core/src/core/useRegle/useStateProperties/{createReactiveCollectionStatus.ts => collections/createReactiveCollectionRoot.ts} (81%) create mode 100644 packages/core/src/core/useRegle/useStateProperties/common/common-types.ts diff --git a/.prettierrc b/.prettierrc index d1eba9b6..990cc569 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,5 @@ { - "printWidth": 100, + "printWidth": 120, "tabWidth": 2, "trailingComma": "es5", "singleQuote": true, diff --git a/README.md b/README.md index 1e70e68b..38722b89 100644 --- a/README.md +++ b/README.md @@ -54,9 +54,10 @@ TODO ### For v1.0 - [x] Unit tests -- [ ] E2E tests (in progress) +- [x] E2E tests - [ ] Type tests - [ ] Simplify/reduce core code +- [ ] `tip` on createRule - [ ] Example repo, Reproduction repl ### Next iterations diff --git a/packages/core/src/core/createRule/createRule.ts b/packages/core/src/core/createRule/createRule.ts index ac8c23a9..c13e3a4c 100644 --- a/packages/core/src/core/createRule/createRule.ts +++ b/packages/core/src/core/createRule/createRule.ts @@ -2,7 +2,6 @@ import type { InferRegleRule, RegleRuleInit, RegleRuleMetadataDefinition, - RegleRuleTypeReturn, RegleUniversalParams, } from '../../types'; import { defineRuleProcessors } from './defineRuleProcessors'; diff --git a/packages/core/src/core/defaultValidators.ts b/packages/core/src/core/defaultValidators.ts index 2cabe1b3..c60f0635 100644 --- a/packages/core/src/core/defaultValidators.ts +++ b/packages/core/src/core/defaultValidators.ts @@ -51,35 +51,15 @@ export type DefaultValidators = { >; integer: RegleRuleDefinition; ipAddress: RegleRuleDefinition; - macAddress: RegleRuleWithParamsDefinition< - string, - [separator?: string | undefined], - false, - boolean - >; - maxLength: RegleRuleWithParamsDefinition< - string | any[] | Record, - [count: number], - false, - boolean - >; + macAddress: RegleRuleWithParamsDefinition; + maxLength: RegleRuleWithParamsDefinition, [count: number], false, boolean>; maxValue: RegleRuleWithParamsDefinition; - minLength: RegleRuleWithParamsDefinition< - string | any[] | Record, - [count: number], - false, - boolean - >; + minLength: RegleRuleWithParamsDefinition, [count: number], false, boolean>; minValue: RegleRuleWithParamsDefinition; numeric: RegleRuleDefinition; regex: RegleRuleWithParamsDefinition; required: RegleRuleDefinition; - sameAs: RegleRuleWithParamsDefinition< - unknown, - [target: unknown, otherName?: string], - false, - boolean - >; + sameAs: RegleRuleWithParamsDefinition; startsWith: RegleRuleWithParamsDefinition], false, boolean>; url: RegleRuleDefinition; }; diff --git a/packages/core/src/core/defineRegleConfig.ts b/packages/core/src/core/defineRegleConfig.ts index 42ed148f..7ecee78d 100644 --- a/packages/core/src/core/defineRegleConfig.ts +++ b/packages/core/src/core/defineRegleConfig.ts @@ -1,9 +1,5 @@ import type { EmptyObject } from 'type-fest'; -import type { - AllRulesDeclarations, - RegleBehaviourOptions, - RegleShortcutDefinition, -} from '../types'; +import type { AllRulesDeclarations, RegleBehaviourOptions, RegleShortcutDefinition } from '../types'; import { createUseRegleComposable, type useRegleFn } from './useRegle'; import { createInferRuleHelper, type inferRulesFn } from './useRegle/inferRules'; @@ -22,11 +18,7 @@ export function defineRegleConfig< useRegle: useRegleFn; inferRules: inferRulesFn; } { - const useRegle = createUseRegleComposable( - rules, - modifiers, - shortcuts as any - ); + const useRegle = createUseRegleComposable(rules, modifiers, shortcuts as any); const inferRules = createInferRuleHelper(); return { useRegle, inferRules }; diff --git a/packages/core/src/core/useRegle/guards/rule.status.guards.ts b/packages/core/src/core/useRegle/guards/rule.status.guards.ts index 1ada580c..96299819 100644 --- a/packages/core/src/core/useRegle/guards/rule.status.guards.ts +++ b/packages/core/src/core/useRegle/guards/rule.status.guards.ts @@ -14,9 +14,7 @@ export function isNestedRulesStatus(rule: $InternalRegleStatusType): rule is $In return isObject(rule) && '$fields' in rule; } -export function isCollectionRulesStatus( - rule: $InternalRegleStatusType -): rule is $InternalRegleCollectionStatus { +export function isCollectionRulesStatus(rule: $InternalRegleStatusType): rule is $InternalRegleCollectionStatus { return !!rule && '$each' in rule; } @@ -30,14 +28,10 @@ export function isRuleStatus(rule: unknown): rule is $InternalRegleRuleStatus { // -- ExternalErrors -export function isNestedExternalErrorStatus( - rule: $InternalRegleErrors -): rule is RegleExternalErrorTree { +export function isNestedExternalErrorStatus(rule: $InternalRegleErrors): rule is RegleExternalErrorTree { return !!rule && '$each' in rule; } -export function isCollectionExternalErrorStatus( - rule: $InternalRegleErrors -): rule is RegleCollectionErrors { +export function isCollectionExternalErrorStatus(rule: $InternalRegleErrors): rule is RegleCollectionErrors { return !!rule && '$each' in rule; } diff --git a/packages/core/src/core/useRegle/guards/ruleDef.guards.ts b/packages/core/src/core/useRegle/guards/ruleDef.guards.ts index f5fb6526..715f1066 100644 --- a/packages/core/src/core/useRegle/guards/ruleDef.guards.ts +++ b/packages/core/src/core/useRegle/guards/ruleDef.guards.ts @@ -14,11 +14,7 @@ export function isNestedRulesDef( state: Ref, rules: Ref<$InternalFormPropertyTypes> ): rules is Ref<$InternalReglePartialRuleTree> { - return ( - isObject(state.value) && - isObject(rules.value) && - !Object.entries(rules.value).some((rule) => isRuleDef(rule)) - ); + return isObject(state.value) && isObject(rules.value) && !Object.entries(rules.value).some((rule) => isRuleDef(rule)); } export function isCollectionRulesDef( @@ -28,9 +24,7 @@ export function isCollectionRulesDef( return (!!rules.value && '$each' in rules.value) || Array.isArray(state.value); } -export function isValidatorRulesDef( - rules: Ref<$InternalFormPropertyTypes> -): rules is Ref<$InternalRegleRuleDecl> { +export function isValidatorRulesDef(rules: Ref<$InternalFormPropertyTypes>): rules is Ref<$InternalRegleRuleDecl> { return !!rules.value && isObject(rules.value); } @@ -38,15 +32,11 @@ export function isRuleDef(rule: unknown): rule is RegleRuleDefinition return isObject(rule) && '_validator' in rule; } -export function isFormRuleDefinition( - rule: Ref -): rule is Ref> { +export function isFormRuleDefinition(rule: Ref): rule is Ref> { return !(typeof rule.value === 'function'); } -export function isFormInline( - rule: Ref -): rule is Ref> { +export function isFormInline(rule: Ref): rule is Ref> { return typeof rule.value === 'function'; } diff --git a/packages/core/src/core/useRegle/inferRules.ts b/packages/core/src/core/useRegle/inferRules.ts index 0d2ae370..8d1c50e2 100644 --- a/packages/core/src/core/useRegle/inferRules.ts +++ b/packages/core/src/core/useRegle/inferRules.ts @@ -11,11 +11,7 @@ import type { NoInferLegacy, PrimitiveTypes, Unwrap } from '../../types/utils'; export interface inferRulesFn> { < TState extends Record, - TRules extends ReglePartialRuleTree< - Unwrap, - Partial & TCustomRules - > & - TValid, + TRules extends ReglePartialRuleTree, Partial & TCustomRules> & TValid, TValid = isDeepExact< NoInferLegacy, ReglePartialRuleTree, Partial & TCustomRules> @@ -26,10 +22,7 @@ export interface inferRulesFn state: MaybeRef | DeepReactiveState, rulesFactory: TRules ): TRules; - ( - state: MaybeRef, - rulesFactory: TRules - ): TRules; + (state: MaybeRef, rulesFactory: TRules): TRules; } export function createInferRuleHelper< @@ -37,10 +30,7 @@ export function createInferRuleHelper< >(): inferRulesFn { function inferRules( state: Record, - rulesFactory: - | Record - | (() => Record) - | ComputedRef> + rulesFactory: Record | (() => Record) | ComputedRef> ) { return rulesFactory; } diff --git a/packages/core/src/core/useRegle/useRegle.ts b/packages/core/src/core/useRegle/useRegle.ts index b833dbad..9f925f59 100644 --- a/packages/core/src/core/useRegle/useRegle.ts +++ b/packages/core/src/core/useRegle/useRegle.ts @@ -23,11 +23,7 @@ export type useRegleFn< TShortcuts extends RegleShortcutDefinition = never, > = < TState extends Record, - TRules extends ReglePartialRuleTree< - Unwrap, - Partial & TCustomRules - > & - TValid, + TRules extends ReglePartialRuleTree, Partial & TCustomRules> & TValid, TValidationGroups extends Record, TValid = isDeepExact< NoInferLegacy, @@ -59,10 +55,7 @@ export function createUseRegleComposable< function useRegle( state: MaybeRef> | DeepReactiveState>, - rulesFactory: - | Record - | (() => Record) - | ComputedRef>, + rulesFactory: Record | (() => Record) | ComputedRef>, options?: Partial> & LocalRegleBehaviourOptions, Record, any> ): Regle, Record, any, any> { diff --git a/packages/core/src/core/useRegle/useStateProperties/collections/createReactiveCollectionElement.ts b/packages/core/src/core/useRegle/useStateProperties/collections/createReactiveCollectionElement.ts new file mode 100644 index 00000000..3e8e3807 --- /dev/null +++ b/packages/core/src/core/useRegle/useStateProperties/collections/createReactiveCollectionElement.ts @@ -0,0 +1,74 @@ +import type { Ref } from 'vue'; +import { toRef } from 'vue'; +import type { + $InternalFormPropertyTypes, + $InternalRegleErrors, + $InternalRegleStatusType, + RegleCollectionRuleDeclKeyProperty, +} from '../../../../types'; +import { randomId } from '../../../../utils'; +import type { CommonResolverOptions, StateWithId } from '../common/common-types'; +import { createReactiveChildrenStatus } from './../createReactiveNestedStatus'; + +interface CreateCollectionElementArgs extends CommonResolverOptions { + $id: string; + index: number; + stateValue: Ref; + rules: $InternalFormPropertyTypes & RegleCollectionRuleDeclKeyProperty; + externalErrors: Ref<$InternalRegleErrors[] | undefined> | undefined; + initialState: any[] | undefined; +} + +export function createCollectionElement({ + $id, + path, + index, + options, + storage, + stateValue, + customMessages, + rules, + externalErrors, + initialState, + shortcuts, + fieldName, +}: CreateCollectionElementArgs): $InternalRegleStatusType | null { + const $fieldId = rules.$key ? rules.$key : randomId(); + let $path = `${path}.${String($fieldId)}`; + + if (typeof stateValue.value === 'object' && stateValue.value != null) { + if (!stateValue.value.$id) { + Object.defineProperties(stateValue.value, { + $id: { + value: $fieldId, + enumerable: false, + configurable: false, + writable: false, + }, + }); + } else { + $path = `${path}.${stateValue.value.$id}`; + } + } + + const $status = createReactiveChildrenStatus({ + state: stateValue, + rulesDef: toRef(() => rules), + customMessages, + path: $path, + storage, + options, + externalErrors: toRef(externalErrors?.value ?? [], index), + initialState: initialState?.[index], + shortcuts, + fieldName, + }); + + if ($status) { + const valueId = stateValue.value?.$id; + $status.$id = valueId ?? String($fieldId); + storage.addArrayStatus($id, $status.$id, $status); + } + + return $status; +} diff --git a/packages/core/src/core/useRegle/useStateProperties/createReactiveCollectionStatus.ts b/packages/core/src/core/useRegle/useStateProperties/collections/createReactiveCollectionRoot.ts similarity index 81% rename from packages/core/src/core/useRegle/useStateProperties/createReactiveCollectionStatus.ts rename to packages/core/src/core/useRegle/useStateProperties/collections/createReactiveCollectionRoot.ts index 1ff20c96..c54780ce 100644 --- a/packages/core/src/core/useRegle/useStateProperties/createReactiveCollectionStatus.ts +++ b/packages/core/src/core/useRegle/useStateProperties/collections/createReactiveCollectionRoot.ts @@ -16,89 +16,15 @@ import type { RegleCollectionRuleDeclKeyProperty, RegleShortcutDefinition, ResolvedRegleBehaviourOptions, -} from '../../../types'; -import { - cloneDeep, - isObject, - randomId, - resetArrayValuesRecursively, - unwrapGetter, -} from '../../../utils'; -import { isVueSuperiorOrEqualTo3dotFive } from '../../../utils/version-compare'; -import type { RegleStorage } from '../../useStorage'; -import { isNestedRulesStatus, isRuleDef } from '../guards'; -import { createReactiveFieldStatus } from './createReactiveFieldStatus'; -import { createReactiveChildrenStatus } from './createReactiveNestedStatus'; -import { isEmpty } from '../../../../../shared'; - -type StateWithId = unknown & { $id?: string }; - -function createCollectionElement({ - $id, - path, - index, - options, - storage, - stateValue, - customMessages, - rules, - externalErrors, - initialState, - shortcuts, - fieldName, -}: { - $id: string; - fieldName: string; - path: string; - index: number; - stateValue: Ref; - customMessages: CustomRulesDeclarationTree | undefined; - storage: RegleStorage; - options: DeepMaybeRef>; - rules: $InternalFormPropertyTypes & RegleCollectionRuleDeclKeyProperty; - externalErrors: Ref<$InternalRegleErrors[] | undefined> | undefined; - initialState: any[] | undefined; - shortcuts: RegleShortcutDefinition | undefined; -}): $InternalRegleStatusType | null { - const $fieldId = rules.$key ? rules.$key : randomId(); - let $path = `${path}.${String($fieldId)}`; - - if (typeof stateValue.value === 'object' && stateValue.value != null) { - if (!stateValue.value.$id) { - Object.defineProperties(stateValue.value, { - $id: { - value: $fieldId, - enumerable: false, - configurable: false, - writable: false, - }, - }); - } else { - $path = `${path}.${stateValue.value.$id}`; - } - } - - const $status = createReactiveChildrenStatus({ - state: stateValue, - rulesDef: toRef(() => rules), - customMessages, - path: $path, - storage, - options, - externalErrors: toRef(externalErrors?.value ?? [], index), - initialState: initialState?.[index], - shortcuts, - fieldName, - }); - - if ($status) { - const valueId = stateValue.value?.$id; - $status.$id = valueId ?? String($fieldId); - storage.addArrayStatus($id, $status.$id, $status); - } - - return $status; -} +} from '../../../../types'; +import { cloneDeep, isObject, randomId, resetArrayValuesRecursively, unwrapGetter } from '../../../../utils'; +import { isVueSuperiorOrEqualTo3dotFive } from '../../../../utils/version-compare'; +import type { RegleStorage } from '../../../useStorage'; +import { isNestedRulesStatus, isRuleDef } from '../../guards'; +import { createReactiveFieldStatus } from './../createReactiveFieldStatus'; +import { isEmpty } from '../../../../../../shared'; +import type { StateWithId } from '../common/common-types'; +import { createCollectionElement } from './createReactiveCollectionElement'; interface CreateReactiveCollectionStatusArgs { state: Ref; @@ -398,21 +324,23 @@ export function createReactiveCollectionStatus({ const result = ref(); watchEffect(() => { - result.value = value({ - $dirty: $dirty.value, - $error: $error.value, - $pending: $pending.value, - $invalid: $invalid.value, - $valid: $valid.value, - $errors: $errors.value as any, - $ready: $ready.value, - $silentErrors: $silentErrors.value as any, - $anyDirty: $anyDirty.value, - $name: $name.value, - $each: $eachStatus.value, - $field: $fieldStatus.value as any, - $value: state as any, - }); + result.value = value( + reactive({ + $dirty, + $error, + $pending, + $invalid, + $valid, + $errors: $errors as any, + $ready, + $silentErrors: $silentErrors as any, + $anyDirty, + $name: $name, + $each: $eachStatus, + $field: $fieldStatus as any, + $value: state, + }) + ); }); return result; })!; diff --git a/packages/core/src/core/useRegle/useStateProperties/common/common-types.ts b/packages/core/src/core/useRegle/useStateProperties/common/common-types.ts new file mode 100644 index 00000000..cec8eaa3 --- /dev/null +++ b/packages/core/src/core/useRegle/useStateProperties/common/common-types.ts @@ -0,0 +1,28 @@ +import type { ComputedRef } from 'vue'; +import type { + CustomRulesDeclarationTree, + RegleShortcutDefinition, + ResolvedRegleBehaviourOptions, +} from '../../../../types'; +import type { RegleStorage } from '../../../useStorage'; + +export type StateWithId = unknown & { $id?: string }; + +export interface CommonResolverOptions { + customMessages: CustomRulesDeclarationTree | undefined; + path: string; + index?: number; + storage: RegleStorage; + options: ResolvedRegleBehaviourOptions; + fieldName: string; + shortcuts: RegleShortcutDefinition | undefined; +} + +export interface CommonResolverScopedState { + $anyDirty: ComputedRef; + $invalid: ComputedRef; + $valid: ComputedRef; + $error: ComputedRef; + $pending: ComputedRef; + $name: ComputedRef; +} diff --git a/packages/core/src/core/useRegle/useStateProperties/createReactiveFieldStatus.ts b/packages/core/src/core/useRegle/useStateProperties/createReactiveFieldStatus.ts index 1209e287..d88607e0 100644 --- a/packages/core/src/core/useRegle/useStateProperties/createReactiveFieldStatus.ts +++ b/packages/core/src/core/useRegle/useStateProperties/createReactiveFieldStatus.ts @@ -1,36 +1,27 @@ import type { ComputedRef, EffectScope, Ref, ToRefs, WatchStopHandle } from 'vue'; import { computed, effectScope, reactive, ref, toRef, unref, watch, watchEffect } from 'vue'; +import { isEmpty } from '../../../../../shared'; import type { $InternalRegleFieldStatus, $InternalRegleResult, $InternalRegleRuleDecl, $InternalRegleRuleStatus, - CustomRulesDeclarationTree, FieldRegleBehaviourOptions, RegleRuleDecl, RegleShortcutDefinition, - ResolvedRegleBehaviourOptions, } from '../../../types'; import { debounce, isVueSuperiorOrEqualTo3dotFive, resetFieldValue } from '../../../utils'; -import type { RegleStorage } from '../../useStorage'; import { extractRulesErrors } from '../useErrors'; +import type { CommonResolverOptions, CommonResolverScopedState } from './common/common-types'; import { createReactiveRuleStatus } from './createReactiveRuleStatus'; -import { isEmpty } from '../../../../../shared'; -interface CreateReactiveFieldStatusArgs { +interface CreateReactiveFieldStatusArgs extends CommonResolverOptions { state: Ref; rulesDef: Ref<$InternalRegleRuleDecl>; - customMessages: CustomRulesDeclarationTree | undefined; - path: string; - fieldName: string; - index?: number; - storage: RegleStorage; - options: ResolvedRegleBehaviourOptions; externalErrors: Ref | undefined; onUnwatch?: () => void; $isArray?: boolean; initialState: unknown | undefined; - shortcuts: RegleShortcutDefinition | undefined; } export function createReactiveFieldStatus({ @@ -47,25 +38,19 @@ export function createReactiveFieldStatus({ initialState, shortcuts, }: CreateReactiveFieldStatusArgs): $InternalRegleFieldStatus { - type ScopeReturnState = { - $error: ComputedRef; - $errors: ComputedRef; - $silentErrors: ComputedRef; - $pending: ComputedRef; - $invalid: ComputedRef; - $valid: ComputedRef; + interface ScopeReturnState extends CommonResolverScopedState { $debounce: ComputedRef; $lazy: ComputedRef; $rewardEarly: ComputedRef; $autoDirty: ComputedRef; $clearExternalErrorsOnChange: ComputedRef; - $anyDirty: ComputedRef; - haveAnyAsyncRule: ComputedRef; + $errors: ComputedRef; + $silentErrors: ComputedRef; + $haveAnyAsyncRule: ComputedRef; $ready: ComputedRef; - $name: ComputedRef; $shortcuts: ToRefs; $validating: Ref; - }; + } let scope = effectScope(); let scopeState!: ScopeReturnState; @@ -132,10 +117,7 @@ export function createReactiveFieldStatus({ function define$commit() { $commit = scopeState.$debounce.value - ? debounce( - $commitHandler, - (scopeState.$debounce.value ?? scopeState.haveAnyAsyncRule) ? 100 : 0 - ) + ? debounce($commitHandler, (scopeState.$debounce.value ?? scopeState.$haveAnyAsyncRule) ? 100 : 0) : $commitHandler; } @@ -277,7 +259,7 @@ export function createReactiveFieldStatus({ return false; }); - const haveAnyAsyncRule = computed(() => { + const $haveAnyAsyncRule = computed(() => { return Object.entries($rules.value).some(([key, ruleResult]) => { return ruleResult._haveAsync; }); @@ -292,21 +274,23 @@ export function createReactiveFieldStatus({ const result = ref(); watchEffect(() => { - result.value = value({ - $dirty: $dirty.value, - $externalErrors: externalErrors?.value ?? [], - $value: state, - $rules: $rules.value, - $error: $error.value, - $pending: $pending.value, - $invalid: $invalid.value, - $valid: $valid.value, - $errors: $errors.value, - $ready: $ready.value, - $silentErrors: $silentErrors.value, - $anyDirty: $anyDirty.value, - $name: $name.value, - }); + result.value = value( + reactive({ + $dirty, + $externalErrors: externalErrors?.value ?? [], + $value: state, + $rules, + $error, + $pending, + $invalid, + $valid, + $errors, + $ready, + $silentErrors, + $anyDirty, + $name, + }) + ); }); return result; })!; @@ -340,7 +324,7 @@ export function createReactiveFieldStatus({ $clearExternalErrorsOnChange, $anyDirty, $name, - haveAnyAsyncRule, + $haveAnyAsyncRule, $shortcuts, $validating, } satisfies ScopeReturnState; @@ -357,16 +341,10 @@ export function createReactiveFieldStatus({ if (rulesDef.value instanceof Function) { createReactiveRulesResult(); } - if ( - scopeState.$autoDirty.value || - (scopeState.$rewardEarly.value && scopeState.$error.value) - ) { + if (scopeState.$autoDirty.value || (scopeState.$rewardEarly.value && scopeState.$error.value)) { $commit(); } - if ( - scopeState.$rewardEarly.value !== true && - scopeState.$clearExternalErrorsOnChange.value - ) { + if (scopeState.$rewardEarly.value !== true && scopeState.$clearExternalErrorsOnChange.value) { $clearExternalErrors(); } }, @@ -383,7 +361,7 @@ export function createReactiveFieldStatus({ } }); - $unwatchAsync = watch(scopeState.haveAnyAsyncRule, define$commit); + $unwatchAsync = watch(scopeState.$haveAnyAsyncRule, define$commit); } function $commitHandler() { @@ -416,10 +394,7 @@ export function createReactiveFieldStatus({ } if (withConditions && runCommit) { - if ( - scopeState.$autoDirty.value || - (scopeState.$rewardEarly.value && scopeState.$error.value) - ) { + if (scopeState.$autoDirty.value || (scopeState.$rewardEarly.value && scopeState.$error.value)) { $commit(); } } else if (runCommit) { @@ -453,6 +428,7 @@ export function createReactiveFieldStatus({ return false; } }); + return { result: validationResults, data }; } catch (e) { return { result: false, data: state.value }; diff --git a/packages/core/src/core/useRegle/useStateProperties/createReactiveNestedStatus.ts b/packages/core/src/core/useRegle/useStateProperties/createReactiveNestedStatus.ts index f85cb851..a6fa89f7 100644 --- a/packages/core/src/core/useRegle/useStateProperties/createReactiveNestedStatus.ts +++ b/packages/core/src/core/useRegle/useStateProperties/createReactiveNestedStatus.ts @@ -1,89 +1,55 @@ -import type { RequiredDeep } from 'type-fest'; import type { ComputedRef, EffectScope, Ref, ToRefs, WatchStopHandle } from 'vue'; -import { - computed, - effectScope, - reactive, - ref, - toRef, - triggerRef, - unref, - watch, - watchEffect, -} from 'vue'; +import { computed, effectScope, reactive, ref, toRef, triggerRef, unref, watch, watchEffect } from 'vue'; +import { isEmpty } from '../../../../../shared'; import type { $InternalFormPropertyTypes, - $InternalRegleCollectionErrors, $InternalRegleErrors, $InternalRegleErrorTree, $InternalReglePartialRuleTree, $InternalRegleResult, $InternalRegleStatus, $InternalRegleStatusType, - CustomRulesDeclarationTree, - DeepMaybeRef, - RegleBehaviourOptions, RegleShortcutDefinition, RegleValidationGroupEntry, RegleValidationGroupOutput, - ResolvedRegleBehaviourOptions, } from '../../../types'; import { mergeArrayGroupProperties, mergeBooleanGroupProperties } from '../../../types'; import { isObject, isRefObject, resetValuesRecursively } from '../../../utils'; -import type { RegleStorage } from '../../useStorage'; import { isCollectionRulesDef, isNestedRulesDef, isValidatorRulesDef } from '../guards'; -import { createReactiveCollectionStatus } from './createReactiveCollectionStatus'; +import type { CommonResolverOptions, CommonResolverScopedState } from './common/common-types'; import { createReactiveFieldStatus } from './createReactiveFieldStatus'; -import { isEmpty } from '../../../../../shared'; +import { createReactiveCollectionStatus } from './collections/createReactiveCollectionRoot'; -interface CreateReactiveNestedStatus { - rootRules?: Ref<$InternalReglePartialRuleTree>; - scopeRules: Ref<$InternalReglePartialRuleTree>; +interface CreateReactiveNestedStatus extends CommonResolverOptions { state: Ref>; - customMessages: CustomRulesDeclarationTree | undefined; - path?: string; - index?: number; - storage: RegleStorage; - options: ResolvedRegleBehaviourOptions; - externalErrors: Ref<$InternalRegleErrorTree | undefined> | undefined; + rootRules?: Ref<$InternalReglePartialRuleTree>; + rulesDef: Ref<$InternalReglePartialRuleTree>; initialState: Record | undefined; - fieldName: string; - shortcuts: RegleShortcutDefinition | undefined; + externalErrors: Ref<$InternalRegleErrorTree | undefined> | undefined; validationGroups?: - | ((rules: { - [x: string]: $InternalRegleStatusType; - }) => Record) + | ((rules: { [x: string]: $InternalRegleStatusType }) => Record) | undefined; } export function createReactiveNestedStatus({ - scopeRules, + rulesDef, state, - customMessages, path = '', rootRules, - storage, - options, externalErrors, validationGroups, initialState, - shortcuts, fieldName, + ...commonArgs }: CreateReactiveNestedStatus): $InternalRegleStatus { - type ScopeState = { + interface ScopeState extends CommonResolverScopedState { $dirty: ComputedRef; - $anyDirty: ComputedRef; - $invalid: ComputedRef; - $valid: ComputedRef; - $error: ComputedRef; - $pending: ComputedRef; $errors: ComputedRef>; $silentErrors: ComputedRef>; $ready: ComputedRef; - $name: ComputedRef; $shortcuts: ToRefs; $groups: ComputedRef>; - }; + } let scope = effectScope(); let scopeState!: ScopeState; @@ -95,85 +61,68 @@ export function createReactiveNestedStatus({ let $unwatchGroups: WatchStopHandle | null = null; async function createReactiveFieldsStatus(watch = true) { + const mapOfRulesDef = Object.entries(rulesDef.value); const scopedRulesStatus = Object.fromEntries( - Object.entries(scopeRules.value) + mapOfRulesDef + .filter(([_, rule]) => !!rule) .map(([statePropKey, statePropRules]) => { if (statePropRules) { const stateRef = toRef(state.value, statePropKey); - triggerRef(stateRef); const statePropRulesRef = toRef(() => statePropRules); - - const $externalErrors = toRef(externalErrors?.value!, statePropKey); + const $externalErrors = toRef(externalErrors?.value ?? {}, statePropKey); return [ statePropKey, createReactiveChildrenStatus({ state: stateRef, rulesDef: statePropRulesRef, - customMessages, path: path ? `${path}.${statePropKey}` : statePropKey, - storage, - options, externalErrors: $externalErrors, initialState: initialState?.[statePropKey], - shortcuts, fieldName: statePropKey, + ...commonArgs, }), ]; } return []; }) - .filter( - (rule): rule is [string, $InternalRegleStatusType] => !!rule.length && rule[1] != null - ) ); const externalRulesStatus = Object.fromEntries( Object.entries(unref(externalErrors) ?? {}) - .filter(([key]) => !(key in scopeRules.value)) - .map(([key, errors]) => { - if (errors) { - const stateRef = toRef(state.value, key); - return [ - key, - createReactiveChildrenStatus({ - state: stateRef, - rulesDef: computed(() => ({})), - customMessages, - path: path ? `${path}.${key}` : key, - storage, - options, - externalErrors: toRef(externalErrors?.value ?? {}, key), - initialState: initialState?.[key], - shortcuts, - fieldName: key, - }), - ]; - } - return []; + .filter(([key, errors]) => !(key in rulesDef.value) && !!errors) + .map(([key]) => { + const stateRef = toRef(state.value, key); + return [ + key, + createReactiveChildrenStatus({ + state: stateRef, + rulesDef: computed(() => ({})), + path: path ? `${path}.${key}` : key, + externalErrors: toRef(externalErrors?.value ?? {}, key), + initialState: initialState?.[key], + fieldName: key, + ...commonArgs, + }), + ]; }) ); const statesWithNoRules = Object.fromEntries( Object.entries(state.value) - .filter( - ([key]) => !(key in scopeRules.value) && !(key in (externalRulesStatus.value ?? {})) - ) - .map(([key, value]) => { + .filter(([key]) => !(key in rulesDef.value) && !(key in (externalRulesStatus.value ?? {}))) + .map(([key]) => { const stateRef = toRef(state.value, key); return [ key, createReactiveChildrenStatus({ state: stateRef, rulesDef: computed(() => ({})), - customMessages, path: path ? `${path}.${key}` : key, - storage, - options, externalErrors: toRef(externalErrors?.value ?? {}, key), initialState: initialState?.[key], - shortcuts, fieldName: key, + ...commonArgs, }), ]; }) @@ -189,7 +138,9 @@ export function createReactiveNestedStatus({ } } - const $fields: Ref> = storage.getFieldsEntry(path); + const $fields: Ref> = commonArgs.storage.getFieldsEntry(path); + + // Create reactive nested fields createReactiveFieldsStatus(); function $reset(): void { @@ -206,29 +157,6 @@ export function createReactiveNestedStatus({ }); } - async function $validate(): Promise<$InternalRegleResult> { - try { - const data = state.value; - - const results = await Promise.allSettled( - Object.values($fields.value).map((statusOrField) => { - return statusOrField.$validate(); - }) - ); - - const validationResults = results.every((value) => { - if (value.status === 'fulfilled') { - return value.value.result === true; - } else { - return false; - } - }); - return { result: validationResults, data }; - } catch (e) { - return { result: false, data: state.value }; - } - } - function define$WatchExternalErrors() { if (externalErrors?.value) { $unwatchExternalErrors = watch( @@ -300,7 +228,7 @@ export function createReactiveNestedStatus({ }); const $ready = computed(() => { - if (!unref(options.autoDirty)) { + if (!unref(commonArgs.options.autoDirty)) { return !($invalid.value || $pending.value); } return $anyDirty.value && !($invalid.value || $pending.value); @@ -312,7 +240,7 @@ export function createReactiveNestedStatus({ }); }); - const $errors = computed(() => { + const $errors = computed>(() => { return Object.fromEntries( Object.entries($fields.value).map(([key, statusOrField]) => { return [key, statusOrField?.$errors]; @@ -320,7 +248,7 @@ export function createReactiveNestedStatus({ ); }); - const $silentErrors = computed(() => { + const $silentErrors = computed>(() => { return Object.fromEntries( Object.entries($fields.value).map(([key, statusOrField]) => { return [key, statusOrField?.$silentErrors]; @@ -331,28 +259,30 @@ export function createReactiveNestedStatus({ const $name = computed(() => fieldName); function processShortcuts() { - if (shortcuts?.nested) { - Object.entries(shortcuts.nested).forEach(([key, value]) => { + if (commonArgs.shortcuts?.nested) { + Object.entries(commonArgs.shortcuts.nested).forEach(([key, value]) => { const scope = effectScope(); $shortcuts[key] = scope.run(() => { const result = ref(); watchEffect(() => { - result.value = value({ - $dirty: $dirty.value, - $value: state, - $error: $error.value, - $pending: $pending.value, - $invalid: $invalid.value, - $valid: $valid.value, - $ready: $ready.value, - $anyDirty: $anyDirty.value, - $name: $name.value, - $silentErrors: $silentErrors.value as any, - $errors: $errors.value as any, - $fields: $fields.value, - }); + result.value = value( + reactive({ + $dirty, + $value: state, + $error, + $pending, + $invalid, + $valid, + $ready, + $anyDirty, + $name, + $silentErrors: $silentErrors as any, + $errors: $errors as any, + $fields, + }) + ); }); return result; })!; @@ -371,9 +301,10 @@ export function createReactiveNestedStatus({ key, { ...Object.fromEntries( - (['$invalid', '$error', '$pending', '$dirty', '$valid'] as const).map( - (property) => [property, mergeBooleanGroupProperties(entries, property)] - ) + (['$invalid', '$error', '$pending', '$dirty', '$valid'] as const).map((property) => [ + property, + mergeBooleanGroupProperties(entries, property), + ]) ), ...Object.fromEntries( (['$errors', '$silentErrors'] as const).map((property) => [ @@ -459,6 +390,29 @@ export function createReactiveNestedStatus({ return Object.fromEntries(dirtyFields); } + async function $validate(): Promise<$InternalRegleResult> { + try { + const data = state.value; + + const results = await Promise.allSettled( + Object.values($fields.value).map((statusOrField) => { + return statusOrField.$validate(); + }) + ); + + const validationResults = results.every((value) => { + if (value.status === 'fulfilled') { + return value.value.result === true; + } else { + return false; + } + }); + return { result: validationResults, data }; + } catch (e) { + return { result: false, data: state.value }; + } + } + const { $shortcuts, ...restScopeState } = scopeState; return reactive({ @@ -477,77 +431,38 @@ export function createReactiveNestedStatus({ }) satisfies $InternalRegleStatus; } -interface CreateReactiveChildrenStatus { - state: Ref; +interface CreateReactiveChildrenStatus extends CommonResolverOptions { + state: Ref; rulesDef: Ref<$InternalFormPropertyTypes>; - customMessages: CustomRulesDeclarationTree | undefined; - path: string; - index?: number; - storage: RegleStorage; - options: DeepMaybeRef>; externalErrors: Ref<$InternalRegleErrors | undefined> | undefined; initialState: any; - fieldName: string; - shortcuts: RegleShortcutDefinition | undefined; - onUnwatch?: () => void; } +/** + * Main resolver divider, will distribute the logic depending on the type of the current value (primitive, object, array) + */ export function createReactiveChildrenStatus({ - state, rulesDef, - customMessages, - path, - storage, - options, externalErrors, - index, - initialState, - shortcuts, - onUnwatch, - fieldName, + ...properties }: CreateReactiveChildrenStatus): $InternalRegleStatusType | null { - if (isCollectionRulesDef(rulesDef, state)) { + if (isCollectionRulesDef(rulesDef, properties.state)) { return createReactiveCollectionStatus({ - state: state as Ref, rulesDef, - customMessages, - path, - storage, - options, - index, - externalErrors: externalErrors as Ref<$InternalRegleCollectionErrors>, - initialState, - fieldName, - shortcuts, + externalErrors: externalErrors as any, + ...properties, }); - } else if (isNestedRulesDef(state, rulesDef) && isRefObject(state)) { + } else if (isNestedRulesDef(properties.state, rulesDef) && isRefObject(properties.state)) { return createReactiveNestedStatus({ - scopeRules: rulesDef, - state, - customMessages, - path, - storage, - options, - index, - initialState, - shortcuts, - fieldName, - externalErrors: externalErrors as Readonly>, + rulesDef, + externalErrors: externalErrors as any, + ...properties, }); } else if (isValidatorRulesDef(rulesDef)) { return createReactiveFieldStatus({ - state, rulesDef, - customMessages, - path, - storage, - options, - index, - externalErrors: externalErrors as Ref, - onUnwatch, - shortcuts, - initialState, - fieldName, + externalErrors: externalErrors as any, + ...properties, }); } diff --git a/packages/core/src/core/useRegle/useStateProperties/createReactiveRuleStatus.ts b/packages/core/src/core/useRegle/useStateProperties/createReactiveRuleStatus.ts index efbf2947..0e14c95b 100644 --- a/packages/core/src/core/useRegle/useStateProperties/createReactiveRuleStatus.ts +++ b/packages/core/src/core/useRegle/useStateProperties/createReactiveRuleStatus.ts @@ -41,11 +41,7 @@ export function createReactiveRuleStatus({ $message: ComputedRef; $type: ComputedRef; $validator: ComputedRef< - RegleRuleDefinitionProcessor< - any, - any, - RegleRuleMetadataDefinition | Promise - > + RegleRuleDefinitionProcessor> >; $params: ComputedRef; $path: ComputedRef; @@ -57,9 +53,7 @@ export function createReactiveRuleStatus({ const _haveAsync = ref(false); - const { $pending, $valid, $metadata, $validating } = storage.trySetRuleStatusRef( - `${path}.${ruleKey}` - ); + const { $pending, $valid, $metadata, $validating } = storage.trySetRuleStatusRef(`${path}.${ruleKey}`); function $watch() { scopeState = scope.run(() => { @@ -118,9 +112,7 @@ export function createReactiveRuleStatus({ } }); - const $validator = computed< - RegleRuleDefinitionProcessor> - >(() => { + const $validator = computed>>(() => { if (isFormRuleDefinition(rule)) { return rule.value.validator; } else { diff --git a/packages/core/src/core/useRegle/useStateProperties/useStateProperties.ts b/packages/core/src/core/useRegle/useStateProperties/useStateProperties.ts index 2d286f32..b84ba428 100644 --- a/packages/core/src/core/useRegle/useStateProperties/useStateProperties.ts +++ b/packages/core/src/core/useRegle/useStateProperties/useStateProperties.ts @@ -1,5 +1,5 @@ import type { ComputedRef, Ref } from 'vue'; -import { computed, reactive, unref } from 'vue'; +import { reactive } from 'vue'; import type { $InternalReglePartialRuleTree, CustomRulesDeclarationTree, @@ -29,7 +29,7 @@ export function useStateProperties({ const regle = reactive( createReactiveNestedStatus({ rootRules: scopeRules, - scopeRules, + rulesDef: scopeRules, state, customMessages: customRules?.(), storage, @@ -39,6 +39,7 @@ export function useStateProperties({ initialState, shortcuts, fieldName: 'root', + path: '', }) ); diff --git a/packages/core/src/core/useStorage/useStorage.ts b/packages/core/src/core/useStorage/useStorage.ts index cdc57c84..de3fe1a0 100644 --- a/packages/core/src/core/useStorage/useStorage.ts +++ b/packages/core/src/core/useStorage/useStorage.ts @@ -17,9 +17,7 @@ export type RegleStorage = ReturnType; */ export function useStorage() { const ruleDeclStorage = shallowRef(new Map>()); - const fieldsStorage = shallowRef( - new Map>>() - ); + const fieldsStorage = shallowRef(new Map>>()); const collectionsStorage = shallowRef(new Map>>()); const dirtyStorage = shallowRef(new Map()); const ruleStatusStorage = shallowRef(new Map()); @@ -76,10 +74,7 @@ export function useStorage() { ruleDeclStorage.value.set($path, options); } - function checkRuleDeclEntry( - $path: string, - newRules: RegleRuleDecl - ): { valid: boolean } | undefined { + function checkRuleDeclEntry($path: string, newRules: RegleRuleDecl): { valid: boolean } | undefined { const storedRulesDefs = ruleDeclStorage.value.get($path); if (!storedRulesDefs) return undefined; diff --git a/packages/core/src/types/core/options.types.ts b/packages/core/src/types/core/options.types.ts index f479bd36..4dc6336a 100644 --- a/packages/core/src/types/core/options.types.ts +++ b/packages/core/src/types/core/options.types.ts @@ -69,18 +69,11 @@ export type ShortcutCommonFn> = { }; export type RegleShortcutDefinition = {}> = { - fields?: ShortcutCommonFn< - RegleFieldStatus & Partial> - >; + fields?: ShortcutCommonFn & Partial>>; nested?: ShortcutCommonFn< - RegleStatus< - Record, - ReglePartialRuleTree & Partial> - > - >; - collections?: ShortcutCommonFn< - RegleCollectionStatus & Partial> + RegleStatus, ReglePartialRuleTree & Partial>> >; + collections?: ShortcutCommonFn & Partial>>; }; export type AddDollarToOptions> = { diff --git a/packages/core/src/types/core/useRegle.types.ts b/packages/core/src/types/core/useRegle.types.ts index 69a10e33..aa23a8a5 100644 --- a/packages/core/src/types/core/useRegle.types.ts +++ b/packages/core/src/types/core/useRegle.types.ts @@ -23,10 +23,7 @@ export interface Regle< } export type isDeepExact = { - [K in keyof T]-?: CheckDeepExact< - NonNullable, - K extends keyof U ? NonNullable : never - >; + [K in keyof T]-?: CheckDeepExact, K extends keyof U ? NonNullable : never>; }[keyof T] extends true ? true : false; @@ -58,13 +55,14 @@ export type DeepSafeFormState< ? {} : Prettify< { - [K in keyof TState as IsPropertyOutputRequired extends false - ? K - : never]?: SafeProperty; + [K in keyof TState as IsPropertyOutputRequired extends false ? K : never]?: SafeProperty< + TState[K], + TRules[K] + >; } & { - [K in keyof TState as IsPropertyOutputRequired extends false - ? never - : K]-?: NonNullable>; + [K in keyof TState as IsPropertyOutputRequired extends false ? never : K]-?: NonNullable< + SafeProperty + >; } >; @@ -81,29 +79,20 @@ type FieldHaveRequiredRule = unknown extends TRule[ type ObjectHaveAtLeastOneRequiredField> = TState extends Maybe ? { - [K in keyof TRule]: TRule[K] extends RegleRuleDecl - ? FieldHaveRequiredRule - : false; + [K in keyof TRule]: TRule[K] extends RegleRuleDecl ? FieldHaveRequiredRule : false; }[keyof TRule] : true; -type ArrayHaveAtLeastOneRequiredField< - TState, - TRule extends RegleCollectionRuleDefinition, -> = +type ArrayHaveAtLeastOneRequiredField> = TState extends Maybe ? { - [K in keyof ExtractFromGetter]: ExtractFromGetter< - TRule['$each'] - >[K] extends RegleRuleDecl + [K in keyof ExtractFromGetter]: ExtractFromGetter[K] extends RegleRuleDecl ? FieldHaveRequiredRule[K]> : false; }[keyof ExtractFromGetter] : true; -export type SafeProperty | undefined> = [ - unknown, -] extends [TState] +export type SafeProperty | undefined> = [unknown] extends [TState] ? unknown : TRule extends RegleCollectionRuleDefinition ? TState extends Array> @@ -111,10 +100,7 @@ export type SafeProperty | : TState : TRule extends ReglePartialRuleTree ? ExtendOnlyRealRecord extends true - ? DeepSafeFormState< - NonNullable extends Record ? NonNullable : {}, - TRule - > + ? DeepSafeFormState extends Record ? NonNullable : {}, TRule> : TRule extends RegleRuleDecl ? FieldHaveRequiredRule extends true ? TState @@ -122,10 +108,9 @@ export type SafeProperty | : TState : TState; -export type IsPropertyOutputRequired< - TState, - TRule extends RegleFormPropertyType | undefined, -> = [unknown] extends [TState] +export type IsPropertyOutputRequired | undefined> = [ + unknown, +] extends [TState] ? unknown : TRule extends RegleCollectionRuleDefinition ? TState extends Array @@ -145,10 +130,7 @@ export type IsPropertyOutputRequired< : false : false; -export type SafeFieldProperty< - TState, - TRule extends RegleFormPropertyType | undefined = never, -> = +export type SafeFieldProperty | undefined = never> = TRule extends RegleRuleDecl ? unknown extends TRule['required'] ? Maybe diff --git a/packages/core/src/types/rules/rule.declaration.types.ts b/packages/core/src/types/rules/rule.declaration.types.ts index 3a4a621d..e15fd40e 100644 --- a/packages/core/src/types/rules/rule.declaration.types.ts +++ b/packages/core/src/types/rules/rule.declaration.types.ts @@ -34,9 +34,7 @@ export type RegleRuleTree< */ export type RegleComputedRules< TForm extends MaybeRef> | DeepReactiveState>, - TCustomRules extends - | Partial - | Regle = Partial, + TCustomRules extends Partial | Regle = Partial, TState = Unwrap, TCustom = TCustomRules extends Regle ? R extends ReglePartialRuleTree @@ -96,15 +94,14 @@ export type RegleRuleDecl< TValue extends any = any, TCustomRules extends Partial = Partial, > = FieldRegleBehaviourOptions & { - [TKey in keyof TCustomRules]?: NonNullable< - TCustomRules[TKey] - > extends RegleRuleWithParamsDefinition + [TKey in keyof TCustomRules]?: NonNullable extends RegleRuleWithParamsDefinition< + any, + infer TParams + > ? RegleRuleDefinition : NonNullable extends RegleRuleDefinition ? FormRuleDeclaration - : - | FormRuleDeclaration - | FieldRegleBehaviourOptions[keyof FieldRegleBehaviourOptions]; + : FormRuleDeclaration | FieldRegleBehaviourOptions[keyof FieldRegleBehaviourOptions]; }; /** @@ -173,6 +170,4 @@ export type FormRuleDeclaration< | Promise, TMetadata extends RegleRuleMetadataDefinition = TReturn extends Promise ? M : TReturn, TAsync extends boolean = boolean, -> = - | InlineRuleDeclaration - | RegleRuleDefinition; +> = InlineRuleDeclaration | RegleRuleDefinition; diff --git a/packages/core/src/types/rules/rule.definition.type.ts b/packages/core/src/types/rules/rule.definition.type.ts index ffe868bc..dcfdb902 100644 --- a/packages/core/src/types/rules/rule.definition.type.ts +++ b/packages/core/src/types/rules/rule.definition.type.ts @@ -1,12 +1,7 @@ import type { RegleRuleCore } from './rule.init.types'; import type { RegleUniversalParams } from './rule.params.types'; import type { RegleInternalRuleDefs } from './rule.internal.types'; -import type { - AllRulesDeclarations, - RegleCommonStatus, - RegleFormPropertyType, - RegleRuleDecl, -} from '.'; +import type { AllRulesDeclarations, RegleCommonStatus, RegleFormPropertyType, RegleRuleDecl } from '.'; import type { ArrayElement, ExcludeByType, Maybe, MaybeGetter } from '../utils'; import type { FieldRegleBehaviourOptions } from '../core'; @@ -30,11 +25,7 @@ export interface RegleRuleDefinition< PossibleRegleRuleMetadataConsumer, string | string[] >; - active: RegleRuleDefinitionWithMetadataProcessor< - TFilteredValue, - PossibleRegleRuleMetadataConsumer, - boolean - >; + active: RegleRuleDefinitionWithMetadataProcessor; type?: string; exec: (value: Maybe) => TAsync extends false ? TMetaData : Promise; } @@ -60,9 +51,7 @@ export interface RegleRuleWithParamsDefinition< TMetadata extends RegleRuleMetadataDefinition = boolean, > extends RegleRuleCore, RegleInternalRuleDefs { - ( - ...params: RegleUniversalParams - ): RegleRuleDefinition; + (...params: RegleUniversalParams): RegleRuleDefinition; } export type RegleRuleMetadataExtended = { @@ -75,12 +64,7 @@ export type UnwrapRuleTree | undefine }; export type UnwrapRuleWithParams | undefined> = - T extends RegleRuleWithParamsDefinition< - infer TValue, - infer TParams, - infer TAsync, - infer TMetadata - > + T extends RegleRuleWithParamsDefinition ? RegleRuleDefinition : T; @@ -150,11 +134,10 @@ export type InferRegleRule< ? RegleRuleDefinition : RegleRuleWithParamsDefinition; -export type RegleRuleDefinitionProcessor< - TValue extends any = any, - TParams extends any[] = [], - TReturn = any, -> = (value: Maybe, ...params: TParams) => TReturn; +export type RegleRuleDefinitionProcessor = ( + value: Maybe, + ...params: TParams +) => TReturn; export type RegleRuleDefinitionWithMetadataProcessor< TValue extends any, @@ -167,14 +150,8 @@ export type RegleCollectionRuleDefinition< TCustomRules extends Partial = Partial, > = | (RegleRuleDecl, TCustomRules> & { - $each: MaybeGetter< - RegleFormPropertyType>, TCustomRules>, - ArrayElement - >; + $each: MaybeGetter>, TCustomRules>, ArrayElement>; }) | ({ - $each: MaybeGetter< - RegleFormPropertyType>, TCustomRules>, - ArrayElement - >; + $each: MaybeGetter>, TCustomRules>, ArrayElement>; } & FieldRegleBehaviourOptions); diff --git a/packages/core/src/types/rules/rule.errors.types.ts b/packages/core/src/types/rules/rule.errors.types.ts index c3368ea8..43e8252f 100644 --- a/packages/core/src/types/rules/rule.errors.types.ts +++ b/packages/core/src/types/rules/rule.errors.types.ts @@ -5,9 +5,7 @@ import type { DeepSafeFormState, SafeFieldProperty } from '../core'; import type { ExtendOnlyRealRecord, Maybe, Prettify } from '../utils'; export type RegleErrorTree | any[]>> = { - readonly [K in keyof UnwrapNestedRefs]: RegleValidationErrors< - UnwrapNestedRefs[K] - >; + readonly [K in keyof UnwrapNestedRefs]: RegleValidationErrors[K]>; }; export type RegleExternalErrorTree | any[]> = PartialDeep< @@ -42,10 +40,7 @@ export type $InternalRegleErrorTree = { /** * @internal */ -export type $InternalRegleErrors = - | $InternalRegleCollectionErrors - | string[] - | $InternalRegleErrorTree; +export type $InternalRegleErrors = $InternalRegleCollectionErrors | string[] | $InternalRegleErrorTree; // - Misc @@ -69,10 +64,7 @@ export type PartialFormState> = [unknown] ext } >; -export type RegleResult< - Data extends Record | any[] | unknown, - TRules extends ReglePartialRuleTree, -> = +export type RegleResult | any[] | unknown, TRules extends ReglePartialRuleTree> = | { result: false; data: NonNullable extends Date | File @@ -96,12 +88,4 @@ export type RegleResult< export type $InternalRegleResult = { result: boolean; data: any }; -export type DataType = - | string - | number - | Record - | File - | Array - | Date - | null - | undefined; +export type DataType = string | number | Record | File | Array | Date | null | undefined; diff --git a/packages/core/src/types/rules/rule.init.types.ts b/packages/core/src/types/rules/rule.init.types.ts index f6453607..7e7d9a5b 100644 --- a/packages/core/src/types/rules/rule.init.types.ts +++ b/packages/core/src/types/rules/rule.init.types.ts @@ -21,13 +21,8 @@ export interface RegleRuleInit< message: | string | string[] - | (( - value: Maybe, - metadata: RegleRuleMetadataConsumer - ) => string | string[]); - active?: - | boolean - | ((value: Maybe, metadata: RegleRuleMetadataConsumer) => boolean); + | ((value: Maybe, metadata: RegleRuleMetadataConsumer) => string | string[]); + active?: boolean | ((value: Maybe, metadata: RegleRuleMetadataConsumer) => boolean); } /** @@ -40,19 +35,11 @@ export interface RegleRuleCore< TAsync extends boolean = false, TMetadata extends RegleRuleMetadataDefinition = boolean, > { - validator: ( - value: Maybe, - ...args: TParams - ) => TAsync extends false ? TMetadata : Promise; + validator: (value: Maybe, ...args: TParams) => TAsync extends false ? TMetadata : Promise; message: | string - | (( - value: Maybe, - metadata: RegleRuleMetadataConsumer - ) => string | string[]); - active?: - | boolean - | ((value: Maybe, metadata: RegleRuleMetadataConsumer) => boolean); + | ((value: Maybe, metadata: RegleRuleMetadataConsumer) => string | string[]); + active?: boolean | ((value: Maybe, metadata: RegleRuleMetadataConsumer) => boolean); type?: string; } @@ -61,13 +48,8 @@ export interface RegleRuleCore< * createRule arguments options */ export interface $InternalRegleRuleInit { - validator: ( - value: any, - ...args: any[] - ) => RegleRuleMetadataDefinition | Promise; - message: - | string - | ((value: any, metadata: $InternalRegleRuleMetadataConsumer) => string | string[]); + validator: (value: any, ...args: any[]) => RegleRuleMetadataDefinition | Promise; + message: string | ((value: any, metadata: $InternalRegleRuleMetadataConsumer) => string | string[]); active?: boolean | ((value: any, metadata: $InternalRegleRuleMetadataConsumer) => boolean); type?: string; } diff --git a/packages/core/src/types/rules/rule.internal.types.ts b/packages/core/src/types/rules/rule.internal.types.ts index 716f7a43..f2a84c55 100644 --- a/packages/core/src/types/rules/rule.internal.types.ts +++ b/packages/core/src/types/rules/rule.internal.types.ts @@ -1,8 +1,5 @@ import type { Maybe } from '../utils'; -import type { - PossibleRegleRuleMetadataConsumer, - RegleRuleMetadataDefinition, -} from './rule.definition.type'; +import type { PossibleRegleRuleMetadataConsumer, RegleRuleMetadataDefinition } from './rule.definition.type'; import type { RegleUniversalParams } from './rule.params.types'; /** @@ -14,17 +11,12 @@ export interface RegleInternalRuleDefs< TAsync extends boolean = false, TMetadata extends RegleRuleMetadataDefinition = boolean, > { - _validator: ( - value: Maybe, - ...args: TParams - ) => TAsync extends false ? TMetadata : Promise; + _validator: (value: Maybe, ...args: TParams) => TAsync extends false ? TMetadata : Promise; _message: | string | string[] | ((value: Maybe, metadata: PossibleRegleRuleMetadataConsumer) => string | string[]); - _active?: - | boolean - | ((value: Maybe, metadata: PossibleRegleRuleMetadataConsumer) => boolean); + _active?: boolean | ((value: Maybe, metadata: PossibleRegleRuleMetadataConsumer) => boolean); _type?: string; _patched: boolean; _params?: RegleUniversalParams; diff --git a/packages/core/src/types/rules/rule.params.types.ts b/packages/core/src/types/rules/rule.params.types.ts index ccd50a82..2878a46a 100644 --- a/packages/core/src/types/rules/rule.params.types.ts +++ b/packages/core/src/types/rules/rule.params.types.ts @@ -22,9 +22,7 @@ export type RegleUniversalParams> = [T] ex : never >; -export type UnwrapRegleUniversalParams> = [T] extends [ - [], -] +export type UnwrapRegleUniversalParams> = [T] extends [[]] ? [] : Parameters< F extends (...args: infer Args) => any diff --git a/packages/core/src/types/rules/rule.status.types.ts b/packages/core/src/types/rules/rule.status.types.ts index 3ae5a336..f2796c60 100644 --- a/packages/core/src/types/rules/rule.status.types.ts +++ b/packages/core/src/types/rules/rule.status.types.ts @@ -54,12 +54,7 @@ export type RegleStatus< TShortcuts extends RegleShortcutDefinition = {}, > = RegleCommonStatus & { readonly $fields: { - readonly [TKey in keyof TState]: InferRegleStatusType< - NonNullable, - TState, - TKey, - TShortcuts - >; + readonly [TKey in keyof TState]: InferRegleStatusType, TState, TKey, TShortcuts>; } & { readonly [TKey in keyof TState as TRules[TKey] extends NonNullable ? TKey @@ -141,10 +136,7 @@ export type RegleFieldStatus< $extractDirtyFields: (filterNullishValues?: boolean) => Maybe; $validate: () => Promise>; readonly $rules: { - readonly [TRuleKey in keyof Omit< - TRules, - '$each' | keyof FieldRegleBehaviourOptions - >]: RegleRuleStatus< + readonly [TRuleKey in keyof Omit]: RegleRuleStatus< TState, TRules[TRuleKey] extends RegleRuleDefinition ? TParams : [], TRules[TRuleKey] extends RegleRuleDefinition @@ -249,10 +241,7 @@ export interface $InternalRegleRuleStatus { $metadata: any; _haveAsync: boolean; $validating: boolean; - $validator( - value: any, - ...args: any[] - ): RegleRuleMetadataDefinition | Promise; + $validator(value: any, ...args: any[]): RegleRuleMetadataDefinition | Promise; $validate(): Promise; $unwatch(): void; $watch(): void; @@ -269,18 +258,10 @@ export type RegleCollectionStatus< TShortcuts extends RegleShortcutDefinition = {}, > = Omit< RegleFieldStatus, - | '$errors' - | '$silentErrors' - | '$extractDirtyFields' - | '$externalErrors' - | '$rules' - | '$value' - | '$validate' + '$errors' | '$silentErrors' | '$extractDirtyFields' | '$externalErrors' | '$rules' | '$value' | '$validate' > & { $value: Maybe; - readonly $each: Array< - InferRegleStatusType, NonNullable, number, TShortcuts> - >; + readonly $each: Array, NonNullable, number, TShortcuts>>; readonly $field: RegleFieldStatus; readonly $errors: RegleCollectionErrors; readonly $silentErrors: RegleCollectionErrors; @@ -289,9 +270,7 @@ export type RegleCollectionStatus< } & ([TShortcuts['collections']] extends [never] ? {} : { - [K in keyof TShortcuts['collections']]: ReturnType< - NonNullable[K] - >; + [K in keyof TShortcuts['collections']]: ReturnType[K]>; }); /** diff --git a/packages/core/src/types/utils/groups.ts b/packages/core/src/types/utils/groups.ts index cee6ebbb..fbe880cc 100644 --- a/packages/core/src/types/utils/groups.ts +++ b/packages/core/src/types/utils/groups.ts @@ -4,10 +4,7 @@ import type { RegleValidationGroupEntry } from '../core'; export function mergeBooleanGroupProperties( entries: RegleValidationGroupEntry[], - property: Extract< - keyof RegleValidationGroupEntry, - '$invalid' | '$error' | '$pending' | '$dirty' | '$valid' - > + property: Extract ) { return entries.some((entry) => { return entry[property]; diff --git a/packages/core/src/types/utils/misc.types.ts b/packages/core/src/types/utils/misc.types.ts index 0ab7e19e..1bb19ed1 100644 --- a/packages/core/src/types/utils/misc.types.ts +++ b/packages/core/src/types/utils/misc.types.ts @@ -14,9 +14,7 @@ export type MaybeGetter = {}> = | T | ((value: Ref, index: number) => T & TAdd); -export type Unwrap>> = T extends Ref - ? UnwrapRef - : UnwrapNestedRefs; +export type Unwrap>> = T extends Ref ? UnwrapRef : UnwrapNestedRefs; export type ExtractFromGetter> = T extends (( value: Ref, @@ -26,11 +24,7 @@ export type ExtractFromGetter> = T extends : T; export type ExtendOnlyRealRecord = - NonNullable extends File | Date - ? false - : NonNullable extends Record - ? true - : false; + NonNullable extends File | Date ? false : NonNullable extends Record ? true : false; export type OmitByType, U> = { [K in keyof T as T[K] extends U ? never : K]: T[K]; @@ -46,9 +40,9 @@ export type ExcludeByType = { export type PrimitiveTypes = string | number | boolean | bigint | Date | File; -export type NonPresentKeys< - TSource extends Record, - Target extends Record, -> = Omit; +export type NonPresentKeys, Target extends Record> = Omit< + Target, + keyof TSource +>; export type NoInferLegacy = [A][A extends any ? 0 : never]; diff --git a/packages/core/src/types/utils/props.types.ts b/packages/core/src/types/utils/props.types.ts index 78280ff6..5bf1553e 100644 --- a/packages/core/src/types/utils/props.types.ts +++ b/packages/core/src/types/utils/props.types.ts @@ -15,13 +15,9 @@ export type InferRegleRoot Regle> = T extends useRegleFn ? UnwrapRuleTree & Partial> : {}; -export type InferRegleShortcuts> = - T extends useRegleFn ? U : {}; +export type InferRegleShortcuts> = T extends useRegleFn ? U : {}; -export type RegleEnforceRequiredRules = Omit< - DefaultValidators, - TRules -> & { +export type RegleEnforceRequiredRules = Omit & { [K in TRules as keyof TRules]-?: NonNullable; }; @@ -29,11 +25,7 @@ export type RegleEnforceCustomRequiredRules< T extends Partial | useRegleFn, TRules extends T extends useRegleFn ? keyof InferRegleRules : keyof T, > = Omit< - T extends useRegleFn - ? InferRegleRules - : T extends Partial - ? UnwrapRuleTree - : {}, + T extends useRegleFn ? InferRegleRules : T extends Partial ? UnwrapRuleTree : {}, TRules > & { [K in TRules]-?: T extends useRegleFn diff --git a/packages/core/src/utils/object.utils.ts b/packages/core/src/utils/object.utils.ts index a6fd8d94..389ebc68 100644 --- a/packages/core/src/utils/object.utils.ts +++ b/packages/core/src/utils/object.utils.ts @@ -49,11 +49,7 @@ function getRegExpFlags(regExp: any) { } } -export function unwrapGetter( - getter: MaybeGetter, - value: Ref, - index?: number -): T { +export function unwrapGetter(getter: MaybeGetter, value: Ref, index?: number): T { if (getter instanceof Function) { return getter(value, index ?? 0); } diff --git a/packages/core/src/utils/version-compare.ts b/packages/core/src/utils/version-compare.ts index f3b8d6f6..2ff7f22f 100644 --- a/packages/core/src/utils/version-compare.ts +++ b/packages/core/src/utils/version-compare.ts @@ -27,5 +27,4 @@ function versionCompare(current: Version, other: Version): VersionIs { return VersionIs.EqualTo; } -export const isVueSuperiorOrEqualTo3dotFive = - versionCompare(version, '3.5.0') === -1 ? false : true; +export const isVueSuperiorOrEqualTo3dotFive = versionCompare(version, '3.5.0') === -1 ? false : true; diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 3b74a11e..b77259c7 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -18,7 +18,8 @@ ], "scripts": { "prepack": "nuxt-module-build build", - "dev": "nuxi dev playground", + "dev": "echo 'no dev build'", + "dev:playground": "nuxi dev playground", "dev:build": "nuxi build playground", "typecheck": "nuxi typecheck playground", "build": "pnpm run dev:prepare && nuxt-module-build build",