@4riders/reform 3.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +266 -0
  3. package/dist/index.d.ts +2715 -0
  4. package/dist/index.es.js +1715 -0
  5. package/dist/index.es.js.map +1 -0
  6. package/package.json +70 -0
  7. package/src/index.ts +90 -0
  8. package/src/reform/ArrayHelper.ts +164 -0
  9. package/src/reform/Form.tsx +81 -0
  10. package/src/reform/FormManager.ts +494 -0
  11. package/src/reform/Reform.ts +15 -0
  12. package/src/reform/components/BaseCheckboxField.tsx +72 -0
  13. package/src/reform/components/BaseDateField.tsx +84 -0
  14. package/src/reform/components/BaseRadioField.tsx +72 -0
  15. package/src/reform/components/BaseSelectField.tsx +103 -0
  16. package/src/reform/components/BaseTextAreaField.tsx +87 -0
  17. package/src/reform/components/BaseTextField.tsx +135 -0
  18. package/src/reform/components/InputHTMLProps.tsx +89 -0
  19. package/src/reform/observers/observer.ts +131 -0
  20. package/src/reform/observers/observerPath.ts +327 -0
  21. package/src/reform/observers/useObservers.ts +232 -0
  22. package/src/reform/useForm.ts +246 -0
  23. package/src/reform/useFormContext.tsx +37 -0
  24. package/src/reform/useFormField.ts +75 -0
  25. package/src/reform/useRender.ts +12 -0
  26. package/src/yop/MessageProvider.ts +204 -0
  27. package/src/yop/Metadata.ts +304 -0
  28. package/src/yop/ObjectsUtil.ts +811 -0
  29. package/src/yop/TypesUtil.ts +148 -0
  30. package/src/yop/ValidationContext.ts +207 -0
  31. package/src/yop/Yop.ts +430 -0
  32. package/src/yop/constraints/CommonConstraints.ts +124 -0
  33. package/src/yop/constraints/Constraint.ts +135 -0
  34. package/src/yop/constraints/MinMaxConstraints.ts +53 -0
  35. package/src/yop/constraints/OneOfConstraint.ts +40 -0
  36. package/src/yop/constraints/TestConstraint.ts +176 -0
  37. package/src/yop/decorators/array.ts +157 -0
  38. package/src/yop/decorators/boolean.ts +69 -0
  39. package/src/yop/decorators/date.ts +73 -0
  40. package/src/yop/decorators/email.ts +66 -0
  41. package/src/yop/decorators/file.ts +69 -0
  42. package/src/yop/decorators/id.ts +35 -0
  43. package/src/yop/decorators/ignored.ts +40 -0
  44. package/src/yop/decorators/instance.ts +110 -0
  45. package/src/yop/decorators/number.ts +73 -0
  46. package/src/yop/decorators/string.ts +90 -0
  47. package/src/yop/decorators/test.ts +41 -0
  48. package/src/yop/decorators/time.ts +112 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","names":["Path","FormManager","InternalFormManager","ArrayHelper","array","T","constructor","form","path","getValue","Array","isArray","undefined","append","element","commit","push","touch","replace","index","touched","getTouchedValue","insert","splice","remove","swap","index1","index2","action","value1","move","from","to","fromElement","i","toElement","clear","length","setTouchedValue","value","validate","render","React","FormManager","Form","FormContext","createContext","useFormContext","useContext","T","Reform","displayFormErrors","logFormErrors","FormHTMLAttributes","useCallback","FormContext","React","renderToStaticMarkup","FormManager","InternalFormManager","ValidationStatus","Reform","FormProps","Omit","HTMLFormElement","form","disabled","Form","props","children","formAttrs","formRef","htmlForm","errors","Map","statuses","filter","_","status","level","e","submit","size","displayFormErrors","all","display","marginTop","padding","fontFamily","border","borderInline","color","background","whiteSpace","JSON","stringify","Object","fromEntries","entries","key","value","isValidElement","DOT","OPEN_BRACKET","SINGLE_QUOTE","DOUBLE_QUOTE","CLOSE_QUOTE","CLOSE_BRACKET","State","Path","identifier","isValidIdentifier","segment","test","splitPath","path","cache","Map","cached","get","slice","segments","state","undefined","escape","i","length","c","charAt","push","parseInt","size","clear","set","joinPath","Number","isNaN","replaceAll","SetResult","root","previousValue","value","T","keys","parent","key","newValue","options","clone","condition","currentValue","lastKeyIndex","lastKey","Array","isArray","array","Object","unset","Diff","a","A","b","B","tree","equal","differs","diff","paths","_diff","result","forEach","known","diffPaths","constructor","Date","getTime","RegExp","source","flags","File","name","type","lastModified","Set","values","has","ArrayBuffer","isView","byteLength","ArrayBufferView","byteOffset","Uint8Array","buffer","Math","max","entry","entries","add","ignoredPath","_equal","prototype","hasOwnProperty","call","cloned","copy","item","val","create","getPrototypeOf","descriptors","getOwnPropertyDescriptors","descriptor","defineProperties","defineLazyProperty","o","PropertyKey","_this","defineProperty","configurable","enumerable","writable","assign","target","U","skipUndefined","includes","excludes","ClassConstructor","args","NonNullable","Type","isSubclassOf","value","parent","T","prototype","Constructor","StringConstructor","BooleanConstructor","NumberConstructor","ArrayElementType","ArrayType","Array","ElementType","isBoolean","isNumber","isNaN","isString","isObject","isArray","isFunction","Function","isDate","Date","getTime","isFile","File","isRegExp","RegExp","isStringArray","every","isBooleanArray","isNumberArray","isDateArray","isPromise","Promise","isFunction","InternalValidationContext","Level","ValidationContext","JSX","ConstraintMessage","Element","ConstraintValue","ConstraintType","ConstraintFunction","context","Value","Parent","Constraint","Message","validateConstraint","name","constraints","Constraints","isConstraintType","value","validate","constraintValue","NonNullable","defaultConstraint","defaultMessage","setStatus","groups","constraint","_validateConstraint","Array","isArray","group","errorCode","message","undefined","level","maybeConstraint","maybeMessage","maybeLevel","_maybeGroup","Constraint","validateConstraint","InternalValidationContext","ValuedContext","MinMaxConstraints","min","NonNullable","Value","MinMax","Parent","max","isMinMaxType","value","validateMinMaxConstraints","context","constraints","isConstraintValue","validateMin","validateMax","ConstraintMessage","InternalValidationContext","Level","ValidationContext","MessageProvider","locale","getMessage","context","code","constraint","message","level","format","value","numberFormat","Intl","NumberFormat","dateFormat","DateTimeFormat","listFormat","ListFormat","Date","Array","isArray","map","item","String","MessageProps","raw","formatted","plural","LDMLPluralRule","MessageFunction","props","BasicMessageProvider","pluralRules","PluralRules","messages","Map","constructor","entries","type","messageFunction","get","kind","select","undefined","s","messageProvider_en_US","messageProvider_fr_FR","Constraint","validateConstraint","isBoolean","InternalValidationContext","Groups","CommonConstraints","ignored","Value","Parent","exists","defined","notnull","required","ContraintsValue","Contraints","ContraintsParent","Validator","Constraints","context","constraints","Traverser","propertyOrIndex","traverseNullish","InternalCommonConstraints","InternalConstraints","kind","validate","traverse","groups","validateCommonConstraints","value","constraint","undefined","validateTypeConstraint","checkType","expectedType","setStatus","InternalValidationContext","Level","ValidationContext","ValidationStatus","ConstraintFunction","ConstraintMessage","isFunction","isObject","joinPath","TestConstraintMessage","TestConstraintFunction","NonNullable","Value","Parent","AsyncTestConstraint","promise","context","Promise","pendingMessage","unavailableMessage","dependencies","revalidate","previous","current","status","TestConstraint","test","defaultGetDependencies","_context","defaultShouldRevalidate","level","some","v","i","validateTestConstraint","testConstraint","groups","_validateTestConstraint","Array","isArray","group","syncTest","undefined","_validateTestConstraintFunction","asyncTest","_validateAsyncTestConstraint","constraint","message","maybeConstraint","maybeMessage","maybeLevel","setStatus","settings","skipAsync","getDependencies","value","concat","path","asyncStatus","yop","asyncStatuses","get","previousDependencies","shouldRevalidate","statuses","set","then","createStatus","catch","error","String","resolve","CommonConstraints","InternalCommonConstraints","validateTypeConstraint","MinMaxConstraints","validateMinMaxConstraints","TestConstraint","validateTestConstraint","fieldValidationDecorator","getValidationDecoratorKind","Groups","InternalClassConstraints","defineLazyProperty","ArrayElementType","Constructor","isNumber","InternalValidationContext","validationSymbol","Yop","id","string","number","ArrayValue","ArrayConstraints","Value","Parent","of","_","context","ClassFieldDecoratorContext","traverseArray","constraints","propertyOrIndex","traverseNullish","value","Array","isArray","undefined","elementConstraints","Symbol","metadata","validateArray","min","length","max","valid","index","element","entries","elementContext","createChildContext","kind","key","validate","arrayKind","array","groups","Partial","_this","name","fields","prototype","resolveClass","CommonConstraints","InternalCommonConstraints","validateTypeConstraint","TestConstraint","validateTestConstraint","fieldValidationDecorator","Groups","InternalClassConstraints","validateClass","defineLazyProperty","ClassConstructor","isObject","InternalValidationContext","validationSymbol","Yop","id","InstanceValue","InstanceConstraints","Value","Parent","of","NoInfer","traverseInstance","context","constraints","key","traverseNullish","undefined","const","classConstraints","Symbol","metadata","traverse","validateInstance","x","instanceKind","instance","groups","prototype","_this","resolveClass","assign","clone","ClassConstructor","isBoolean","isObject","InternalValidationContext","validationSymbol","CommonConstraints","ContraintsParent","ContraintsValue","InternalCommonConstraints","InternalConstraints","Traverser","validateCommonConstraints","validateTypeConstraint","Validator","validateConstraint","TestConstraintFunction","validateTestConstraint","ArrayConstraints","arrayKind","InstanceConstraints","instanceKind","InternalClassConstraints","test","Class","fields","name","traverseClass","context","constraints","key","traverseNullish","value","undefined","x","validateClass","valid","parent","fieldName","fieldConstraints","Object","entries","validate","fieldContext","createChildContext","kind","_","constraint","initClassConstraints","decoratorMetadata","DecoratorMetadata","metadata","hasOwnProperty","bind","validation","traverse","ClassFieldDecorator","ClassFieldDecoratorContext","Parent","Value","getMetadataFromDecorator","decorator","placeholder","getMetadata","model","T","Symbol","getMetadataFields","getClassConstructor","of","decoratorSymbol","getValidationDecoratorKind","fieldDecorator","properties","field","reset","classConstraints","Groups","group","Constraints","mergeMetadata","props","groups","merger","params","values","concat","forEach","mergeDefaultMetadata","defaultProps","constraintName","keys","groupKey","groupName","fieldValidationDecorator","validator","isMinMaxType","ignored","defineProperty","ConstraintMessage","joinPath","Path","ValidationForm","ValidationSettings","Yop","Group","Level","ValidationStatus","level","path","value","kind","code","constraint","message","ValidationContext","Value","parent","Parent","parentContext","getRoot","T","rootContext","settings","form","store","Map","UndefinedParent","Object","freeze","create","InternalValidationContext","yop","statuses","constructor","props","key","userContext","Error","concat","ignored","ignore","groups","createChildContext","createStatus","messageProvider","getMessage","setStatus","status","set","ValuedContext","NonNullable","CommonConstraints","validateConstraint","MinMaxConstraints","validateMinMaxConstraints","MessageProvider","messageProvider_en_US","messageProvider_fr_FR","ClassFieldDecorator","getMetadataFromDecorator","joinPath","Path","splitPath","Constructor","isBoolean","Group","InternalValidationContext","ValidationStatus","FormManager","Symbol","metadata","for","validationSymbol","AsyncValidationStatus","status","dependencies","ResolvedConstraints","required","min","MinMax","max","UnsafeResolvedConstraints","fieldMetadata","ValidationForm","submitted","submitting","statuses","Map","errors","store","htmlForm","HTMLFormElement","getValue","path","T","isTouched","touch","untouch","isDirty","ignoredPath","ValidationSettings","groups","ignore","skipAsync","form","ConstraintsAtSettings","unsafeMetadata","Yop","defaultInstance","classIds","messageProviders","registerMessageProvider","locale","_store","_asyncStatuses","asyncStatuses","registerClass","id","constructor","set","resolveClass","silent","resolved","get","console","error","prototype","contextAt","decorator","value","settings","traverseNullish","constraints","undefined","segments","context","yop","kind","segment","traverse","createChildContext","key","const","constraintsAt","resolvedContraints","_","constraint","isMinMaxType","Value","init","getAsyncStatus","rawValidate","validate","Array","from","values","provider","Intl","getCanonicalLocales","e","getLocale","setLocale","has","messageProvider","InternalCommonConstraints","Constraint","fieldDecorator","Groups","ignored","Parent","groups","field","name","constraint","Object","entries","FormEvent","clone","equal","get","set","SetResult","unset","FormConfig","ValidationForm","ResolvedConstraints","UnsafeResolvedConstraints","ValidationSettings","Yop","ConstraintsAtSettings","joinPath","Path","ValidationStatus","ignored","ArrayHelper","Reform","ReformValidationSettings","method","ReformConstraintsAtSettings","SetValueOptionsObject","touch","validate","propagate","SetValueOptions","FormManager","render","setSubmitting","submitting","initialValues","T","initialValuesPending","values","setValue","path","value","options","touchedOnly","ignore","Map","validateAt","skipAsync","changed","statuses","updateAsyncStatus","scrollToFirstError","constraintsAt","unsafeMetadata","MinMax","submit","e","HTMLFormElement","array","addReformEventListener","listener","EventListener","removeReformEventListener","ReformSetValueEventType","ReformSetValueEvent","CustomEvent","form","previousValue","createReformSetValueEvent","detail","InternalFormManager","_config","validationSchema","yop","pathCache","_initialValues","undefined","_initialValuesPending","_values","_statuses","touched","_submitting","_submitted","eventTarget","EventTarget","htmlForm","constructor","addEventListener","removeEventListener","submitted","config","store","pending","commitInitialValues","initialValuesConverter","onRender","getValue","V","result","root","untouch","dispatchEvent","setTimeout","isDirty","ignoredPath","length","isTouched","condition","currentValue","getTouchedValue","setTouchedValue","errors","Array","from","filter","status","level","ignoreFn","_form","previousIgnore","schema","groups","validationGroups","isArray","validationPath","rawValidate","forEach","prefix","key","keys","startsWith","includes","charAt","delete","size","settings","getAsyncStatus","preventDefault","stopPropagation","pendings","asyncStatuses","Promise","all","map","constraint","message","canSubmit","submitGuard","onSubmit","logFormErrors","console","error","element","window","document","getElementById","elt","sort","elt1","elt2","compareDocumentPosition","Node","DOCUMENT_POSITION_FOLLOWING","shift","scrollIntoView","behavior","block","focus","preventScroll","helper","useObservers","InternalCommonConstraints","fieldDecorator","Path","ReformSetValueEvent","FormConfig","ObserverCallbackOptions","untouch","propagate","ObserverCallbackContext","path","observedValue","currentValue","T","setValue","value","options","event","ObserverCallback","context","ObserverMetadata","callback","Observers","Map","ObserversField","observers","observer","Value","Parent","field","metadata","set","delete","Path","SLASH","OPEN_BRACKET","SINGLE_QUOTE","DOUBLE_QUOTE","CLOSE_QUOTE","CLOSE_BRACKET","State","PathElement","kind","value","identifier","pushProperty","segment","segments","test","push","splitObserverPath","path","cache","Map","length","undefined","cached","get","slice","state","escape","i","charAt","startsWith","c","parseInt","size","clear","set","reRegExpChar","reHasRegExpChar","RegExp","source","escapeRegExp","s","replace","observerPathToRegexp","observerPath","currentPath","shift","parentPath","pop","unshift","map","regexPath","index","Number","isNaN","toFixed","join","useEffect","getClassConstructor","getMetadataFields","Path","splitPath","ClassConstructor","FormManager","ReformSetValueEvent","SetValueOptions","ObserverCallbackContext","ObserverCallbackOptions","ObserverMetadata","ObserversField","observer","observerPathToRegexp","splitObserverPath","ObserverData","T","path","collectObservers","model","observersMap","Map","metadata","Record","Object","entries","forEach","name","fieldMetadata","isArray","kind","push","Number","NaN","observers","observerPath","pathRegExp","observersData","get","set","concat","fieldModel","pop","SetValueCalled","value","createCallbackContext","event","setValueCalled","observedValue","detail","currentValue","setValue","options","setValueOptions","touch","propagate","untouch","form","callObservers","observerData","startPath","length","pathElement","callback","slice","Array","itemPath","isNaN","item","itemIndex","newStartPath","createReformEventListener","from","map","RegExp","values","eventPath","test","i","pathSegment","eventSegment","validate","render","EventListener","useObservers","reformEventListener","addReformEventListener","removeReformEventListener","useReducer","useRender","useMemo","instance","Path","isPromise","Group","FormManager","InternalFormManager","useRender","useObservers","FormConfig","initialValues","T","Promise","initialValuesConverter","values","validationSchema","_","context","ClassFieldDecoratorContext","validationPath","validationGroups","ignore","path","form","submitGuard","onSubmit","dispatchEvent","Model","args","NonNullable","useForm","config","deps","React","DependencyList","model","configOrModel","onSubmitOrDeps","undefined","render","Array","isArray","manager","newManager","of","required","initialValuesPending","then","value","setTimeout","onRender","commitInitialValues","useRef","isPromise","ValidationStatus","ResolvedConstraints","FormManager","useFormContext","useRender","FieldState","value","Value","touched","status","form","Root","render","constraints","MinMax","useFormField","name","unsafeMetadata","promiseRef","Promise","undefined","statuses","get","level","constraint","current","finally","updateAsyncStatus","getValue","isTouched","constraintsAt","React","InputHTMLAttributes","useRef","InputAttributes","ReformEvents","useFormField","BaseCheckboxFieldHTMLAttributes","Omit","BaseCheckboxFieldProps","render","BaseCheckboxField","props","onChange","inputProps","value","fieldValue","form","name","inputRef","HTMLInputElement","internalOnChange","event","ChangeEvent","currentTarget","checked","setValue","current","document","activeElement","defaultChecked","InputHTMLAttributes","useRef","useFormField","BaseTextFieldHTMLAttributes","ReformEvents","localDateToString","date","Date","isNaN","getTime","year","getFullYear","toString","padStart","month","getMonth","day","getDate","stringToLocalDate","value","timeIndex","indexOf","substring","BaseDateFieldProps","render","BaseDateField","props","onChange","onBlur","inputProps","fieldValue","form","name","inputRef","HTMLInputElement","getInputValue","event","React","SyntheticEvent","currentTarget","internalOnChange","ChangeEvent","validity","badInput","setValue","validateAt","changed","internalOnBlur","FocusEvent","valid","valueMissing","current","document","activeElement","defaultValue","React","InputHTMLAttributes","useRef","InputAttributes","ReformEvents","useFormField","BaseRadioFieldHTMLAttributes","Omit","BaseRadioFieldProps","V","modelValue","render","BaseRadioField","props","onChange","onBlur","inputProps","value","fieldValue","form","name","inputRef","HTMLInputElement","internalOnChange","event","ChangeEvent","currentTarget","checked","setValue","current","document","activeElement","defaultChecked","React","DOMAttributes","SelectHTMLAttributes","useRef","ReformEvents","useFormField","BaseSelectFieldHTMLAttributes","Omit","HTMLSelectElement","name","BaseSelectFieldProps","V","modelValues","toOptionValue","modelValue","toOptionContent","toModelValue","optionValue","render","BaseSelectField","props","Value","onChange","onBlur","selectProps","value","fieldValue","form","selectRef","internalOnChange","event","ChangeEvent","currentTarget","setValue","current","document","activeElement","defaultValue","map","React","DOMAttributes","TextareaHTMLAttributes","useRef","useFormField","ReformEvents","BaseTextAreaFieldHTMLAttributes","Omit","HTMLTextAreaElement","name","BaseTextAreaFieldProps","render","BaseTextAreaField","props","onChange","onBlur","textAreaProps","value","fieldValue","form","textAreaRef","internalOnChange","event","ChangeEvent","currentTarget","setValue","validateAt","internalOnBlur","FocusEvent","current","document","activeElement","defaultValue","React","InputHTMLAttributes","useRef","InputAttributes","ReformEvents","useFormField","InputSelection","start","end","direction","BaseTextFieldHTMLAttributes","Omit","BaseTextFieldProps","V","toModelValue","value","toTextValue","acceptInputValue","formatDisplayedValue","formatOnEdit","render","BaseTextField","props","Value","onChange","onBlur","inputProps","fieldValue","form","name","inputRef","HTMLInputElement","previousInputValue","previousInputSelection","getInputValue","event","SyntheticEvent","currentTarget","replace","internalOnSelect","FormEvent","target","current","selectionStart","selectionEnd","selectionDirection","undefined","length","formattedValue","internalOnInput","selection","setSelectionRange","internalOnChange","ChangeEvent","setValue","validateAt","changed","internalOnBlur","FocusEvent","document","activeElement","convertedValue","String","defaultValue","Constraint","validateConstraint","InternalValidationContext","ValuedContext","OneOfConstraint","oneOf","NonNullable","Value","NoInfer","Parent","validateOneOfConstraint","context","constraints","isConstraintValue","value","OneOfType","equals","value1","value2","array","includes","some","item","CommonConstraints","validateTypeConstraint","OneOfConstraint","validateOneOfConstraint","TestConstraint","validateTestConstraint","isBoolean","isBooleanArray","InternalValidationContext","fieldValidationDecorator","Groups","BooleanValue","BooleanConstraints","Value","Parent","validateBoolean","context","constraints","boolean","groups","CommonConstraints","validateTypeConstraint","MinMaxConstraints","validateMinMaxConstraints","OneOfConstraint","validateOneOfConstraint","TestConstraint","validateTestConstraint","isDate","isDateArray","InternalValidationContext","fieldValidationDecorator","Groups","DateValue","Date","DateConstraints","Value","Parent","validateDate","context","constraints","value","min","max","date1","date2","getTime","date","groups","CommonConstraints","validateTypeConstraint","Constraint","Message","validateConstraint","MinMaxConstraints","validateMinMaxConstraints","OneOfConstraint","validateOneOfConstraint","TestConstraint","validateTestConstraint","isNumber","isRegExp","isString","isStringArray","InternalValidationContext","ValuedContext","fieldValidationDecorator","Groups","StringValue","StringConstraints","Value","Parent","match","NonNullable","RegExp","validateString","context","constraints","defaultRegexp","defaultMatchMessage","type","value","min","length","max","re","test","string","groups","Message","InternalValidationContext","fieldValidationDecorator","Groups","StringConstraints","StringValue","validateString","isNumber","EmailConstraints","Omit","Value","Parent","formatError","emailRegex","validateEmail","context","constraints","email","groups","CommonConstraints","validateTypeConstraint","MinMaxConstraints","validateMinMaxConstraints","TestConstraint","validateTestConstraint","isFile","isNumber","InternalValidationContext","fieldValidationDecorator","Groups","FileValue","File","FileConstraints","Value","Parent","validateFile","context","constraints","value","min","size","max","file","groups","Constructor","Yop","ArrayConstraints","InstanceConstraints","id","Type","decorateClass","target","Class","_","ClassDecoratorContext","registerClass","CommonConstraints","validateTypeConstraint","MinMaxConstraints","validateMinMaxConstraints","OneOfConstraint","validateOneOfConstraint","TestConstraint","validateTestConstraint","isNumber","isNumberArray","InternalValidationContext","fieldValidationDecorator","Groups","NumberValue","NumberConstraints","Value","Parent","validateNumber","context","constraints","value","min","max","number","groups","TestConstraintFunction","initClassConstraints","Constructor","InstanceType","Class","Type","test","decorateClass","_","context","ClassDecoratorContext","classConstraints","metadata","InternalValidationContext","fieldValidationDecorator","Groups","StringValue","MinMaxConstraints","validateMinMaxConstraints","CommonConstraints","validateTypeConstraint","isFunction","isString","isStringArray","OneOfConstraint","validateOneOfConstraint","TestConstraint","validateTestConstraint","Message","TimeConstraints","Value","Parent","formatError","timeRegex","timeToMillis","time","matches","exec","undefined","MAX_MILLIS","validateTime","context","constraints","millis","value","message","setStatus","_","min","max","groups"],"sources":["../src/reform/ArrayHelper.ts","../src/reform/useFormContext.tsx","../src/reform/Reform.ts","../src/reform/Form.tsx","../src/yop/ObjectsUtil.ts","../src/yop/TypesUtil.ts","../src/yop/constraints/Constraint.ts","../src/yop/constraints/MinMaxConstraints.ts","../src/yop/MessageProvider.ts","../src/yop/constraints/CommonConstraints.ts","../src/yop/constraints/TestConstraint.ts","../src/yop/decorators/array.ts","../src/yop/decorators/instance.ts","../src/yop/Metadata.ts","../src/yop/ValidationContext.ts","../src/yop/Yop.ts","../src/yop/decorators/ignored.ts","../src/reform/FormManager.ts","../src/reform/observers/observer.ts","../src/reform/observers/observerPath.ts","../src/reform/observers/useObservers.ts","../src/reform/useRender.ts","../src/reform/useForm.ts","../src/reform/useFormField.ts","../src/reform/components/BaseCheckboxField.tsx","../src/reform/components/BaseDateField.tsx","../src/reform/components/BaseRadioField.tsx","../src/reform/components/BaseSelectField.tsx","../src/reform/components/BaseTextAreaField.tsx","../src/reform/components/BaseTextField.tsx","../src/yop/constraints/OneOfConstraint.ts","../src/yop/decorators/boolean.ts","../src/yop/decorators/date.ts","../src/yop/decorators/string.ts","../src/yop/decorators/email.ts","../src/yop/decorators/file.ts","../src/yop/decorators/id.ts","../src/yop/decorators/number.ts","../src/yop/decorators/test.ts","../src/yop/decorators/time.ts"],"sourcesContent":["import { Path } from \"../yop/ObjectsUtil\"\nimport { FormManager, InternalFormManager } from \"./FormManager\"\n\n/**\n * Utility class for manipulating array fields in a form model, with automatic touch, validation, and rendering. See {@link FormManager.array} for details.\n * @template T - The type of array elements.\n * @category Form Management\n */\nexport class ArrayHelper<T = any> {\n\n private array: T[] | undefined\n\n /**\n * Creates an ArrayHelper for a given form and path.\n * @param form - The form manager instance.\n * @param path - The path to the array field in the form.\n */\n constructor(readonly form: InternalFormManager<any>, readonly path: string | Path) {\n this.array = form.getValue<T[]>(path)\n if (!Array.isArray(this.array))\n this.array = undefined\n }\n\n /**\n * Tells if the field at the given path was an array.\n * @returns True if the field was an array, false otherwise.\n */\n isArray() {\n return this.array != null\n }\n\n /**\n * Appends an element to the array.\n * @param element - The element to append.\n * @param commit - Whether to validate and render after the operation (default: true).\n */\n append(element: T, commit = true) {\n this.array!.push(element)\n this.form.touch(this.path)\n this.commit(commit)\n }\n\n /**\n * Replaces the element at the given index.\n * @param index - The index to replace.\n * @param element - The new element.\n * @param commit - Whether to validate and render after the operation (default: true).\n */\n replace(index: number, element: T, commit = true) {\n this.array![index] = element\n const touched = this.form.getTouchedValue<any[]>(this.path)\n if (touched == null)\n this.form.touch(this.path)\n else if (Array.isArray(touched))\n touched[index] = undefined\n this.commit(commit)\n }\n\n /**\n * Inserts an element at the given index.\n * @param index - The index to insert at.\n * @param element - The element to insert.\n * @param commit - Whether to validate and render after the operation (default: true).\n */\n insert(index: number, element: T, commit = true) {\n this.array!.splice(index, 0, element)\n const touched = this.form.getTouchedValue<any[]>(this.path)\n if (touched == null)\n this.form.touch(this.path)\n else if (Array.isArray(touched))\n touched.splice(index, 0, undefined)\n this.commit(commit)\n }\n\n /**\n * Removes the element at the given index.\n * @param index - The index to remove.\n * @param commit - Whether to validate and render after the operation (default: true).\n */\n remove(index: number, commit = true) {\n this.array!.splice(index, 1)\n const touched = this.form.getTouchedValue<any[]>(this.path)\n if (touched == null)\n this.form.touch(this.path)\n else if (Array.isArray(touched))\n touched.splice(index, 1)\n this.commit(commit)\n }\n\n /**\n * Swaps two elements in the array.\n * @param index1 - The first index.\n * @param index2 - The second index.\n * @param commit - Whether to validate and render after the operation (default: true).\n */\n swap(index1: number, index2: number, commit = true) {\n const action = <T>(array: T[]) => {\n const value1 = array[index1]\n array[index1] = array[index2]\n array[index2] = value1\n }\n\n action(this.array!)\n const touched = this.form.getTouchedValue<any[]>(this.path)\n if (touched == null)\n this.form.touch(this.path)\n else if (Array.isArray(touched))\n action(touched)\n this.commit(commit)\n }\n\n /**\n * Moves an element from one index to another.\n * @param from - The source index.\n * @param to - The destination index.\n * @param commit - Whether to validate and render after the operation (default: true).\n */\n move(from: number, to: number, commit = true) {\n if (from !== to) {\n const action = from < to ?\n <T>(array: T[]) => {\n const fromElement = array[from]\n for (let i = from; i < to; i++)\n array[i] = array[i + 1]\n array[to] = fromElement\n } :\n <T>(array: T[]) => {\n const toElement = array[to]\n for (let i = to; i > from; i--)\n array[i + 1] = array[i]\n array[from] = toElement\n }\n \n action(this.array!)\n const touched = this.form.getTouchedValue<any[]>(this.path)\n if (touched == null)\n this.form.touch(this.path)\n else if (Array.isArray(touched))\n action(touched)\n this.commit(commit)\n }\n }\n\n /**\n * Removes all elements from the array.\n * @param commit - Whether to validate and render after the operation (default: true).\n */\n clear(commit = true) {\n this.array!.splice(0, this.array!.length)\n this.form.setTouchedValue(this.path, true)\n this.commit(commit)\n }\n\n /**\n * Validates and renders the form if value is true.\n * @param value - Whether to commit (validate and render).\n */\n private commit(value: boolean) {\n if (value) {\n this.form.validate()\n this.form.render()\n }\n }\n}\n","import React from \"react\"\nimport { FormManager } from \"./FormManager\"\nimport { Form } from \"./Form\"\n\n/**\n * React context for providing a FormManager instance to descendant components.\n * @ignore\n */\nexport const FormContext = React.createContext<FormManager<unknown> | null>(null)\n\n/**\n * React hook to access the current {@link FormManager} from context. This hook should be used within a component that is a descendant of a {@link Form} component,\n * which provides the FormManager via context. The generic type parameter `T` can be used to specify the type of the form values managed by the FormManager,\n * allowing for type-safe access to form values.\n * \n * Example usage:\n * ```tsx\n * function MyFormComponent() {\n * const form = useFormContext<MyFormValues>()\n * // use form to access values, statuses, etc.\n * }\n * \n * const form = useForm(MyFormModel, onSubmit)\n * return (\n * <Form form={form} autoComplete=\"off\" noValidate disabled={form.submitting}>\n * <MyFormComponent />\n * </Form>\n * )\n * ```\n * \n * @template T - The type of the form values managed by the FormManager.\n * @returns The {@link FormManager} instance from context.\n * @category Form Management\n */\nexport function useFormContext<T = unknown>() {\n return React.useContext(FormContext)! as FormManager<T>\n}\n","/**\n * Static configuration for form error display and logging.\n * @category Form Management\n */\nexport class Reform {\n /**\n * Whether to display form errors in the UI (debug only).\n */\n public static displayFormErrors = false\n \n /**\n * Whether to log form errors to the console (debug only).\n */\n public static logFormErrors = true\n}","import { FormHTMLAttributes, useCallback } from \"react\"\nimport { FormContext } from \"./useFormContext\"\nimport React from \"react\"\nimport { renderToStaticMarkup } from \"react-dom/server\"\nimport { FormManager, InternalFormManager } from \"./FormManager\"\nimport { ValidationStatus } from \"../yop/ValidationContext\"\nimport { Reform } from \"./Reform\"\n\n/**\n * Props for the Form component.\n * @property form - The form manager instance.\n * @property disabled - Whether the form is disabled.\n * @category Form Management\n */\nexport interface FormProps extends Omit<FormHTMLAttributes<HTMLFormElement>, \"onSubmit\"> {\n\n /** The form manager instance. */\n form: FormManager<unknown>\n /** Whether the form is disabled. */\n disabled?: boolean\n}\n\n/**\n * React component for rendering an HTML form with context, error display, and automatic form disabling. All children of\n * this component will have access to the form manager via context, and they will be enclosed in an HTML `fieldset` that is disabled according to the\n * `disabled` prop. If there are any validation errors, and if the debug option `displayFormErrors` is enabled (see {@link Reform.displayFormErrors}),\n * they will be displayed in a formatted block below the form.\n * \n * Example usage:\n * ```tsx\n * const form = useForm(MyFormModel, onSubmit)\n * return (\n * <Form form={form} autoComplete=\"off\" noValidate disabled={form.submitting}>\n * // form fields here, using form context\n * <button type=\"submit\">Submit</button>\n * </Form>\n * )\n * ```\n * \n * @param props - The Form props.\n * @returns The rendered Form component.\n * @category Form Management\n */\nexport function Form(props: FormProps) {\n const { form, children, disabled, ...formAttrs } = props\n \n const formRef = useCallback((htmlForm: HTMLFormElement) => {\n (form as InternalFormManager<any>).htmlForm = htmlForm\n }, [form])\n\n const errors = new Map<string, ValidationStatus>([...form.statuses].filter(([_, status]) => status.level === \"error\"))\n\n return (\n <FormContext.Provider value={ form }>\n <form ref={ formRef } onSubmit={ (e) => form.submit(e) } { ...formAttrs }>\n <fieldset disabled={ disabled }>{ children }</fieldset>\n \n { errors.size > 0 && Reform.displayFormErrors &&\n <div style={{\n all: \"initial\",\n display: \"block\",\n marginTop: \"1em\",\n padding: \"1em\",\n fontFamily: \"monospace\",\n border: \"2px solid firebrick\",\n borderInline: \"2px solid firebrick\",\n color: \"firebrick\",\n background: \"white\",\n whiteSpace: \"pre-wrap\"\n }}>\n { JSON.stringify(\n Object.fromEntries(errors.entries()),\n (key, value) => key === \"message\" && React.isValidElement(value) ? renderToStaticMarkup(value) : value,\n 4\n )}\n </div>\n }\n </form>\n </FormContext.Provider>\n )\n}\n","/**\n * State constants for path parsing.\n * @ignore\n */\nconst DOT = 1\nconst OPEN_BRACKET = 2\nconst SINGLE_QUOTE = 3\nconst DOUBLE_QUOTE = 4\nconst CLOSE_QUOTE = 5\nconst CLOSE_BRACKET = 6\n\n/**\n * Type for path parser state.\n * @ignore\n */\ntype State = typeof DOT | typeof OPEN_BRACKET | typeof SINGLE_QUOTE | typeof DOUBLE_QUOTE | typeof CLOSE_QUOTE | typeof CLOSE_BRACKET | undefined\n\n/**\n * Type for a parsed path, as an array of string or number segments. Numbers represent array indices, while strings represent object keys. This type\n * is used for efficient access to nested properties in objects or arrays.\n * @see {@link splitPath}\n * @category Utilities\n */\nexport type Path = (string | number)[]\n\nconst identifier = /^[$_\\p{ID_Start}][$\\p{ID_Continue}]*$/u\n/**\n * Checks if a string is a valid JavaScript identifier.\n * @param segment - The string segment to check.\n * @returns True if valid identifier, false otherwise.\n * @ignore\n */\nfunction isValidIdentifier(segment: string): boolean {\n return identifier.test(segment)\n}\n\n/**\n * Splits a string path into segments, handling dot/bracket/quote notation.\n * @param path - The path string to split.\n * @param cache - Optional cache for parsed paths.\n * @returns The parsed path as an array, or undefined if invalid.\n * @category Utilities\n */\nexport function splitPath(path: string, cache?: Map<string, Path>): Path | undefined {\n\n if (cache != null) {\n const cached = cache.get(path)\n if (cached != null)\n return cached.slice()\n }\n\n const segments = []\n\n let state: State = undefined,\n escape = false,\n segment = \"\"\n\n for (let i = 0; i < path.length; i++) {\n let c = path.charAt(i)\n\n switch (c) {\n\n case '\\\\':\n if (state !== SINGLE_QUOTE && state !== DOUBLE_QUOTE)\n return undefined\n if (escape)\n segment += '\\\\'\n escape = !escape\n continue\n\n case ' ': case '\\t': case '\\r': case '\\n':\n if (state === SINGLE_QUOTE || state === DOUBLE_QUOTE)\n segment += c\n else {\n while (++i < path.length && ((c = path.charAt(i)) === ' ' || c === '\\t' || c === '\\r' || c === '\\n'))\n ;\n if (state === OPEN_BRACKET && path.charAt(i) !== ']' && segment)\n return undefined\n --i\n }\n break\n\n case '.':\n if (state === SINGLE_QUOTE || state === DOUBLE_QUOTE)\n segment += c\n else if (state === CLOSE_BRACKET) {\n if (segment)\n return undefined\n state = DOT\n }\n else if (state === undefined || state === DOT) {\n if (!isValidIdentifier(segment))\n return undefined\n segments.push(segment)\n segment = \"\"\n state = DOT\n }\n else\n return undefined\n break\n\n case '[':\n if (state === SINGLE_QUOTE || state === DOUBLE_QUOTE)\n segment += c\n else if (state === DOT) {\n if (!isValidIdentifier(segment))\n return undefined\n segments.push(segment)\n segment = \"\"\n state = OPEN_BRACKET\n }\n else if (state === CLOSE_BRACKET) {\n if (segment)\n return undefined\n state = OPEN_BRACKET\n }\n else if (state === undefined) {\n if (segment) {\n if (!isValidIdentifier(segment))\n return undefined\n segments.push(segment)\n segment = \"\"\n }\n state = OPEN_BRACKET\n }\n else\n return undefined\n break\n\n case ']':\n if (state === SINGLE_QUOTE || state === DOUBLE_QUOTE)\n segment += c\n else if (state === OPEN_BRACKET) {\n if (!segment)\n return undefined\n segments.push(parseInt(segment, 10))\n segment = \"\"\n state = CLOSE_BRACKET\n }\n else if (state === CLOSE_QUOTE) {\n segments.push(segment)\n segment = \"\"\n state = CLOSE_BRACKET\n }\n else\n return undefined\n break\n\n case '\\'':\n if (escape || state === DOUBLE_QUOTE)\n segment += c\n else if (state === SINGLE_QUOTE)\n state = CLOSE_QUOTE\n else if (state === OPEN_BRACKET && !segment)\n state = SINGLE_QUOTE\n else\n return undefined\n break\n\n case '\"':\n if (escape || state === SINGLE_QUOTE)\n segment += c\n else if (state === DOUBLE_QUOTE)\n state = CLOSE_QUOTE\n else if (state === OPEN_BRACKET && !segment)\n state = DOUBLE_QUOTE\n else\n return undefined\n break\n\n default:\n if (state === CLOSE_QUOTE || (state === OPEN_BRACKET && (c < '0' || c > '9')))\n return undefined\n segment += c\n break\n }\n\n escape = false\n }\n\n switch (state) {\n case undefined:\n if (segment) {\n if (!isValidIdentifier(segment))\n return undefined\n segments.push(segment)\n }\n break\n case CLOSE_BRACKET:\n if (segment)\n return undefined\n break\n case DOT:\n if (!isValidIdentifier(segment))\n return undefined\n segments.push(segment)\n break\n default:\n return undefined\n }\n\n if (cache != null) {\n if (cache.size >= 500)\n cache.clear()\n cache.set(path, segments.slice())\n }\n\n return segments\n}\n\n/**\n * Joins path segments into a string, using dot/bracket notation as needed.\n * @param segments - The path segments to join.\n * @returns The joined path string.\n * @category Utilities\n */\nexport function joinPath(segments: Path): string {\n let path = \"\"\n for (let segment of segments) {\n if (typeof segment === \"number\")\n path += \"[\" + (Number.isNaN(segment) ? \"?\" : segment) + \"]\"\n else if (isValidIdentifier(segment))\n path += (path ? \".\" : \"\") + segment\n else\n path += \"['\" + segment.replaceAll(\"'\", \"\\\\'\") + \"']\"\n }\n return path\n}\n\n/**\n * Result type for set operation, including root and previous value.\n * @category Utilities\n */\nexport type SetResult = undefined | {\n root: unknown\n previousValue?: unknown\n}\n\n/**\n * Retrieves a value from an object or array using a string or parsed path.\n * @param value - The root object or array.\n * @param path - The path string or array.\n * @param cache - Optional cache for parsed paths.\n * @returns The value at the path, or undefined if not found.\n * @category Utilities\n */\nexport function get<T = any>(value: unknown, path: string | Path, cache?: Map<string, Path>): T | undefined {\n const keys = typeof path === \"string\" ? splitPath(path, cache) : path\n if (keys == null)\n return undefined\n let parent: any = value\n for (const key of keys) {\n if (parent == null)\n return undefined\n parent = parent[key]\n }\n return parent\n}\n\n/**\n * Sets a value in an object or array at a given path, optionally cloning and using a condition.\n * @param value - The root object or array.\n * @param path - The path string or array.\n * @param newValue - The value to set.\n * @param cache - Optional cache for parsed paths.\n * @param options - Optional settings for cloning and condition.\n * @returns The set result, including root and previous value.\n * @category Utilities\n */\nexport function set(value: unknown, path: string | Path, newValue: unknown, cache?: Map<string, Path>, options: {\n clone?: boolean\n condition?: (currentValue: unknown) => boolean\n} = { clone: false }): SetResult {\n\n const keys = typeof path === \"string\" ? splitPath(path, cache) : path\n if (keys == null)\n return undefined\n\n if (options.clone)\n newValue = clone(newValue)\n\n if (keys.length === 0)\n return { root: newValue }\n\n const lastKeyIndex = keys.length - 1\n const lastKey = keys[lastKeyIndex]\n\n const root = (\n typeof (keys[0] ?? lastKey) === \"number\" ?\n Array.isArray(value) ? value : [] :\n value != null && typeof value === \"object\" ? value : {}\n )\n\n let parent: any = root\n for (let i = 0; i < lastKeyIndex; i++) {\n const key = keys[i]\n const array = typeof (keys[i + 1] ?? lastKey) === \"number\"\n\n if (parent[key] == null)\n parent[key] = array ? [] : {}\n else if (array) {\n if (!Array.isArray(parent[key]))\n parent[key] = []\n }\n else if (!(parent[key] instanceof Object))\n parent[key] = {}\n parent = parent[key]\n }\n\n const previousValue = parent[lastKey]\n if (options.condition?.(previousValue) !== false)\n parent[lastKey] = newValue\n return { root, previousValue }\n}\n\n/**\n * Removes a value from an object or array at a given path.\n * @param value - The root object or array.\n * @param path - The path string or array.\n * @param cache - Optional cache for parsed paths.\n * @returns True if unset, false otherwise.\n * @category Utilities\n */\nexport function unset(value: unknown, path: string | Path, cache?: Map<string, Path>): boolean | undefined {\n if (value == null)\n return false\n\n const keys = typeof path === \"string\" ? splitPath(path, cache) : path\n if (keys == null || keys.length === 0)\n return undefined\n\n const lastKeyIndex = keys.length - 1\n const lastKey = keys[lastKeyIndex]\n let parent: any = value\n \n for (let i = 0; i < lastKeyIndex; i++) {\n parent = parent[keys[i]]\n if (parent == null)\n return false\n }\n\n if (!(lastKey in parent))\n return false\n\n try {\n delete parent[lastKey]\n }\n catch {\n return false\n }\n return true\n}\n\n/**\n * Type for a diff result between two values.\n * @template A - The first value type.\n * @template B - The second value type.\n * @category Utilities\n */\nexport type Diff<A = any, B = any> = {\n\n /**\n * The first value in the diff comparison.\n */\n a: A\n\n /**\n * The second value in the diff comparison.\n */\n b: B\n\n /**\n * The diff tree representing differences between the two values. The tree is a nested object where keys are path segments and values are\n * either further nested objects or empty objects indicating a difference at that path. If a path is not present in the tree, it means\n * the values are equal at that path. When `equal` is true, the tree is an empty object: `{}`.\n */\n tree: { [key: string | number]: any }\n\n /**\n * Indicates whether the two values are equal.\n */\n equal: boolean\n}\n\n/**\n * Checks if two values differ at a given path, using a diff tree.\n * @param diff - The diff result.\n * @param path - The path to check.\n * @returns True if values differ at the path, false otherwise.\n * @category Utilities\n */\nexport function differs(diff: Diff, path: Path): boolean {\n if (diff.equal)\n return false\n \n let { a, b, tree } = diff\n for (let key of path) {\n if (tree[key] == null) {\n a = get(a, path)\n b = get(b, path)\n return !equal(a, b) && (a != null || b != null)\n }\n tree = tree[key]\n }\n \n return true\n}\n\n/**\n * Computes the diff between two values, returning a diff tree and equality flag.\n * @template A - The first value type.\n * @template B - The second value type.\n * @param a - The first value.\n * @param b - The second value.\n * @returns The diff result.\n * @category Utilities\n */\nexport function diff<A = any, B = any>(a: A, b: B): Diff<A, B> {\n const paths: Path[] = []\n _diff(a, b, new Map(), [], paths)\n\n const result = {\n a,\n b,\n tree: {} as { [key: string | number]: any },\n equal: paths.length === 0\n }\n\n paths.forEach(path => {\n let tree = result.tree\n path.forEach(key => {\n if (tree[key] == null)\n tree[key] = {}\n tree = tree[key]\n })\n })\n\n return result\n}\n\n/**\n * Internal recursive diff function for comparing two values.\n * @param a - The first value.\n * @param b - The second value.\n * @param known - Map of known comparisons.\n * @param path - Current path.\n * @param diffPaths - Array of differing paths.\n * @ignore\n */\nfunction _diff(a: any, b: any, known: Map<any, any>, path: Path, diffPaths: Path[]): void {\n if (a === b)\n return\n\n if (a == null || b == null) {\n diffPaths.push(path)\n return\n }\n\n if ((typeof a == 'object') && (typeof b == 'object')) {\n if (a.constructor !== b.constructor) {\n diffPaths.push(path)\n return\n }\n\n if (a instanceof Date) {\n if (a.getTime() !== (b as Date).getTime())\n diffPaths.push(path)\n return\n }\n \n if (a instanceof RegExp) {\n if (a.source !== (b as RegExp).source || a.flags !== (b as RegExp).flags)\n diffPaths.push(path)\n return\n }\n\n if (a instanceof File) {\n if (a.name !== (b as File).name || a.size !== (b as File).size || a.type !== (b as File).type || a.lastModified !== (b as File).lastModified)\n diffPaths.push(path)\n return\n }\n\n if (a instanceof Set) {\n if (a.size !== (b as Set<any>).size) {\n diffPaths.push(path)\n return\n }\n for (const value of a.values()) {\n if (!(b as Set<any>).has(value)) {\n diffPaths.push(path)\n return\n }\n }\n return\n }\n\n if (a instanceof ArrayBuffer || ArrayBuffer.isView(a)) {\n if (ArrayBuffer.isView(a)) {\n if (a.byteLength !== (b as ArrayBufferView).byteLength || a.byteOffset !== (b as ArrayBufferView).byteOffset) {\n diffPaths.push(path)\n return\n }\n a = new Uint8Array(a.buffer, a.byteOffset, a.byteLength)\n b = new Uint8Array((b as ArrayBufferView).buffer, (b as ArrayBufferView).byteOffset, (b as ArrayBufferView).byteLength)\n }\n else {\n if (a.byteLength !== (b as ArrayBuffer).byteLength) {\n diffPaths.push(path)\n return\n }\n a = new Uint8Array(a)\n b = new Uint8Array(b)\n }\n for (let i = (a as Uint8Array).length; i-- !== 0; ) {\n if ((a as Uint8Array)[i] !== (b as Uint8Array)[i]) {\n diffPaths.push(path)\n return\n }\n }\n return\n }\n\n if (known.get(a) === b)\n return\n known.set(a, b).set(b, a)\n\n if (Array.isArray(a)) {\n const length = Math.max(a.length, (b as any[]).length)\n for (let i = 0; i < length; i++)\n _diff(a[i], (b as any[])[i], known, [...path, i], diffPaths)\n return\n }\n\n if (a instanceof Map) {\n const keys = new Set<any>()\n for (const entry of a.entries()) {\n const key = entry[0]\n keys.add(key)\n _diff(entry[1], (b as Map<any, any>).get(key), known, [...path, key], diffPaths)\n }\n for (const entry of (b as Map<any, any>).entries()) {\n const key = entry[0]\n if (!keys.has(key))\n _diff(a.get(key), entry[1], known, [...path, key], diffPaths)\n }\n return\n }\n\n const keys = new Set<any>()\n for (let key of Object.keys(a)) {\n keys.add(key)\n _diff(a[key], b[key], known, [...path, key], diffPaths)\n }\n for (let key of Object.keys(b)) {\n if (!keys.has(key))\n _diff(a[key], b[key], known, [...path, key], diffPaths)\n }\n return\n }\n\n if (!(a !== a && b !== b))\n diffPaths.push(path)\n}\n\n/**\n * Checks deep equality between two values, optionally ignoring a path.\n * @param a - The first value.\n * @param b - The second value.\n * @param ignoredPath - Optional path to ignore.\n * @returns True if equal, false otherwise.\n * @category Utilities\n */\nexport function equal(a: any, b: any, ignoredPath?: string | Path) {\n return _equal(a, b, new Map(), ignoredPath ? typeof ignoredPath === \"string\" ? splitPath(ignoredPath) : ignoredPath : undefined)\n}\n\n/**\n * Internal recursive equality function for comparing two values.\n * @param a - The first value.\n * @param b - The second value.\n * @param known - Map of known comparisons.\n * @param ignoredPath - Optional path to ignore.\n * @returns True if equal, false otherwise.\n * @ignore\n */\nfunction _equal(a: any, b: any, known: Map<any, any>, ignoredPath?: Path): boolean {\n if (a === b)\n return true\n\n if (a == null || b == null)\n return false\n\n if ((typeof a == 'object') && (typeof b == 'object')) {\n if (a.constructor !== b.constructor)\n return false\n\n if (a instanceof Date)\n return a.getTime() === (b as Date).getTime()\n\n if (a instanceof RegExp)\n return a.source === (b as RegExp).source && a.flags === (b as RegExp).flags\n \n if (a instanceof File)\n return a.name === (b as File).name && a.size === (b as File).size && a.type === (b as File).type && a.lastModified === (b as File).lastModified\n\n if (a instanceof Set) {\n if (a.size !== (b as Set<any>).size)\n return false\n for (const entry of a.entries()) {\n if (!(b as Set<any>).has(entry[0]))\n return false\n }\n return true\n }\n\n if (a instanceof ArrayBuffer || ArrayBuffer.isView(a)) {\n if (ArrayBuffer.isView(a)) {\n if (a.byteLength !== (b as ArrayBufferView).byteLength || a.byteOffset !== (b as ArrayBufferView).byteOffset)\n return false\n a = new Uint8Array(a.buffer, a.byteOffset, a.byteLength)\n b = new Uint8Array((b as ArrayBufferView).buffer, (b as ArrayBufferView).byteOffset, (b as ArrayBufferView).byteLength)\n }\n else {\n if (a.byteLength !== (b as ArrayBuffer).byteLength)\n return false\n a = new Uint8Array(a)\n b = new Uint8Array(b)\n }\n for (let i = (a as Uint8Array).length; i-- !== 0; ) {\n if ((a as Uint8Array)[i] !== (b as Uint8Array)[i])\n return false\n }\n return true\n }\n\n if (known.get(a) === b)\n return true\n known.set(a, b).set(b, a)\n\n if (Array.isArray(a)) {\n const length = a.length\n if (length !== (b as any[]).length)\n return false\n for (let i = length; i-- !== 0; ) {\n if (ignoredPath != null && i === ignoredPath[0]) {\n if (ignoredPath.length === 1)\n continue\n if (!_equal(a[i], (b as any[])[i], known, ignoredPath.slice(1)))\n return false\n }\n if (!_equal(a[i], (b as any[])[i], known))\n return false\n }\n return true\n }\n\n if (a instanceof Map) {\n if (a.size !== (b as Map<any, any>).size)\n return false\n for (const entry of a.entries()) {\n if (!(b as Map<any, any>).has(entry[0]))\n return false\n }\n for (const entry of a.entries()) {\n const key = entry[0]\n if (ignoredPath != null && key === ignoredPath[0]) {\n if (ignoredPath.length === 1)\n continue\n if (!_equal(entry[1], (b as Map<any, any>).get(key), known, ignoredPath.slice(1)))\n return false\n }\n if (!_equal(entry[1], (b as Map<any, any>).get(key), known))\n return false\n }\n return true\n }\n\n const keys = Object.keys(a)\n const length = keys.length\n if (length !== Object.keys(b).length)\n return false\n for (let i = length; i-- !== 0; ) {\n if (!Object.prototype.hasOwnProperty.call(b, keys[i]))\n return false\n }\n for (let i = length; i-- !== 0; ) {\n const key = keys[i]\n if (ignoredPath != null && key === ignoredPath[0]) {\n if (ignoredPath.length === 1)\n continue\n if (!_equal(a[key], b[key], known, ignoredPath.slice(1)))\n return false\n }\n if (!_equal(a[key], b[key], known))\n return false\n }\n\n return true\n }\n\n return a !== a && b !== b\n}\n\n/**\n * Deep clones a value, handling arrays, objects, dates, maps, sets, and files.\n * @template T - The value type.\n * @param value - The value to clone.\n * @param cloned - Optional map of already cloned values.\n * @returns The cloned value.\n * @category Utilities\n */\nexport function clone<T>(value: T, cloned?: Map<any, any>): T {\n if (value == null || typeof value !== 'object')\n return value\n\n if (cloned == null)\n cloned = new Map<any, any>()\n else {\n const copy = cloned.get(value)\n if (copy != null)\n return copy\n }\n\n if (Array.isArray(value)) {\n const copy = new Array()\n cloned.set(value, copy)\n value.forEach(item => copy.push(clone(item, cloned)))\n return copy as T\n }\n if (value instanceof Date) {\n const copy = new Date(value)\n cloned.set(value, copy)\n return copy as T\n }\n if (value instanceof RegExp) {\n const copy = new RegExp(value)\n cloned.set(value, copy)\n return copy as T\n }\n if (value instanceof Set) {\n const copy = new Set()\n cloned.set(value, copy)\n value.forEach(item => copy.add(clone(item, cloned)))\n return copy as T\n }\n if (value instanceof Map) {\n const copy = new Map()\n cloned.set(value, copy)\n value.forEach((val, key) => copy.set(clone(key, cloned), clone(val, cloned)))\n return copy as T\n }\n if (value instanceof File) {\n cloned.set(value, value)\n return value\n }\n\n const copy = Object.create(Object.getPrototypeOf(value))\n cloned.set(value, copy)\n const descriptors = Object.getOwnPropertyDescriptors(value)\n for (const descriptor of Object.values(descriptors)) {\n if (descriptor.get == null)\n descriptor.value = clone(descriptor.value, cloned)\n }\n Object.defineProperties(copy, descriptors)\n\n return copy as T\n}\n\n/**\n * Defines a lazily-evaluated property on an object.\n * @template T - The object type.\n * @param o - The object.\n * @param name - The property name.\n * @param get - The getter function.\n * @ignore\n */\nexport function defineLazyProperty<T>(o: T, name: PropertyKey, get: ((_this: T) => unknown)) {\n Object.defineProperty(o, name, { configurable: true, enumerable: true, get: function() {\n const value = get(this)\n Object.defineProperty(this, name, { value, configurable: true, enumerable: true, writable: true })\n return value\n }})\n}\n\n/**\n * Assigns properties from source to target, with options for skipping undefined, including, or excluding keys.\n * @template T - The target type.\n * @template U - The source type.\n * @param target - The target object.\n * @param source - The source object.\n * @param options - Optional settings for assignment.\n * @returns The merged object.\n * @category Utilities\n */\nexport function assign<T extends {}, U>(target: T, source: U, options?: { skipUndefined?: boolean, includes?: (keyof U)[], excludes?: (keyof U)[] }): T & U {\n const descriptors = Object.getOwnPropertyDescriptors(source)\n if (options && (options.skipUndefined || options.includes || options.excludes)) {\n for (const [name, descriptor] of Object.entries(descriptors)) {\n if (options.skipUndefined && descriptor.get == null && descriptor.value === undefined)\n delete descriptors[name]\n else if (options.includes && !options.includes.includes(name as keyof U))\n delete descriptors[name]\n else if (options.excludes?.includes(name as keyof U))\n delete descriptors[name]\n }\n }\n Object.defineProperties(target, descriptors)\n return target as T & U\n}\n\n\n","\n/**\n * Type for a class constructor of a given type.\n * @template Type - The type of the class instance.\n * @ignore\n */\nexport type ClassConstructor<Type> = new (...args: any) => NonNullable<Type>\n\n/**\n * Checks if a class constructor is a subclass of another.\n * @template T - The parent class type.\n * @param value - The class constructor to check.\n * @param parent - The parent class constructor.\n * @returns True if value is a subclass of parent.\n * @ignore\n */\nexport const isSubclassOf = <T>(value: ClassConstructor<any>, parent: ClassConstructor<T>): value is ClassConstructor<T> =>\n value.prototype instanceof parent\n\n/**\n * Type for a constructor of a given type, including primitive constructors.\n * @template Type - The type to construct.\n * @ignore\n */\nexport type Constructor<Type = unknown> =\n Type extends unknown ? ClassConstructor<Type> | StringConstructor | BooleanConstructor | NumberConstructor :\n [Type] extends [string | null | undefined] ? StringConstructor :\n [Type] extends [boolean | null | undefined] ? BooleanConstructor :\n [Type] extends [number | null | undefined] ? NumberConstructor :\n ClassConstructor<Type>\n\n/**\n * Type for extracting the element type from an array type.\n * @template ArrayType - The array type.\n * @ignore\n */\nexport type ArrayElementType<ArrayType> = ArrayType extends Array<infer ElementType> ? ElementType : never\n\n/**\n * Checks if a value is a boolean.\n * @template T - The boolean type.\n * @param value - The value to check.\n * @returns True if value is boolean.\n * @ignore\n */\nexport const isBoolean = <T extends boolean>(value: any): value is T => typeof value === \"boolean\"\n/**\n * Checks if a value is a valid number (not NaN).\n * @template T - The number type.\n * @param value - The value to check.\n * @returns True if value is a valid number.\n * @ignore\n */\nexport const isNumber = <T extends number>(value: any): value is T => typeof value === \"number\" && !isNaN(value)\n/**\n * Checks if a value is a string.\n * @template T - The string type.\n * @param value - The value to check.\n * @returns True if value is a string.\n * @ignore\n */\nexport const isString = <T extends string>(value: any): value is T => typeof value === \"string\"\n/**\n * Checks if a value is a non-null object (not an array).\n * @template T - The object type.\n * @param value - The value to check.\n * @returns True if value is an object.\n * @ignore\n */\nexport const isObject = <T extends object>(value: any): value is T => value != null && !Array.isArray(value) && typeof value === \"object\"\n/**\n * Checks if a value is a function.\n * @template T - The function type.\n * @param value - The value to check.\n * @returns True if value is a function.\n * @ignore\n */\nexport const isFunction = <T extends Function>(value: any): value is T => typeof value === \"function\"\n/**\n * Checks if a value is a valid Date object.\n * @template T - The Date type.\n * @param value - The value to check.\n * @returns True if value is a valid Date.\n * @ignore\n */\nexport const isDate = <T extends Date>(value: any): value is T => value instanceof Date && !isNaN(value.getTime())\n/**\n * Checks if a value is a File object.\n * @template T - The File type.\n * @param value - The value to check.\n * @returns True if value is a File.\n * @ignore\n */\nexport const isFile = <T extends File>(value: any): value is T => value instanceof File\n/**\n * Checks if a value is a RegExp object.\n * @param value - The value to check.\n * @returns True if value is a RegExp.\n * @ignore\n */\nexport const isRegExp = (value: any): value is RegExp => value instanceof RegExp\n\n/**\n * Checks if a value is an array of strings.\n * @template T - The string type.\n * @param value - The value to check.\n * @returns True if value is an array of strings.\n * @ignore\n */\nexport const isStringArray = <T extends string>(value: any): value is Array<T> => Array.isArray(value) && value.every(isString)\n/**\n * Checks if a value is an array of booleans.\n * @template T - The boolean type.\n * @param value - The value to check.\n * @returns True if value is an array of booleans.\n * @ignore\n */\nexport const isBooleanArray = <T extends boolean>(value: any): value is Array<T> => Array.isArray(value) && value.every(isBoolean)\n/**\n * Checks if a value is an array of numbers.\n * @template T - The number type.\n * @param value - The value to check.\n * @returns True if value is an array of numbers.\n * @ignore\n */\nexport const isNumberArray = <T extends number>(value: any): value is Array<T> => Array.isArray(value) && value.every(isNumber)\n/**\n * Checks if a value is an array of Date objects.\n * @template T - The Date type.\n * @param value - The value to check.\n * @returns True if value is an array of Dates.\n * @ignore\n */\nexport const isDateArray = <T extends Date>(value: any): value is Array<T> => Array.isArray(value) && value.every(isDate)\n\n/**\n * Checks if a value is a Promise.\n * @template T - The Promise type.\n * @param value - The value to check.\n * @returns True if value is a Promise.\n * @ignore\n */\nexport const isPromise = <T>(value: any): value is Promise<T> => (\n value != null &&\n typeof value === \"object\" &&\n \"then\" in value && typeof value[\"then\"] === \"function\" &&\n \"catch\" in value && typeof value[\"catch\"] === \"function\"\n)\n","import { isFunction } from \"../TypesUtil\"\nimport { InternalValidationContext, Level, ValidationContext } from \"../ValidationContext\"\nimport { JSX } from \"react\"\n\n/**\n * Type representing a constraint message, which can be a direct string or JSX element.\n * @category Shared Constraints\n */\nexport type ConstraintMessage = string | JSX.Element\n\n/**\n * Type representing a constraint value, which can be a direct value or a tuple containing the value, an optional message, and an optional level.\n * This allows for flexible constraint definitions that can include custom error messages and severity levels.\n * @template ConstraintType - The type of the constraint value.\n * @category Shared Constraints\n */\nexport type ConstraintValue<ConstraintType> = ConstraintType | readonly [ConstraintType, ConstraintMessage, Level?]\n\n/**\n * Type representing a constraint function that returns a constraint value.\n * @template Value - The type of the value being validated.\n * @template ConstraintType - The type of the constraint value.\n * @template Parent - The type of the parent object.\n * @category Shared Constraints\n */\nexport type ConstraintFunction<Value, ConstraintType, Parent = unknown> = ((context: ValidationContext<Value, Parent>) => ConstraintValue<ConstraintType> | undefined)\n\n/**\n * A constraint can be defined as a direct value, a tuple with value, message and level, or a function returning \n * either of those.\n * @category Shared Constraints\n */\nexport type Constraint<Value, ConstraintType, Parent = unknown> =\n ConstraintValue<ConstraintType> |\n ConstraintFunction<Value, ConstraintType, Parent>\n\n/**\n * A validation message can be defined as a direct string/JSX element or a function returning a message.\n * @category Shared Constraints\n */\nexport type Message<Value, Parent> = ConstraintMessage | ((context: ValidationContext<Value, Parent>) => ConstraintMessage)\n\n/**\n * Validates a constraint for a given context and constraint definition.\n * Handles group-based constraints and default values/messages.\n *\n * @template Value - The type of the value being validated.\n * @template ConstraintType - The type of the constraint value.\n * @template Parent - The type of the parent object.\n * @template Constraints - The type of the constraints object.\n * @param context - The validation context.\n * @param constraints - The constraints object.\n * @param name - The name of the constraint to validate.\n * @param isConstraintType - Type guard for the constraint value.\n * @param validate - Function to validate the value against the constraint.\n * @param defaultConstraint - Optional default constraint value.\n * @param defaultMessage - Optional default error message.\n * @param setStatus - Whether to set the status on failure (default: true).\n * @returns True if the constraint passes, false otherwise.\n * @ignore\n */\nexport function validateConstraint<Value, ConstraintType, Parent, Constraints = { [name: string]: Constraint<Value, ConstraintType, Parent> }>(\n context: InternalValidationContext<Value, Parent>,\n constraints: Constraints,\n name: keyof Constraints,\n isConstraintType: (value: any) => value is ConstraintType,\n validate: (value: Value, constraintValue: NonNullable<ConstraintType>) => boolean,\n defaultConstraint?: ConstraintType,\n defaultMessage?: Message<Value, Parent>,\n setStatus = true\n) {\n if (context.groups == null) {\n const constraint = constraints[name] as Constraint<Value, ConstraintType, Parent> | undefined\n return _validateConstraint(context, constraint, isConstraintType, validate, name as string, defaultConstraint, defaultMessage, setStatus)\n }\n \n const groups = Array.isArray(context.groups) ? context.groups : [context.groups]\n for (const group of groups) {\n const constraint = (group == null ? constraints[name] : (constraints as any).groups?.[group]?.[name]) as Constraint<Value, ConstraintType, Parent> | undefined\n if (!_validateConstraint(context, constraint, isConstraintType, validate, name as string, defaultConstraint, defaultMessage, setStatus))\n return false\n }\n return true\n}\n\n/**\n * Internal helper to validate a single constraint value, handling tuple and function forms.\n * @ignore\n */\nfunction _validateConstraint<Value, ConstraintType, Parent>(\n context: InternalValidationContext<Value, Parent>,\n constraint: Constraint<Value, ConstraintType, Parent> | undefined,\n isConstraintType: (value: any) => value is ConstraintType,\n validate: (value: Value, constraintValue: NonNullable<ConstraintType>) => boolean,\n errorCode: string,\n defaultConstraint?: ConstraintType,\n defaultMessage?: Message<Value, Parent>,\n setStatus = true\n) {\n if (constraint == null && defaultConstraint == null)\n return true\n\n let message: ConstraintMessage | undefined = undefined\n let level: Level = \"error\"\n\n if (isFunction(constraint))\n constraint = (constraint as ConstraintFunction<Value, ConstraintType>)(context)\n\n if (constraint != null && !isConstraintType(constraint)) {\n if (Array.isArray(constraint)) {\n const [maybeConstraint, maybeMessage, maybeLevel, _maybeGroup] = constraint\n if (maybeConstraint == null || isConstraintType(maybeConstraint)) {\n constraint = maybeConstraint\n message = maybeMessage\n level = (maybeLevel as unknown as Level) ?? \"error\"\n }\n else\n constraint = undefined\n }\n else\n constraint = undefined\n }\n \n if (constraint == null && defaultConstraint != null)\n constraint = defaultConstraint\n \n if (message == null && defaultMessage != null)\n message = isFunction(defaultMessage) ? defaultMessage(context) : defaultMessage\n\n return (\n constraint == null ||\n validate(context.value as Value, constraint as NonNullable<ConstraintType>) ||\n (setStatus === true && context.setStatus(errorCode, constraint, message, level) == null)\n )\n}\n","import { Constraint, validateConstraint } from \"./Constraint\"\nimport { InternalValidationContext, ValuedContext } from \"../ValidationContext\"\n\n/**\n * Interface for min and max constraints on a value.\n * @template Value - The type of the value being validated.\n * @template MinMax - The type for min/max values.\n * @template Parent - The type of the parent object.\n * @property min - Minimum constraint for the value, if any.\n * @property max - Maximum constraint for the value, if any.\n * @property isMinMaxType - Type guard for min/max values.\n * @category Shared Constraints\n */\nexport interface MinMaxConstraints<Value, MinMax, Parent = unknown> {\n /**\n * Minimum constraint for the value. The value must be greater than or equal to this constraint.\n */\n min?: Constraint<NonNullable<Value>, MinMax | null | undefined, Parent>\n /**\n * Maximum constraint for the value. The value must be less than or equal to this constraint.\n */\n max?: Constraint<NonNullable<Value>, MinMax | null | undefined, Parent>\n /**\n * Optional type guard function to determine if a value is a valid min/max constraint. This can be used to ensure\n * that the constraint values are of the expected type.\n */\n isMinMaxType?: (value: any) => value is MinMax\n}\n\n/**\n * Validates min and max constraints for a value.\n * @template Value - The type of the value being validated.\n * @template MinMax - The type for min/max values.\n * @template Parent - The type of the parent object.\n * @param context - The validation context.\n * @param constraints - The min/max constraints to validate.\n * @param isConstraintValue - Type guard for min/max values.\n * @param validateMin - Function to validate the min constraint.\n * @param validateMax - Function to validate the max constraint.\n * @returns True if both min and max constraints pass, false otherwise.\n * @ignore\n */\nexport function validateMinMaxConstraints<Value, MinMax, Parent>(\n context: InternalValidationContext<Value, Parent>,\n constraints: MinMaxConstraints<Value, MinMax, Parent>,\n isConstraintValue: (value: any) => value is MinMax,\n validateMin: (value: NonNullable<Value>, min: NonNullable<MinMax>) => boolean,\n validateMax: (value: NonNullable<Value>, max: NonNullable<MinMax>) => boolean) {\n return (\n validateConstraint(context as ValuedContext<Value, Parent>, constraints, \"min\", isConstraintValue, validateMin) &&\n validateConstraint(context as ValuedContext<Value, Parent>, constraints, \"max\", isConstraintValue, validateMax)\n )\n}\n","import { ConstraintMessage } from \"./constraints/Constraint\";\nimport { InternalValidationContext, Level, ValidationContext } from \"./ValidationContext\";\n\n/**\n * Interface for providing localized validation messages.\n * @category Localization\n */\nexport interface MessageProvider {\n /**\n * The locale identifier (e.g., 'en-US', 'fr-FR').\n */\n readonly locale: string\n\n /**\n * Returns a localized message for a given validation context and code.\n * @param context - The validation context.\n * @param code - The message code.\n * @param constraint - The constraint value.\n * @param message - An optional custom message.\n * @param level - The validation level (e.g., 'error', 'pending').\n * @returns The resolved message.\n */\n getMessage(context: InternalValidationContext<unknown>, code: string, constraint: any, message: ConstraintMessage | undefined, level: Level): ConstraintMessage\n}\n\n/**\n * Formats a value for display in a localized message, handling numbers, dates, and arrays.\n * @param value - The value to format.\n * @param numberFormat - The number formatter.\n * @param dateFormat - The date formatter.\n * @param listFormat - The list formatter.\n * @returns The formatted string.\n * @ignore\n */\nfunction format(value: any, numberFormat: Intl.NumberFormat, dateFormat: Intl.DateTimeFormat, listFormat: Intl.ListFormat): string {\n return (\n typeof value === \"number\" ? numberFormat.format(value) :\n value instanceof Date ? dateFormat.format(value) :\n Array.isArray(value) ? listFormat.format(value.map(item => format(item, numberFormat, dateFormat, listFormat))) :\n String(value)\n )\n}\n\n/**\n * Properties passed to a message function for formatting.\n * @category Localization\n */\nexport type MessageProps = {\n context: ValidationContext<unknown>\n code: string\n constraint: {\n raw: any\n formatted: string\n plural?: Intl.LDMLPluralRule\n }\n level: Level\n}\n\n/**\n * Function type for generating a message from message properties.\n * @see {@link MessageProps}\n * @category Localization\n */\nexport type MessageFunction = (props: MessageProps) => string\n\n/**\n * Basic implementation of MessageProvider for localized validation messages.\n * @category Localization\n */\nexport class BasicMessageProvider implements MessageProvider {\n\n private readonly numberFormat: Intl.NumberFormat\n private readonly dateFormat: Intl.DateTimeFormat\n private readonly listFormat: Intl.ListFormat\n private readonly pluralRules: Intl.PluralRules\n\n /**\n * Map of message codes to message functions.\n */\n readonly messages: Map<string, MessageFunction>\n\n /**\n * Creates a new BasicMessageProvider for a given locale and message entries.\n * @param locale - The locale identifier.\n * @param entries - Optional array of [code, message function] pairs.\n */\n constructor(readonly locale: string, entries?: (readonly [string, MessageFunction])[]) {\n this.numberFormat = new Intl.NumberFormat(this.locale)\n this.dateFormat = new Intl.DateTimeFormat(this.locale)\n this.listFormat = new Intl.ListFormat(this.locale, { type: \"disjunction\" })\n this.pluralRules = new Intl.PluralRules(this.locale)\n\n this.messages = new Map<string, MessageFunction>(entries)\n }\n\n /**\n * @inheritdoc\n */\n getMessage(context: InternalValidationContext<unknown>, code: string, constraint: any, message: ConstraintMessage | undefined, level: Level): ConstraintMessage {\n if (message != null)\n return message\n\n const messageFunction = this.messages.get(`${ context.kind }.${ code }`) ?? this.messages.get(code)\n if (messageFunction == null)\n return `Unexpected error: ${ context.kind }.${ code }`\n\n return messageFunction({\n context,\n code,\n constraint: {\n raw: constraint,\n formatted: format(constraint, this.numberFormat, this.dateFormat, this.listFormat),\n plural: typeof constraint === \"number\" ? this.pluralRules.select(constraint) : undefined\n },\n level\n })\n }\n}\n\n/**\n * Returns the plural suffix 's' if the plural rule is not 'one'.\n * @param plural - The plural rule.\n * @returns 's' if plural, otherwise an empty string.\n * @ignore\n */\nfunction s(plural?: Intl.LDMLPluralRule): string {\n return plural == null || plural === \"one\" ? \"\" : \"s\"\n}\n\n/**\n * English (US) message provider for validation messages.\n * @category Localization\n */\nexport const messageProvider_en_US = new BasicMessageProvider(\"en-US\", [\n [\"string.min\", ({ constraint }) => `Minimum ${ constraint.formatted } character${ s(constraint.plural) }`],\n [\"string.max\", ({ constraint }) => `Maximum ${ constraint.formatted } character${ s(constraint.plural) }`],\n [\"string.match\", () => \"Invalid format\"],\n\n [\"email.min\", ({ constraint }) => `Minimum ${ constraint.formatted } character${ s(constraint.plural) }`],\n [\"email.max\", ({ constraint }) => `Maximum ${ constraint.formatted } character${ s(constraint.plural) }`],\n [\"email.match\", () => \"Invalid email format\"],\n\n [\"time.min\", ({ constraint }) => `Must be after or equal to ${ constraint.formatted }`],\n [\"time.max\", ({ constraint }) => `Must be before or equal to ${ constraint.formatted }`],\n [\"time.match\", () => \"Invalid time format\"],\n\n [\"number.min\", ({ constraint }) => `Must be greater or equal to ${ constraint.formatted }`],\n [\"number.max\", ({ constraint }) => `Must be less or equal to ${ constraint.formatted }`],\n\n [\"date.min\", ({ constraint }) => `Date must be greater or equal to ${ constraint.formatted }`],\n [\"date.max\", ({ constraint }) => `Date must be less or equal to ${ constraint.formatted }`],\n\n [\"file.min\", ({ constraint }) => `File must have a size of at least ${ constraint.formatted } byte${ s(constraint.plural) }`],\n [\"file.max\", ({ constraint }) => `File must have a size of at most ${ constraint.formatted } byte${ s(constraint.plural) }`],\n\n [\"array.min\", ({ constraint }) => `At least ${ constraint.formatted } element${ s(constraint.plural) }`],\n [\"array.max\", ({ constraint }) => `At most ${ constraint.formatted } element${ s(constraint.plural) }`],\n\n [\"type\", ({ constraint }) => `Wrong value type (expected ${ constraint.raw })`],\n [\"test\", ({ level }) => level === \"pending\" ? \"Pending...\" : level === \"error\" ? \"Invalid value\" : \"\"],\n [\"oneOf\", ({ constraint }) => `Must be one of: ${ constraint.formatted }`],\n [\"exists\", () => \"Required field\"],\n [\"defined\", () => \"Required field\"],\n [\"notnull\", () => \"Required field\"],\n [\"required\", () => \"Required field\"]\n])\n\n/**\n * French (FR) message provider for validation messages.\n * @category Localization\n */\nexport const messageProvider_fr_FR = new BasicMessageProvider(\"fr-FR\", [\n [\"string.min\", ({ constraint }) => `Minimum ${ constraint.formatted } caractère${ s(constraint.plural) }`],\n [\"string.max\", ({ constraint }) => `Maximum ${ constraint.formatted } caractère${ s(constraint.plural) }`],\n [\"string.match\", () => \"Format incorrect\"],\n\n [\"email.min\", ({ constraint }) => `Minimum ${ constraint.formatted } caractère${ s(constraint.plural) }`],\n [\"email.max\", ({ constraint }) => `Maximum ${ constraint.formatted } caractère${ s(constraint.plural) }`],\n [\"email.match\", () => \"Format d'email incorrect\"],\n\n [\"time.min\", ({ constraint }) => `Doit être antérieur ou égal à ${ constraint.formatted }`],\n [\"time.max\", ({ constraint }) => `Doit être postérieur ou égal à ${ constraint.formatted }`],\n [\"time.match\", () => \"Format horaire incorrect\"],\n\n [\"number.min\", ({ constraint }) => `Doit être supérieur ou égal à ${ constraint.formatted }`],\n [\"number.max\", ({ constraint }) => `Doit être inférieur ou égal à ${ constraint.formatted }`],\n\n [\"date.min\", ({ constraint }) => `La date doit être postérieure ou égale au ${ constraint.formatted }`],\n [\"date.max\", ({ constraint }) => `La date doit être antérieure ou égale au ${ constraint.formatted }`],\n\n [\"file.min\", ({ constraint }) => `Le fichier doit avoir une taille d'au moins ${ constraint.formatted } octet${ s(constraint.plural) }`],\n [\"file.max\", ({ constraint }) => `Le fichier doit avoir une taille d'au plus ${ constraint.formatted } octet${ s(constraint.plural) }`],\n\n [\"array.min\", ({ constraint }) => `Au moins ${ constraint.formatted } élément${ s(constraint.plural) }`],\n [\"array.max\", ({ constraint }) => `Au plus ${ constraint.formatted } élément${ s(constraint.plural) }`],\n\n [\"type\", ({ constraint }) => `Valeur du mauvais type (${ constraint.raw } attendu)`],\n [\"test\", ({ level }) => level === \"pending\" ? \"En cours...\" : level === \"error\" ? \"Valeur incorrecte\" : \"\"],\n [\"oneOf\", ({ constraint }) => `Doit être parmi : ${ constraint.formatted }`],\n [\"exists\", () => \"Champ obligatoire\"],\n [\"defined\", () => \"Champ obligatoire\"],\n [\"notnull\", () => \"Champ obligatoire\"],\n [\"required\", () => \"Champ obligatoire\"]\n])\n","import { Constraint, validateConstraint } from \"./Constraint\"\nimport { isBoolean } from \"../TypesUtil\"\nimport { InternalValidationContext } from \"../ValidationContext\"\nimport { Groups } from \"../Metadata\"\n\n/**\n * Common validation constraints for a value, used in decorators and validation logic.\n * @template Value - The type of the value being validated.\n * @template Parent - The type of the parent object.\n * @category Shared Constraints\n */\nexport interface CommonConstraints<Value, Parent = unknown> {\n /**\n * If `true`, the validation of the decorated element is skipped.\n */\n ignored?: Constraint<Value | null | undefined, boolean, Parent>\n /**\n * If `true`, the property must be present in the parent object (ie: `\"prop\" in obj` is true).\n */\n exists?: Constraint<Value | null | undefined, boolean, Parent>\n /**\n * If `true`, the value must not be `undefined`.\n */\n defined?: Constraint<Value | null | undefined, boolean, Parent>\n /**\n * If `true`, the value must not be `null`.\n */\n notnull?: Constraint<Value | null | undefined, boolean, Parent>\n /**\n * If `true`, the value must not be `undefined` or `null`.\n */\n required?: Constraint<Value | null | undefined, boolean, Parent>\n}\n\n/**\n * Extracts the value type from a CommonConstraints type.\n * @ignore\n */\nexport type ContraintsValue<Contraints> = Contraints extends CommonConstraints<infer Value, infer _Parent> ? Value : never\n\n/**\n * Extracts the parent type from a CommonConstraints type.\n * @ignore\n */\nexport type ContraintsParent<Contraints> = Contraints extends CommonConstraints<infer _Value, infer Parent> ? Parent : never\n\n/**\n * Type for a validation function for a set of constraints.\n * @ignore\n */\nexport type Validator<Constraints, Value = ContraintsValue<Constraints>, Parent = ContraintsParent<Constraints>> =\n (context: InternalValidationContext<Value, Parent>, constraints: Constraints) => boolean\n\n/**\n * Type for a function that traverses nested constraints and values.\n * @ignore\n */\nexport type Traverser<Constraints, Value = ContraintsValue<Constraints>, Parent = ContraintsParent<Constraints>> =\n ((context: InternalValidationContext<Value, Parent>, constraints: Constraints, propertyOrIndex: string | number, traverseNullish?: boolean) =>\n readonly [InternalCommonConstraints | undefined, InternalValidationContext<unknown>])\n\n/**\n * Used internally.\n * @ignore\n */\nexport interface InternalConstraints {\n /**\n * The kind of the decorated value (eg: `string`, `number`, etc.)\n */\n kind: string\n \n /**\n * The method that validates the decorated value.\n */\n validate: Validator<this>\n \n /**\n * The method that returns the constraints and value of a nested field.\n */\n traverse?: Traverser<this>\n\n /**\n * Validation groups with specific constraints. If specified, the given constraints will only be validated if at least one\n * of the groups is active in the validation context.\n */\n groups?: Groups<this>\n}\n \n\n/**\n * Internal constraints that include both common and internal constraint logic.\n * @ignore\n */\nexport interface InternalCommonConstraints extends CommonConstraints<any, any>, InternalConstraints {\n}\n\n/**\n * Validates the common constraints (defined, notnull, required) for a value.\n * @template Value - The type of the value being validated.\n * @template Parent - The type of the parent object.\n * @param context - The validation context.\n * @param constraints - The constraints to validate.\n * @returns True if all constraints pass, false otherwise.\n * @ignore\n */\nexport function validateCommonConstraints<Value, Parent>(context: InternalValidationContext<Value, Parent>, constraints: CommonConstraints<Value, Parent>) {\n return (\n validateConstraint(context, constraints, \"defined\", isBoolean, (value, constraint) => constraint !== true || value !== undefined) &&\n validateConstraint(context, constraints, \"notnull\", isBoolean, (value, constraint) => constraint !== true || value !== null) &&\n validateConstraint(context, constraints, \"required\", isBoolean, (value, constraint) => constraint !== true || value != null)\n )\n}\n\n/**\n * Validates the type of a value using a provided type check function.\n * @param context - The validation context.\n * @param checkType - Function to check the value's type.\n * @param expectedType - The expected type as a string.\n * @returns True if the value matches the expected type, false otherwise.\n * @ignore\n */\nexport function validateTypeConstraint(context: InternalValidationContext<any>, checkType: (value: any) => boolean, expectedType: string) {\n return checkType(context.value) || context.setStatus(\"type\", expectedType) == null\n}\n","import { InternalValidationContext, Level, ValidationContext, ValidationStatus } from \"../ValidationContext\"\nimport { ConstraintFunction, ConstraintMessage } from \"./Constraint\"\nimport { isFunction, isObject } from \"../TypesUtil\"\nimport { joinPath } from \"../ObjectsUtil\"\n\n/**\n * Type for test constraint messages, which can be a simple message, a tuple of message and level, a boolean, or undefined.\n * @category Shared Constraints\n */\nexport type TestConstraintMessage = ConstraintMessage | readonly [ConstraintMessage, Level] | boolean | undefined\n\n/**\n * Type for a test constraint function, which can return a test constraint message or be undefined.\n * @template Value - The type of the value being validated.\n * @template Parent - The type of the parent object.\n * @category Shared Constraints\n */\nexport type TestConstraintFunction<Value, Parent = unknown> = ConstraintFunction<NonNullable<Value>, TestConstraintMessage, Parent>\n\n/**\n * Interface for an asynchronous test constraint.\n * @template Value - The type of the value being validated.\n * @template Parent - The type of the parent object.\n * @property promise - Function returning a promise for the constraint message.\n * @property pendingMessage - Message to show while pending.\n * @property unavailableMessage - Message to show if async service is unavailable.\n * @property dependencies - Function to get dependencies for revalidation.\n * @property revalidate - Function to determine if revalidation is needed.\n * @category Shared Constraints\n */\nexport interface AsyncTestConstraint<Value, Parent = unknown> {\n promise: (context: ValidationContext<NonNullable<Value>, Parent>) => Promise<TestConstraintMessage>\n pendingMessage?: ConstraintMessage\n unavailableMessage?: ConstraintMessage\n dependencies?: (context: InternalValidationContext<Value, Parent>) => any[],\n revalidate?: (context: InternalValidationContext<Value, Parent>, previous: any[], current: any[], status: ValidationStatus | undefined) => boolean\n}\n\n/**\n * Interface for a test constraint, which can be sync, async, or both.\n * @template Value - The type of the value being validated.\n * @template Parent - The type of the parent object.\n * @property test - The test constraint function or async constraint.\n * @category Shared Constraints\n */\nexport interface TestConstraint<Value, Parent = unknown> {\n test?: TestConstraintFunction<Value, Parent> | AsyncTestConstraint<Value, Parent> | readonly [TestConstraintFunction<Value, Parent>, AsyncTestConstraint<Value, Parent>]\n}\n\nconst defaultGetDependencies = (_context: InternalValidationContext<unknown>) => []\nconst defaultShouldRevalidate = (_context: InternalValidationContext<unknown>, previous: any[], current: any[], status: ValidationStatus | undefined) =>\n status?.level !== \"unavailable\" && current.some((v, i) => v !== previous[i])\n\n/**\n * Validates a test constraint for a value, handling sync and async cases.\n * @template Value - The type of the value being validated.\n * @template Parent - The type of the parent object.\n * @param context - The validation context.\n * @param testConstraint - The test constraint to validate.\n * @returns True if the constraint passes, false otherwise.\n * @ignore\n */\nexport function validateTestConstraint<Value, Parent>(\n context: InternalValidationContext<Value, Parent>,\n testConstraint: TestConstraint<Value, Parent>\n) {\n if (context.groups == null)\n return testConstraint.test == null || _validateTestConstraint(context, testConstraint)\n\n const groups = Array.isArray(context.groups) ? context.groups : [context.groups]\n for (const group of groups) {\n const test = (group == null ? testConstraint.test : (testConstraint as any).groups?.[group]?.test)\n if (test != null && !_validateTestConstraint(context, { test }))\n return false\n }\n return true\n}\n\n/**\n * Internal helper to validate a test constraint (sync and async).\n * @ignore\n */\nfunction _validateTestConstraint<Value, Parent>(\n context: InternalValidationContext<Value, Parent>,\n testConstraint: TestConstraint<Value, Parent>\n) {\n const test = testConstraint.test!\n\n const syncTest = (isFunction(test) ? test : Array.isArray(test) ? test[0] : undefined) as TestConstraintFunction<Value, Parent> | undefined\n if (syncTest != null && !_validateTestConstraintFunction(context as InternalValidationContext<NonNullable<Value>, Parent>, syncTest))\n return false\n\n const asyncTest = (isObject(test) ? test : Array.isArray(test) ? test[1] : undefined) as AsyncTestConstraint<Value, Parent> | undefined\n return asyncTest == null || _validateAsyncTestConstraint(context as InternalValidationContext<NonNullable<Value>, Parent>, asyncTest)\n}\n\n/**\n * Internal helper to validate a synchronous test constraint function.\n * @ignore\n */\nfunction _validateTestConstraintFunction<Value, Parent>(\n context: InternalValidationContext<NonNullable<Value>, Parent>,\n test: TestConstraintFunction<Value, Parent>\n) {\n let constraint: any = undefined\n let message: any = undefined\n let level: Level | undefined = undefined\n\n constraint = test(context)\n\n if (Array.isArray(constraint)) {\n const [maybeConstraint, maybeMessage, maybeLevel] = constraint\n constraint = maybeConstraint\n message = maybeMessage\n level = maybeLevel ?? undefined\n }\n\n if (constraint == null || constraint === true)\n return true\n return context.setStatus(\"test\", false, typeof constraint === \"string\" ? constraint : message, level ?? \"error\") == null\n}\n\n/**\n * Internal helper to validate an asynchronous test constraint.\n * @ignore\n */\nfunction _validateAsyncTestConstraint<Value, Parent>(\n context: InternalValidationContext<NonNullable<Value>, Parent>,\n test: AsyncTestConstraint<Value, Parent>\n) {\n if (context.settings?.skipAsync)\n return true\n\n const getDependencies = test.dependencies ?? defaultGetDependencies\n const dependencies = [context.value].concat(getDependencies(context))\n\n const path = joinPath(context.path)\n let asyncStatus = context.yop.asyncStatuses.get(path)\n if (asyncStatus != null) {\n const previousDependencies = asyncStatus.dependencies\n asyncStatus.dependencies = dependencies\n const shouldRevalidate = test.revalidate ?? defaultShouldRevalidate\n if (!shouldRevalidate(context, previousDependencies, dependencies, asyncStatus.status)) {\n if (asyncStatus.status != null) {\n context.statuses.set(path, asyncStatus.status)\n return false\n }\n return true\n }\n }\n\n asyncStatus = { dependencies }\n \n const promise = test.promise(context)\n .then(message => {\n if (message == null || message === true)\n asyncStatus.status = undefined\n else if (message === false)\n asyncStatus.status = context.createStatus(\"test\", false)\n else if (!Array.isArray(message))\n asyncStatus.status = context.createStatus(\"test\", false, message as ConstraintMessage)\n else {\n const [maybeMessage, maybeLevel] = message as readonly [ConstraintMessage, Level]\n asyncStatus.status = context.createStatus(\"test\", false, maybeMessage, maybeLevel ?? \"error\")\n }\n return asyncStatus.status\n })\n .catch(error => {\n asyncStatus.status = context.createStatus(\"test\", false, error != null ? String(error) : test.unavailableMessage, \"unavailable\")\n return Promise.resolve(asyncStatus.status)\n })\n\n asyncStatus.status = context.setStatus(\"test\", promise, test.pendingMessage, \"pending\")\n context.yop.asyncStatuses.set(path, asyncStatus)\n return false\n}","import { CommonConstraints, InternalCommonConstraints, validateTypeConstraint } from \"../constraints/CommonConstraints\"\nimport { MinMaxConstraints, validateMinMaxConstraints } from \"../constraints/MinMaxConstraints\"\nimport { TestConstraint, validateTestConstraint } from \"../constraints/TestConstraint\"\nimport { fieldValidationDecorator, getValidationDecoratorKind, Groups, InternalClassConstraints } from \"../Metadata\"\nimport { defineLazyProperty } from \"../ObjectsUtil\"\nimport { ArrayElementType, Constructor, isNumber } from \"../TypesUtil\"\nimport { InternalValidationContext } from \"../ValidationContext\"\nimport { validationSymbol, Yop } from \"../Yop\"\nimport { id } from \"./id\"\nimport { string } from \"./string\"\nimport { number } from \"./number\"\n\n/**\n * Type for an array value, which can be an array, null, or undefined.\n * @ignore\n */\nexport type ArrayValue = any[] | null | undefined\n\n/**\n * Interface for array field constraints, combining common, min/max, test, and element type constraints.\n * @template Value - The type of the array value.\n * @template Parent - The type of the parent object.\n * @see {@link id}\n * @see {@link CommonConstraints}\n * @see {@link MinMaxConstraints}\n * @see {@link TestConstraint}\n * @category Property Decorators\n */\nexport interface ArrayConstraints<Value extends ArrayValue, Parent> extends\n CommonConstraints<Value, Parent>,\n MinMaxConstraints<Value, number, Parent>,\n TestConstraint<Value, Parent> {\n /**\n * A class constructor, a function returning a constructor, a validation decorator, or a class id (see {@link id}) to\n * validate each array element against.\n * @see {@link array}\n */\n of: (\n Constructor<ArrayElementType<Value>> |\n (() => Constructor<ArrayElementType<Value>>) |\n ((_: any, context: ClassFieldDecoratorContext<Value, ArrayElementType<Value>>) => void) |\n string\n )\n}\n\n/**\n * Traverses an array field to retrieve element constraints and value at a given index or property.\n * @template Value - The type of the array value.\n * @template Parent - The type of the parent object.\n * @param context - The validation context for the array.\n * @param constraints - The array constraints.\n * @param propertyOrIndex - The property name or array index to traverse.\n * @param traverseNullish - If true, traverses only if value is not nullish; otherwise, returns undefined for nullish values.\n * @returns A tuple of the element constraints (if any) and the value at the given index/property.\n * @ignore\n */\nfunction traverseArray<Value extends ArrayValue, Parent>(\n context: InternalValidationContext<Value, Parent>,\n constraints: ArrayConstraints<Value, Parent>,\n propertyOrIndex: string | number,\n traverseNullish?: boolean\n): readonly [InternalCommonConstraints | undefined, any] {\n if (traverseNullish ? context.value != null && (!Array.isArray(context.value) || typeof propertyOrIndex !== \"number\") : context.value == null)\n return [undefined, undefined]\n const of = constraints.of as any\n const elementConstraints = of?.[Symbol.metadata]?.[validationSymbol]\n return [elementConstraints, context.value?.[propertyOrIndex as number]]\n}\n\n/**\n * Validates an array field against its constraints, including type, min/max length, and element validation.\n * @template Value - The type of the array value.\n * @template Parent - The type of the parent object.\n * @param context - The validation context for the array.\n * @param constraints - The array constraints to validate.\n * @returns True if all constraints pass, false otherwise.\n * @ignore\n */\nfunction validateArray<Value extends ArrayValue, Parent>(context: InternalValidationContext<Value, Parent>, constraints: ArrayConstraints<Value, Parent>) {\n if (!validateTypeConstraint(context, Array.isArray, \"array\") ||\n !validateMinMaxConstraints(context, constraints, isNumber, (value, min) => value.length >= min, (value, max) => value.length <= max) ||\n constraints.of == null)\n return false\n\n let valid = true\n \n const elementConstraints = (constraints.of as any)[Symbol.metadata]?.[validationSymbol] as InternalCommonConstraints | undefined\n if (elementConstraints != null) {\n for (const [index, element] of context.value!.entries()) {\n const elementContext = context.createChildContext({\n kind: elementConstraints.kind,\n value: element,\n key: index,\n })\n valid = elementConstraints.validate(elementContext, elementConstraints) && valid\n } \n }\n \n return valid && validateTestConstraint(context, constraints)\n}\n\n/**\n * Constant representing the kind of array validation decorator.\n * @ignore\n */\nexport const arrayKind = \"array\"\n\n/**\n * Decorator for validating a field value as an array of a specified element type. The `of` property can be set to a custom\n * class constructor, or a validation decorator such as {@link string}, {@link number}, etc. Using a validation decorator allows\n * applying constraints to each array element.\n * \n * Example usage:\n * ```tsx\n * class Person {\n * \n * // the array itself must not be null, but its elements may be null\n * @array({ of: Dog, required: true })\n * dogs: Dog[] | null = null\n * \n * // the array must not be null, and all its elements must also be non-null\n * @array({ of: instance({ of: Cat, required: true }), required: true })\n * cats: Cat[] | null = null\n * \n * // a non-empty array of strings with at least 5 characters each\n * @array({ of: string({ required: true, min: 5 }), required: true, min: 1 })\n * names: string[] | null = null\n * }\n * const form = useForm(Person, ...)\n * \n * // the array decorator can also be used as a function to allow standalone validation:\n * Yop.validate([], array({ of: Dog, min: 1 })) // error: \"At least 1 element\"\n * ```\n * \n * @template Value - The type of the array value.\n * @template Parent - The type of the parent object.\n * @param constraints - The array constraints to apply.\n * @param groups - Optional validation groups.\n * @returns A field decorator function with validation.\n * @category Property Decorators\n */\nexport function array<Value extends ArrayValue, Parent>(constraints?: ArrayConstraints<Value, Parent>, groups?: Groups<ArrayConstraints<Value, Parent>>) {\n if (getValidationDecoratorKind(constraints?.of) != null) {\n const of = constraints!.of as ((_: any, context: Partial<ClassFieldDecoratorContext<Value, ArrayElementType<Value>>>) => void)\n defineLazyProperty(constraints, \"of\", (_this) => {\n const metadata = { [validationSymbol]: {} as InternalClassConstraints }\n of(null, { metadata, name: \"of\" })\n return { [Symbol.metadata]: { [validationSymbol]: metadata[validationSymbol]!.fields!.of }}\n })\n }\n else if (typeof constraints?.of === \"string\" || (typeof constraints?.of === \"function\" && constraints.of.prototype == null)) {\n const of = constraints!.of\n defineLazyProperty(constraints, \"of\", (_this) => Yop.resolveClass(of))\n }\n return fieldValidationDecorator(arrayKind, constraints ?? ({} as ArrayConstraints<Value, Parent>), groups, validateArray, isNumber, traverseArray)\n}\n\n","import { CommonConstraints, InternalCommonConstraints, validateTypeConstraint } from \"../constraints/CommonConstraints\"\nimport { TestConstraint, validateTestConstraint } from \"../constraints/TestConstraint\"\nimport { fieldValidationDecorator, Groups, InternalClassConstraints, validateClass } from \"../Metadata\"\nimport { defineLazyProperty } from \"../ObjectsUtil\"\nimport { ClassConstructor, isObject } from \"../TypesUtil\"\nimport { InternalValidationContext } from \"../ValidationContext\"\nimport { validationSymbol, Yop } from \"../Yop\"\nimport { id } from \"./id\"\n\n/**\n * Type for values that can be validated as instances (objects, null, or undefined).\n * @ignore\n */\nexport type InstanceValue = object | null | undefined\n\n\n/**\n * Constraints for validating an instance of a class. Inherits common and test constraints.\n * @template Value - The type of the instance value.\n * @template Parent - The type of the parent object.\n * @property of - A class constructor, a function returning a constructor, or a class id to validate the instance against.\n * @see {@link id}\n * @see {@link CommonConstraints}\n * @see {@link TestConstraint}\n * @category Property Decorators\n */\nexport interface InstanceConstraints<Value extends InstanceValue, Parent> extends\n CommonConstraints<Value, Parent>,\n TestConstraint<Value, Parent> {\n /**\n * A class constructor, a function returning a constructor, or a class id (see {@link id}) to validate the instance against.\n */\n of: ClassConstructor<NoInfer<Value>> | (() => ClassConstructor<NoInfer<Value>>) | string\n}\n\n/**\n * Traverses the constraints of a class instance for validation.\n * @param context - The validation context.\n * @param constraints - The instance constraints.\n * @param key - The property key to traverse.\n * @param traverseNullish - Whether to traverse nullish values.\n * @returns A tuple of the internal constraints and the value.\n * @ignore\n */\nfunction traverseInstance<Value extends InstanceValue, Parent>(\n context: InternalValidationContext<Value, Parent>,\n constraints: InstanceConstraints<Value, Parent>,\n key: string | number,\n traverseNullish?: boolean\n): readonly [InternalCommonConstraints | undefined, any] {\n if (constraints.of == null)\n return [undefined, undefined] as const\n const classConstraints = (constraints.of as any)[Symbol.metadata]?.[validationSymbol] as InternalClassConstraints | undefined\n if (classConstraints == null)\n return [undefined, undefined] as const\n return classConstraints.traverse!(context as InternalValidationContext<never, never>, classConstraints, key, traverseNullish)\n}\n\n/**\n * Validates that a value is an instance of the specified class and meets all constraints.\n * @param context - The validation context.\n * @param constraints - The instance constraints.\n * @returns True if valid, false otherwise.\n * @ignore\n */\nfunction validateInstance<Value extends InstanceValue, Parent>(context: InternalValidationContext<Value, Parent>, constraints: InstanceConstraints<Value, Parent>) {\n if (!validateTypeConstraint(context, isObject, \"object\") ||\n !validateTestConstraint(context, constraints) ||\n constraints.of == null)\n return false\n\n const classConstraints = (constraints.of as any)[Symbol.metadata]?.[validationSymbol] as InternalClassConstraints | undefined\n return classConstraints == null || validateClass(context as InternalValidationContext<{ [x: string]: any }>, classConstraints)\n}\n\n/**\n * The kind string used to identify instance constraints.\n * @ignore\n */\nexport const instanceKind = \"instance\"\n\n/**\n * Decorator for validating a field value as an instance of a specified class. The `of` property must be set to a custom\n * class constructor, not a built-in object type like String or Date.\n * \n * Example usage:\n * ```tsx\n * class Person {\n * @instance({ of: Dog, required: true })\n * dog: Dog | null = null\n * }\n * const form = useForm(Person, ...)\n * \n * // the instance decorator can also be used as a function to allow standalone validation:\n * Yop.validate(new Person(), instance({ of: Person })) // error: dog is a \"Required field\"\n * ```\n * @template Value - The type of the instance value.\n * @template Parent - The type of the parent object.\n * @param constraints - The instance constraints.\n * @param groups - Optional validation groups.\n * @returns A field decorator that stores the instance constraints and validation function in the class metadata.\n * @category Property Decorators\n */\nexport function instance<Value extends InstanceValue, Parent>(constraints?: InstanceConstraints<Value, Parent>, groups?: Groups<InstanceConstraints<Value, Parent>>) {\n if (typeof constraints?.of === \"string\" || (typeof constraints?.of === \"function\" && constraints.of.prototype == null)) {\n const of = constraints.of\n defineLazyProperty(constraints, \"of\", (_this) => Yop.resolveClass(of))\n }\n return fieldValidationDecorator(instanceKind, constraints ?? ({} as InstanceConstraints<Value, Parent>), groups, validateInstance, undefined, traverseInstance)\n}\n","import { assign, clone } from \"./ObjectsUtil\"\nimport { ClassConstructor, isBoolean, isObject } from \"./TypesUtil\"\nimport { InternalValidationContext } from \"./ValidationContext\"\nimport { validationSymbol } from \"./Yop\"\nimport { CommonConstraints, ContraintsParent, ContraintsValue, InternalCommonConstraints, InternalConstraints, Traverser, validateCommonConstraints, validateTypeConstraint, Validator } from \"./constraints/CommonConstraints\"\nimport { validateConstraint } from \"./constraints/Constraint\"\nimport { TestConstraintFunction, validateTestConstraint } from \"./constraints/TestConstraint\"\nimport { ArrayConstraints, arrayKind } from \"./decorators/array\"\nimport { InstanceConstraints, instanceKind } from \"./decorators/instance\"\n\n/**\n * Internal constraints for a class, including test and field constraints.\n * @template Class - The type of the class.\n * @ignore\n */\nexport interface InternalClassConstraints<Class = any> extends InternalConstraints {\n /**\n * Optional test constraint function for the class.\n */\n test?: TestConstraintFunction<Class>\n /**\n * Optional map of field names to their internal constraints.\n */\n fields?: { [name: string]: InternalCommonConstraints }\n}\n\n/**\n * Traverses a class field to retrieve its constraints and value.\n * @param context - The validation context for the class.\n * @param constraints - The class constraints.\n * @param key - The field name or index to traverse.\n * @param traverseNullish - If true, traverses only if value is not nullish; otherwise, returns undefined for nullish values.\n * @returns A tuple of the field constraints (if any) and the value at the given key.\n * @ignore\n */\nexport function traverseClass(\n context: InternalValidationContext<unknown>,\n constraints: InternalClassConstraints,\n key: string | number,\n traverseNullish?: boolean\n): readonly [InternalCommonConstraints | undefined, any] {\n if (traverseNullish ? context.value != null && (typeof context.value !== \"object\" || typeof key !== \"string\") : context.value == null)\n return [undefined, undefined]\n return [constraints.fields?.[key], (context.value as { [x: string]: any })?.[key]]\n}\n\n/**\n * Validates a class object against its constraints, including all fields and test constraints.\n * @param context - The validation context for the class object.\n * @param constraints - The class constraints to validate.\n * @returns True if all constraints pass, false otherwise.\n * @ignore\n */\nexport function validateClass(context: InternalValidationContext<{ [x: string]: any }>, constraints: InternalClassConstraints) {\n if (context.value == null || !validateTypeConstraint(context, isObject, \"object\"))\n return false\n \n let valid = true\n\n const parent = context.value\n for (const [fieldName, fieldConstraints] of Object.entries(constraints.fields!)) {\n if (fieldConstraints.validate == null)\n continue\n \n const fieldContext = context.createChildContext({\n kind: fieldConstraints.kind,\n value: parent[fieldName],\n key: fieldName,\n })\n \n valid = (\n validateConstraint(fieldContext, fieldConstraints, \"exists\", isBoolean, (_, constraint) => constraint !== true || fieldName in parent) &&\n fieldConstraints.validate(fieldContext, fieldConstraints) &&\n valid\n )\n }\n\n return valid && validateTestConstraint(context, constraints)\n}\n\n/**\n * Initializes and returns the internal class constraints for a given decorator metadata object.\n * @param decoratorMetadata - The metadata object from a class decorator.\n * @returns The initialized internal class constraints.\n * @ignore\n */\nexport function initClassConstraints(decoratorMetadata: DecoratorMetadata) {\n const metadata = decoratorMetadata as unknown as { [validationSymbol]: InternalClassConstraints } \n if (!Object.hasOwnProperty.bind(metadata)(validationSymbol))\n metadata[validationSymbol] = clone(metadata[validationSymbol] ?? {})\n \n const validation = metadata[validationSymbol]\n validation.validate ??= validateClass\n validation.traverse ??= traverseClass\n validation.kind ??= \"class\"\n return validation\n}\n\n/**\n * Type for a class field decorator function.\n * @template Value - The type of the field value.\n * @template Parent - The type of the parent object.\n * @ignore\n */\nexport type ClassFieldDecorator<Value, Parent = unknown> = (_: unknown, context: ClassFieldDecoratorContext<Parent, Value>) => void\n\n/**\n * Retrieves field metadata from a class field decorator.\n * @template Value - The type of the field value.\n * @template Parent - The type of the parent object.\n * @param decorator - The class field decorator function.\n * @returns The field constraints metadata for a placeholder field.\n * @ignore\n */\nexport function getMetadataFromDecorator<Value, Parent>(decorator: ClassFieldDecorator<Value, Parent>) {\n const metadata = { [validationSymbol]: {} as InternalClassConstraints }\n decorator(null, { metadata, name: \"placeholder\" } as any) \n return metadata[validationSymbol]?.fields?.placeholder\n}\n\n/**\n * Retrieves the validation metadata for a given class constructor.\n * @template T - The type of the class instance.\n * @param model - The class constructor.\n * @returns The common constraints metadata, if any.\n * @ignore\n */\nexport function getMetadata<T>(model: ClassConstructor<T>) {\n return model?.[Symbol.metadata]?.[validationSymbol] as CommonConstraints<any, T> | undefined\n}\n\n/**\n * Retrieves the field constraints metadata for all fields of a class constructor.\n * @template T - The type of the class instance.\n * @param model - The class constructor.\n * @returns An object mapping field names to their constraints, if any.\n * @ignore\n */\nexport function getMetadataFields<T>(model: ClassConstructor<T>) {\n const metadata = model?.[Symbol.metadata]?.[validationSymbol] as InternalClassConstraints | undefined\n return metadata?.fields as { [K in keyof T]: CommonConstraints<any, T> } | undefined\n}\n\n/**\n * Retrieves the class constructor from validation metadata, handling array and instance kinds.\n * @template T - The type of the class instance.\n * @param metadata - The validation metadata object.\n * @returns The class constructor, if found.\n * @ignore\n */\nexport function getClassConstructor<T>(metadata: any): ClassConstructor<T> | undefined {\n if (metadata?.kind === arrayKind) {\n const of = (metadata as unknown as ArrayConstraints<any, any>).of\n if (typeof of === \"function\")\n return of as ClassConstructor<T>\n metadata = (of as any)?.[Symbol.metadata]?.[validationSymbol] as unknown as InternalConstraints\n }\n return (\n metadata?.kind === instanceKind ?\n (metadata as unknown as InstanceConstraints<any, any>).of as ClassConstructor<T> :\n undefined\n )\n}\n\n/**\n * Symbol used to tag validation decorators with their kind.\n * @ignore\n */\nconst decoratorSymbol = Symbol(\"YopValidationDecorator\")\n\n/**\n * Retrieves the kind of a validation decorator from a value.\n * @param value - The value to inspect.\n * @returns The decorator kind, if present.\n * @ignore\n */\nexport function getValidationDecoratorKind(value: any): string | undefined {\n return value?.[decoratorSymbol]\n}\n\n/**\n * Creates a class field decorator that assigns or modifies field constraints.\n * @template Parent - The type of the parent object.\n * @template Value - The type of the field value.\n * @param properties - An object or function to assign/modify field constraints.\n * @param reset - If true, resets the field constraints before applying properties.\n * @returns A class field decorator function.\n * @ignore\n */\nexport function fieldDecorator<Parent, Value>(properties: object | ((field: InternalCommonConstraints) => void), reset = false) {\n return (_: unknown, context: ClassFieldDecoratorContext<Parent, Value>) => {\n const classConstraints = initClassConstraints(context.metadata)\n if (!Object.hasOwnProperty.bind(classConstraints)(\"fields\"))\n classConstraints.fields = clone(classConstraints.fields ?? {})\n\n const fieldName = context.name as string\n const fields = classConstraints.fields!\n if (reset || !Object.hasOwnProperty.bind(fields)(fieldName))\n fields[fieldName] = {} as InternalCommonConstraints\n\n if (typeof properties === \"function\")\n properties(fields[fieldName])\n else\n assign(fields[fieldName], properties)\n }\n}\n\n/**\n * Type for a map of group names to constraints.\n * @template Constraints - The type of the constraints.\n * @ignore\n */\nexport type Groups<Constraints> = { [group: string]: Constraints }\n\n/**\n * Merges constraints from props and groups using a merger function.\n * @template Constraints - The type of the constraints.\n * @param props - The main constraints object.\n * @param groups - Optional groups of constraints.\n * @param merger - Function to merge each constraints object.\n * @ignore\n */\nexport function mergeMetadata<Constraints>(props?: Constraints, groups?: Groups<Constraints>, merger: (params: Constraints) => void = () => {}) {\n Object.values(groups ?? {}).concat(props != null ? [props] : []).forEach(params => {\n merger(params)\n })\n}\n\n\n/**\n * Merges default constraint properties into field metadata, applying to all groups if not already set.\n * @template Constraints - The type of the constraints.\n * @template Parent - The type of the parent object.\n * @template Value - The type of the field value.\n * @param decorator - The field decorator function.\n * @param defaultProps - The default constraint properties to merge.\n * @returns A new field decorator function with merged defaults.\n * @ignore\n */\nexport function mergeDefaultMetadata<Constraints extends {}, Parent, Value>(\n decorator: (_: unknown, context: ClassFieldDecoratorContext<Parent, Value>) => void,\n defaultProps: Constraints\n) {\n return (_: unknown, context: ClassFieldDecoratorContext<Parent, Value>) => {\n decorator(_, context)\n const fields = (context.metadata?.[validationSymbol] as InternalClassConstraints)?.fields\n if (fields?.[context.name as string] != null) {\n const metadata = fields[context.name as string]\n Object.entries(defaultProps).forEach(([key, value]) => {\n const constraintName = key as keyof InternalCommonConstraints\n if (metadata[constraintName] === undefined)\n metadata[constraintName] = value as any\n if (metadata.groups != null) {\n Object.keys(metadata.groups).forEach(groupKey => {\n const groupName = groupKey as keyof Groups<Constraints>\n if (metadata.groups![groupName][constraintName] === undefined)\n metadata.groups![groupName][constraintName] = value as any\n })\n }\n })\n }\n }\n}\n\n/**\n * Creates a field validation decorator with the specified kind, constraints, groups, and validator.\n * @template Constraints - The type of the field constraints.\n * @template Value - The type of the field value.\n * @template Parent - The type of the parent object.\n * @param kind - The kind of the field (e.g., 'string', 'number').\n * @param constraints - The field constraints to apply.\n * @param groups - Optional groups of constraints.\n * @param validator - The validation function for the field.\n * @param isMinMaxType - Optional function to check min/max type.\n * @param traverse - Optional traverser function for the field.\n * @returns A class field decorator function with validation.\n * @ignore\n */\nexport function fieldValidationDecorator<\n Constraints extends CommonConstraints<any, any>,\n Value = ContraintsValue<Constraints>,\n Parent = ContraintsParent<Constraints>\n>(\n kind: string,\n constraints: Constraints,\n groups: Groups<Constraints> | undefined,\n validator: Validator<Constraints>,\n isMinMaxType?: (value: any) => boolean,\n traverse?: Traverser<Constraints>,\n) {\n const validate = (context: InternalValidationContext<any, any>, constraints: Constraints) => {\n if (context.ignored() || !validateConstraint(context, constraints, \"ignored\", isBoolean, (_, constraint) => constraint === false, undefined, undefined, false))\n return true\n if (!validateCommonConstraints(context, constraints))\n return false\n if (context.value == null)\n return true\n return validator(context, constraints)\n }\n constraints = assign(clone(constraints), { groups, kind, validate, traverse, isMinMaxType })\n const decorator = fieldDecorator<Parent, Value>(constraints)\n Object.defineProperty(decorator, decoratorSymbol, { value: kind })\n return decorator\n}\n","import { ConstraintMessage } from \"./constraints/Constraint\"\nimport { joinPath, Path } from \"./ObjectsUtil\"\nimport { ValidationForm, ValidationSettings, Yop } from \"./Yop\"\n\n/**\n * Type representing the validation group or groups being currently validated. `undefined` means the default group.\n * @category Validation Management\n */\nexport type Group = string | ((string | undefined)[])\n\n/**\n * The types of validation status levels. \"pending\" and \"unavailable\" are only used for asynchronous validations.\n * \"pending\" indicates that the asynchronous validation is in progress, while \"unavailable\" indicates that the validation\n * couldn't be performed (e.g., due to an unreachable server).\n * @see {@link ValidationStatus}\n * @category Validation Management\n */\nexport type Level = \"info\" | \"warning\" | \"error\" | \"pending\" | \"unavailable\"\n\n/**\n * Interface representing the status of a validation, including its level, path, value, kind, code, constraint, and message.\n * This is used to track the results of validation operations and provide feedback to the user.\n * @category Validation Management\n */\nexport type ValidationStatus = {\n\n /**\n * The severity level of the validation status, or the status of asynchronous validation.\n * @see {@link Level}\n */\n level: Level\n\n /**\n * The path to the validated value, represented as a string (e.g., \"users[0].address.street\").\n */\n path: string\n\n /**\n * The value that was validated.\n */\n value: any\n\n /**\n * The kind of validation (e.g., \"string\", \"number\", \"array\"), used for message resolution.\n */\n kind: string\n\n /**\n * A code representing the specific validation type (e.g., \"required\", \"min\"), used for message resolution.\n */\n code: string\n\n /**\n * The constraint value that caused the validation error (e.g., `true` for a \"required\" constraint, `1` for a \"min\" constraint).\n */\n constraint: any\n\n /**\n * The resolved message for this validation status, which can be displayed to the user.\n */\n message: ConstraintMessage\n}\n\n/**\n * Interface representing the context of a validation operation, providing access to the value being validated, its path,\n * parent context, root context, settings, form, and a store for sharing data across validations.\n * \n * @template Value - The type of the value being validated.\n * @template Parent - The type of the parent object containing the value.\n * @category Validation Management\n */\nexport interface ValidationContext<Value, Parent = unknown> {\n \n readonly kind: string\n\n readonly value: Value\n readonly path: Path\n\n readonly parent: Parent\n readonly parentContext: ValidationContext<Parent> | undefined\n\n getRoot<T>(): T | undefined\n readonly rootContext: ValidationContext<unknown> | undefined\n\n readonly settings: ValidationSettings | undefined\n\n readonly form: ValidationForm | undefined\n\n readonly store: Map<string, any>\n}\n\n/**\n * @ignore\n */\nexport const UndefinedParent = Object.freeze(Object.create(null))\n\n/**\n * Internal implementation of the ValidationContext interface, used for managing validation state and providing utility methods\n * for creating child contexts and statuses.\n * @ignore\n */\nexport class InternalValidationContext<Value, Parent = unknown> implements ValidationContext<Value, Parent> {\n\n readonly yop: Yop\n\n readonly kind: string\n\n readonly value: Value\n readonly path: Path\n\n readonly parentContext: InternalValidationContext<Parent> | undefined\n readonly rootContext: InternalValidationContext<unknown> | undefined\n\n readonly settings: ValidationSettings | undefined\n\n readonly store: Map<string, any>\n\n readonly statuses: Map<string, ValidationStatus>\n\n constructor(props: {\n yop: Yop\n kind: string\n value: Value\n key?: string | number | undefined\n parentContext?: InternalValidationContext<Parent> | undefined\n rootContext?: InternalValidationContext<unknown> | undefined\n userContext?: unknown | undefined\n statuses?: Map<string, ValidationStatus>\n settings?: ValidationSettings\n }) {\n if (props.parentContext != null && props.key == null)\n throw new Error(\"key must be provided when parentContext is provided\")\n\n this.yop = props.yop\n this.kind = props.kind\n this.value = props.value\n this.parentContext = props.parentContext\n this.rootContext = props.rootContext\n this.settings = props.settings\n this.statuses = props.statuses ?? new Map()\n\n this.store = props.yop.store\n\n this.path = props.key == null ? [] : (props.parentContext?.path.concat(props.key) ?? [props.key])\n }\n\n ignored() {\n return this.settings?.ignore?.(this.path) ?? false\n }\n\n get parent() {\n return this.parentContext?.value || UndefinedParent as Parent\n }\n\n get groups() {\n return this.settings?.groups\n }\n\n get form() {\n return this.settings?.form\n }\n\n getRoot<T>() {\n return this.rootContext?.value as T | undefined\n }\n\n createChildContext(props: {\n kind: string\n value: Value\n key: string | number\n }) {\n return new InternalValidationContext({\n yop: this.yop,\n kind: props.kind,\n value: props.value,\n key: props.key,\n parentContext: this,\n rootContext: this.rootContext ?? this,\n settings: this.settings,\n statuses: this.statuses\n })\n }\n\n createStatus(code: string, constraint: any, message?: ConstraintMessage, level: Level = \"error\"): ValidationStatus {\n return {\n level,\n path: joinPath(this.path),\n value: this.value,\n kind: this.kind,\n code,\n constraint,\n message: this.yop.messageProvider.getMessage(this, code, constraint, message, level),\n }\n }\n\n setStatus(code: string, constraint: any, message?: ConstraintMessage, level: Level = \"error\"): ValidationStatus {\n const status = this.createStatus(code, constraint, message, level)\n this.statuses.set(status.path, status)\n return status\n }\n}\n\n/**\n * @ignore\n */\nexport type ValuedContext<Value, Parent> = InternalValidationContext<NonNullable<Value>, Parent>\n\n","import { CommonConstraints } from \"./constraints/CommonConstraints\"\nimport { validateConstraint } from \"./constraints/Constraint\"\nimport { MinMaxConstraints, validateMinMaxConstraints } from \"./constraints/MinMaxConstraints\"\nimport { MessageProvider, messageProvider_en_US, messageProvider_fr_FR } from \"./MessageProvider\"\nimport { ClassFieldDecorator, getMetadataFromDecorator } from \"./Metadata\"\nimport { joinPath, Path, splitPath } from \"./ObjectsUtil\"\nimport { Constructor, isBoolean } from \"./TypesUtil\"\nimport { Group, InternalValidationContext, ValidationStatus } from \"./ValidationContext\"\nimport { FormManager } from \"../reform/FormManager\"\n\n(Symbol as any).metadata ??= Symbol.for(\"Symbol.metadata\")\n\n/**\n * Symbol used to store validation metadata on class fields. This symbol is used as a key to attach validation constraints and related\n * information to class properties.\n * @ignore\n */\nexport const validationSymbol = Symbol('YopValidation')\n\n/**\n * Type for async validation status, including dependencies.\n * @category Validation Management\n */\nexport type AsyncValidationStatus = {\n\n /**\n * The current validation status, which can be \"pending\", \"unavailable\", or a regular validation status.\n */\n status?: ValidationStatus | undefined\n /**\n * The dependencies for the asynchronous validation.\n */\n dependencies: any[]\n}\n\n/**\n * Type for resolved constraints, including required, min, and max.\n * @template MinMax - The type for min/max values.\n * @category Validation Management\n */\nexport type ResolvedConstraints<MinMax = unknown> = {\n\n /**\n * Whether the field is required.\n */\n required: boolean\n /**\n * The minimum value or length for the field, if applicable.\n */\n min?: MinMax\n /**\n * The maximum value or length for the field, if applicable.\n */\n max?: MinMax\n}\n\n/**\n * Type for resolved constraints with an editable field metadata. *Warning*: the `fieldMetadata` property is mutable and should be used with\n * caution, as modifying it can lead to unexpected behavior in validation logic. It is intended for advanced use cases where access to the\n * original constraints is necessary, but it should not be modified during normal validation operations.\n * @template MinMax - The type for min/max values.\n * @category Validation Management\n */\nexport type UnsafeResolvedConstraints<MinMax = unknown> = ResolvedConstraints<MinMax> &{\n fieldMetadata?: CommonConstraints<any, any> | undefined\n}\n\n/**\n * Base interface of a form manager, extended by {@link FormManager}, representing form state and operations.\n * @category Validation Management\n */\nexport interface ValidationForm {\n\n /**\n * Whether the form has been submitted at least once, even if the submission was unsuccessful.\n */\n readonly submitted: boolean\n /**\n * Whether the form is currently being submitted.\n */\n readonly submitting: boolean\n /**\n * Map of validation statuses for each field.\n */\n readonly statuses: Map<string, ValidationStatus>\n /**\n * List of all errors in the form: this includes all validation statuses with a severity level of \"error\".\n */\n readonly errors: ValidationStatus[]\n /**\n * A map that can be used to store arbitrary data related to the form.\n */\n readonly store: Map<string, any>\n /**\n * The HTML form element associated with this validation form.\n */\n readonly htmlForm?: HTMLFormElement\n\n /**\n * Retrieves the value of a field by its path.\n * @template T - The expected type of the field value.\n * @param path - The path to the field.\n * @returns The value of the field, or undefined if not found.\n */\n getValue<T = any>(path: string | Path): T | undefined\n\n /**\n * Checks if a field has been touched.\n * @param path - The path to the field.\n * @returns True if the field has been touched, false otherwise.\n */\n isTouched(path?: string | Path): boolean\n /**\n * Marks a field as touched.\n * @param path - The path to the field.\n */\n touch(path?: string | Path): void\n /**\n * Marks a field as untouched.\n * @param path - The path to the field.\n */\n untouch(path?: string | Path): void\n\n /**\n * Checks if a field is dirty (has been modified). If no path is provided, checks if any field in the entire form is dirty.\n * @param path - The path to the field.\n * @param ignoredPath - Optional path to ignore during the check.\n * @returns True if the field is dirty, false otherwise.\n */\n isDirty(path?: string | Path, ignoredPath?: string | Path): boolean\n}\n\n/**\n * Interface for validation settings, including path, groups, and options.\n * @category Validation Management\n */\nexport interface ValidationSettings {\n\n /**\n * The path to the field or object being validated. This can be a string with dot notation (e.g., \"address.street\") or\n * an array of path segments (e.g., [\"address\", \"street\"]). If omitted, the validation will be performed on the root value.\n */\n path?: string | Path\n\n /**\n * Validation groups to apply during validation. This can be a single group or an array of groups. If specified, only the\n * constraints associated with at least one of the active groups will be validated.\n */\n groups?: Group\n\n /**\n * Function to determine if a path should be ignored during validation.\n */\n ignore?: (path: Path) => boolean\n\n /**\n * Whether to skip asynchronous validation.\n */\n skipAsync?: boolean\n\n /**\n * The validation form associated with this validation context. This form is set by the form manager when performing form-level validation\n * and can be used to access form state and operations during validation.\n */\n form?: ValidationForm\n}\n\n/**\n * Interface for settings used when resolving constraints at a specific path.\n * @ignore\n */\nexport interface ConstraintsAtSettings extends ValidationSettings {\n unsafeMetadata?: boolean\n}\n\n/**\n * Main class for validation logic, constraint resolution, and message provider management.\n * @category Validation Management\n */\nexport class Yop {\n\n private static defaultInstance?: Yop\n private static classIds = new Map<string, Constructor<unknown>>()\n \n private static messageProviders = new Map<string, MessageProvider>()\n static {\n this.registerMessageProvider(messageProvider_en_US)\n this.registerMessageProvider(messageProvider_fr_FR)\n }\n\n private locale: string = Yop.defaultInstance?.locale ?? \"en-US\"\n \n private _store = new Map<string, any>()\n private _asyncStatuses = new Map<string, AsyncValidationStatus>()\n\n /**\n * Gets the store map, which can be used to store arbitrary data related to validation operations. This allows sharing data across different\n * validation contexts and operations.\n */\n get store() {\n return this._store\n }\n\n /**\n * Gets the map of asynchronous validation statuses, where each key is a path and the value is the corresponding asynchronous validation status.\n */\n get asyncStatuses() {\n return this._asyncStatuses\n }\n\n /**\n * Registers a class constructor with a given ID.\n * @param id The ID to associate with the class constructor.\n * @param constructor The class constructor to register.\n * @ignore\n */\n static registerClass(id: string, constructor: Constructor<unknown>) {\n Yop.classIds.set(id, constructor)\n }\n\n /**\n * Resolves a class constructor by its ID.\n * @param id The ID of the class or a function reference.\n * @param silent If true, suppresses error messages for unregistered classes.\n * @returns The resolved class constructor, or undefined if not found.\n * @ignore\n */\n static resolveClass<T>(id: unknown, silent = false): Constructor<T> | undefined {\n if (typeof id === \"string\") {\n const resolved = Yop.classIds.get(id)\n if (resolved == null && silent === false)\n console.error(`Class \"${ id }\" unregistered in Yop. Did you forget to add a @id(\"${ id }\") decorator to the class?`)\n return resolved as Constructor<T>\n }\n if (typeof id === \"function\" && id.prototype == null)\n return id() as Constructor<T>\n return id as Constructor<T> | undefined\n }\n\n private contextAt(decorator: ClassFieldDecorator<any>, value: any, settings: ValidationSettings, traverseNullish = false) {\n let constraints = getMetadataFromDecorator(decorator)\n if (constraints == null)\n return undefined\n\n const segments = typeof settings.path === \"string\" ? splitPath(settings.path) : (settings.path ?? [])\n if (segments == null)\n return undefined\n \n let context = new InternalValidationContext<any>({\n yop: this,\n kind: constraints.kind,\n value,\n settings: settings,\n })\n\n for (const segment of segments) {\n [constraints, value] = constraints.traverse?.(context, constraints, segment, traverseNullish) ?? [,]\n if (constraints == null)\n return undefined\n context = context.createChildContext({ kind: constraints.kind, value, key: segment })\n }\n \n return [context, constraints] as const\n }\n\n /**\n * Retrieves the constraints for a given class field decorator and value, using the provided settings.\n * @param decorator The class field decorator defining the constraints.\n * @param value The value to be validated against the constraints.\n * @param settings Optional settings for constraint resolution, including path and unsafe metadata flag.\n * @returns The resolved constraints, or undefined if no constraints are found.\n */\n constraintsAt<MinMax = unknown>(decorator: ClassFieldDecorator<any>, value: any, settings?: ConstraintsAtSettings): ResolvedConstraints<MinMax> | undefined {\n const [context, constraints] = this.contextAt(decorator, value, settings ?? {}, true) ?? []\n\n if (context != null && constraints != null) {\n const resolvedContraints: UnsafeResolvedConstraints<MinMax> = { required: false }\n validateConstraint(context, constraints, \"required\", isBoolean, (_, constraint) => { resolvedContraints.required = constraint; return true })\n const isMinMaxType = (constraints as MinMaxConstraints<any, any>).isMinMaxType\n if (isMinMaxType != null) {\n validateMinMaxConstraints(\n context,\n constraints as MinMaxConstraints<unknown, unknown>,\n isMinMaxType,\n (_, min) => { resolvedContraints.min = min; return true },\n (_, max) => { resolvedContraints.max = max; return true }\n )\n }\n if (settings?.unsafeMetadata)\n resolvedContraints.fieldMetadata = constraints\n return resolvedContraints\n }\n\n return undefined\n }\n /**\n * Static version of the constraintsAt method, which initializes the Yop instance and retrieves the constraints for a given class field decorator and value.\n * @param decorator The class field decorator defining the constraints.\n * @param value The value to be validated against the constraints.\n * @param settings Optional settings for constraint resolution, including path and unsafe metadata flag.\n * @returns The resolved constraints, or undefined if no constraints are found.\n */\n static constraintsAt<Value>(decorator: ClassFieldDecorator<Value>, value: any, settings?: ConstraintsAtSettings) {\n return Yop.init().constraintsAt(decorator, value, settings)\n }\n\n /**\n * Retrieves the asynchronous validation status for a given path. The path can be a string or an array of path segments.\n * @param path The path for which to retrieve the asynchronous validation status.\n * @returns The asynchronous validation status, or undefined if not found.\n */\n getAsyncStatus(path: string | Path) {\n return this.asyncStatuses.get(typeof path === \"string\" ? path : joinPath(path))?.status\n }\n\n /**\n * Validates a value against the constraints defined by a class field decorator, using the provided validation settings. This method performs\n * the validation logic and returns the validation context, which includes the results of the validation operation. The context contains\n * information about the value, its path, any validation statuses.\n * @param value The value to be validated.\n * @param decorator The decorator defining the validation constraints.\n * @param settings The validation settings, including the path and other options.\n * @returns The validation context after performing the validation.\n * @ignore\n */\n rawValidate<Value>(value: any, decorator: ClassFieldDecorator<Value>, settings: ValidationSettings = { path: [] }) {\n const [context, constraints] = this.contextAt(decorator, value, settings) ?? []\n if (context != null && constraints != null)\n constraints.validate(context, constraints)\n return context\n }\n\n /**\n * Validates a value against the constraints defined by a class field decorator, using the provided validation settings. This method performs\n * the validation logic and returns the validation statuses array.\n * @param value The value to be validated.\n * @param decorator The decorator defining the validation constraints.\n * @param settings The validation settings, including the path and other options.\n * @returns An array of validation statuses after performing the validation.\n */\n validate<Value>(value: any, decorator: ClassFieldDecorator<Value>, settings: ValidationSettings = { path: [] }) {\n const context = this.rawValidate(value, decorator, settings)\n return context != null ? Array.from(context.statuses.values()) : []\n }\n /**\n * Static version of the validate method, which initializes the Yop instance and performs validation on the provided value using the specified\n * decorator and settings.\n * @param value The value to be validated.\n * @param decorator The decorator defining the validation constraints.\n * @param settings The validation settings, including the path and other options.\n * @returns An array of validation statuses after performing the validation.\n * @see {@link Yop#validate}\n */\n static validate<Value>(value: any, decorator: ClassFieldDecorator<Value>, settings?: ValidationSettings) {\n return Yop.init().validate(value, decorator, settings)\n }\n\n /**\n * Registers a message provider for a specific locale. The message provider is used to retrieve localized validation messages\n * based on the current locale setting.\n * @param provider The message provider to register.\n */\n static registerMessageProvider(provider: MessageProvider) {\n try {\n const locale = Intl.getCanonicalLocales(provider.locale)[0]\n Yop.messageProviders.set(locale, provider)\n }\n catch (e) {\n console.error(`Invalid locale \"${ provider.locale }\" in message provider. Ignoring.`, e)\n }\n }\n\n /**\n * Gets the current locale used for message resolution. This locale determines which message provider is used to retrieve validation messages.\n * @returns The current locale as a string.\n */\n getLocale() {\n return this.locale\n }\n /**\n * Static version of the getLocale method, which initializes the Yop instance and retrieves the current locale.\n * @returns The current locale as a string.\n * @see {@link Yop#getLocale}\n */\n static getLocale() {\n return Yop.init().locale\n }\n \n /**\n * Sets the current locale used for message resolution. This locale determines which message provider is used to retrieve validation messages.\n * @param locale The locale to set. This should be a valid BCP 47 language tag (e.g., \"en-US\", \"fr-FR\").\n */\n setLocale(locale: string) {\n try {\n locale = Intl.getCanonicalLocales(locale)[0]\n if (Yop.messageProviders.has(locale))\n this.locale = locale\n else\n console.error(`No message provider for locale \"${ locale }\". Ignoring`)\n }\n catch (e) {\n console.error(`Invalid locale \"${ locale }\". Ignoring.`, e)\n }\n }\n /**\n * Static version of the setLocale method, which initializes the Yop instance and sets the current locale.\n * @param locale The locale to set. This should be a valid BCP 47 language tag (e.g., \"en-US\", \"fr-FR\").\n * @see {@link Yop#setLocale}\n */\n static setLocale(locale: string) {\n Yop.init().setLocale(locale)\n }\n\n /**\n * Gets the message provider for the current locale. This message provider is used to retrieve localized validation messages based on the current locale setting.\n */\n get messageProvider() {\n return Yop.messageProviders.get(this.locale)!\n }\n\n /**\n * Initializes the Yop instance if it hasn't been initialized yet and returns the default instance.\n * @returns The default Yop instance.\n */\n static init(): Yop {\n if (Yop.defaultInstance == null)\n Yop.defaultInstance = new Yop()\n return Yop.defaultInstance\n }\n}\n","import { InternalCommonConstraints } from \"../constraints/CommonConstraints\"\nimport { Constraint } from \"../constraints/Constraint\"\nimport { fieldDecorator, Groups } from \"../Metadata\"\n\n/**\n * Field decorator to mark a field as ignored for validation.\n * \n * Example usage:\n * ```tsx\n * class Person {\n * @string({ required: true, match: /^[A-Za-z]+$/ })\n * name: string | null = null\n * }\n * class Anonymous extends Person {\n * @ignored() // ignore all validation constraints on `name`\n * override name: string | null = null\n * }\n * ```\n * \n * @template Parent - The type of the parent object.\n * @param ignored - The constraint or boolean indicating if the field should be ignored (default: true).\n * @param groups - Optional groups with their own ignored constraints.\n * @returns A field decorator function that marks a field as ignored for validation.\n * @category Property Decorators\n */\nexport function ignored<Parent>(ignored: Constraint<any, boolean, Parent> = true, groups?: Groups<Constraint<any, boolean, Parent>>) {\n return fieldDecorator<Parent, any>(field => {\n field.ignored = ignored\n\n if (groups != null) {\n field.groups ??= {}\n for (const [name, constraint] of Object.entries(groups)) {\n if (field.groups?.[name] != null)\n field.groups[name].ignored = constraint\n else\n field.groups[name] = { ignored: constraint } as InternalCommonConstraints\n }\n }\n })\n}\n","import { FormEvent } from \"react\"\nimport { clone, equal, get, set, SetResult, unset } from \"../yop/ObjectsUtil\"\nimport { FormConfig } from \"./useForm\"\nimport { ValidationForm, ResolvedConstraints, UnsafeResolvedConstraints, ValidationSettings, Yop, ConstraintsAtSettings } from \"../yop/Yop\"\nimport { joinPath, Path } from \"../yop/ObjectsUtil\"\nimport { ValidationStatus } from \"../yop/ValidationContext\"\nimport { ignored } from \"../yop/decorators/ignored\"\nimport { ArrayHelper } from \"./ArrayHelper\"\nimport { Reform } from \"./Reform\"\n\n/**\n * Validation settings for reform forms, extending base validation settings.\n * @property method - The validation method to use.\n * @ignore\n */\nexport interface ReformValidationSettings extends ValidationSettings {\n method: \"validate\" | \"validateAt\" | \"constraintsAt\"\n}\n\n/**\n * Settings for constraintsAt validation, combining reform and Yop constraint settings.\n * @ignore\n */\nexport interface ReformConstraintsAtSettings extends ReformValidationSettings, ConstraintsAtSettings {\n}\n\n/**\n * Options object for setValue operations.\n * @property touch - Whether to mark the field as touched.\n * @property validate - Whether to validate after setting the value.\n * @property propagate - Whether to propagate the change to observers.\n * @category Form Management\n */\nexport type SetValueOptionsObject = {\n /** Whether to mark the field as touched. */\n touch?: boolean\n /** Whether to validate after setting the value. */\n validate?: boolean\n /** Whether to propagate the change to observers. */\n propagate?: boolean\n}\n\n/**\n * Options for setValue: either a boolean (validate) or an options object.\n * @category Form Management\n */\nexport type SetValueOptions = boolean | SetValueOptionsObject\n\n/**\n * Interface for a form manager, providing value management, validation, and event APIs.\n * @category Form Management\n */\nexport interface FormManager<T> extends ValidationForm {\n\n /**\n * Renders the form, causing any changes to be reflected in the UI.\n */\n render(): void\n\n /**\n * Sets the submitting state of the form. Submitting state is automatically set to `true` when the form is submitted, and\n * should be reset to `false` when submission is complete.\n * @param submitting - Whether the form is submitting.\n */\n setSubmitting(submitting: boolean): void\n \n /**\n * The initial values of the form, as provided in the form config. These values are not modified by the form manager, and\n * represent the original state of the form.\n */\n readonly initialValues: T | null | undefined\n\n /**\n * Used when initialValues is provided as a promise. Indicates whether the promise is still pending.\n */\n readonly initialValuesPending: boolean\n\n /**\n * The current values of the form. These values are managed by the form manager and should be considered the source of truth\n * for the form state.\n */\n readonly values: T\n\n /**\n * Sets the value of a form field.\n * @param path - The path to the field.\n * @param value - The value to set.\n * @param options - Options for setting the value. See {@link SetValueOptions}.\n * @returns The result of the set operation, or undefined if the path was invalid. See {@link SetResult}.\n */\n setValue(path: string | Path, value: unknown, options?: SetValueOptions): SetResult\n\n /**\n * Validates the entire form.\n * @param touchedOnly - Whether to validate only touched fields.\n * @param ignore - A function to determine if a path should be ignored during validation.\n */\n validate(touchedOnly?: boolean, ignore?: (path: Path) => boolean): Map<string, ValidationStatus>\n\n /**\n * Validates a specific field located at a given path in the form.\n * @param path - The path to the field.\n * @param touchedOnly - Whether to validate only touched fields.\n * @param skipAsync - Whether to skip asynchronous validation.\n */\n validateAt(path: string | Path, touchedOnly?: boolean, skipAsync?: boolean): {\n changed: boolean,\n statuses: Map<string, ValidationStatus>\n }\n\n /**\n * Updates the asynchronous validation status of a specific field.\n * @param path - The path to the field.\n */\n updateAsyncStatus(path: string | Path): void\n\n /**\n * Scrolls to the first field with a validation error, if any. This is typically called after form submission if there\n * are validation errors, to bring the user's attention to the first error. The implementation will scroll to an HTML with\n * an id set to the path of the field with the error, so form fields should have their id set accordingly for this to work.\n */\n scrollToFirstError(): void\n\n /**\n * Retrieves the constraints for a specific field.\n * @param path - The path to the field.\n * @param unsafeMetadata - Whether to include unsafe field metadata. If `true`, the resolved constraints will be of type\n * {@link UnsafeResolvedConstraints}, which enables modification of the field constraints stored in the class metadata.\n * This can be useful for advanced use cases, but should be used with caution.\n * @return The resolved constraints for the field, or undefined if there are no constraints. See {@link ResolvedConstraints}.\n */\n constraintsAt<MinMax = unknown>(path: string | Path, unsafeMetadata?: boolean): ResolvedConstraints<MinMax> | undefined\n\n /**\n * Handler for form submission. This should be called in the onSubmit handler of the form element. It will prevent the default\n * form submission behavior,\n * @param e - The form submission event.\n */\n submit(e: FormEvent<HTMLFormElement>): void\n\n /**\n * Retrieves an array helper for a specific field. The array helper provides methods for manipulating array fields, such\n * as appending, inserting, and removing elements, with automatic touch, validation, and rendering.\n * @param path - The path to the array field.\n * @return An ArrayHelper instance for the specified path, or undefined if the field is not an array.\n */\n array<T = any>(path: string): ArrayHelper<T> | undefined\n\n /**\n * Adds an event listener for reform events of type {@link ReformSetValueEvent}.\n * @param listener - The event listener to add.\n */\n addReformEventListener(listener: EventListener): void\n\n /**\n * Removes an event listener for reform events of type {@link ReformSetValueEvent}.\n * @param listener - The event listener to remove.\n */\n removeReformEventListener(listener: EventListener): void\n}\n\n/**\n * The event type string for reform set value events.\n * @ignore\n */\nconst ReformSetValueEventType = 'reform:set-value'\n\n/**\n * Event fired when a value is set in the form, used for observer propagation.\n * @template T - The type of the value being set.\n * @category Form Management\n */\nexport interface ReformSetValueEvent<T = any> extends CustomEvent<{\n readonly form: FormManager<unknown>,\n readonly path: string,\n readonly previousValue: T,\n readonly value: T,\n readonly options: SetValueOptionsObject\n}> {\n}\n\n/**\n * Creates a ReformSetValueEvent for observer propagation.\n * @template T - The type of the value being set.\n * @param form - The form manager instance.\n * @param path - The path to the value being set.\n * @param previousValue - The previous value at the path.\n * @param value - The new value being set.\n * @param options - The set value options.\n * @returns The created ReformSetValueEvent.\n * @ignore\n */\nfunction createReformSetValueEvent<T = any>(\n form: FormManager<unknown>,\n path: string,\n previousValue: T,\n value: T,\n options: SetValueOptionsObject\n): ReformSetValueEvent<T> {\n return new CustomEvent(ReformSetValueEventType, { detail: { form, path, previousValue, value, options }})\n}\n\n/**\n * Implementation of the FormManager interface, providing value management, validation, eventing, and array helpers.\n * @ignore\n */\nexport class InternalFormManager<T extends object | null | undefined> implements FormManager<T> {\n\n private _config: FormConfig<T> = { validationSchema: ignored() }\n private yop = new Yop()\n private pathCache = new Map<string, Path>()\n\n private _initialValues: unknown = undefined\n private _initialValuesPending = false\n private _values: unknown = undefined\n private _statuses = new Map<string, ValidationStatus>()\n private touched: object | true | null = null\n private _submitting = false\n private _submitted = false\n\n private eventTarget = new EventTarget()\n\n htmlForm?: HTMLFormElement\n\n constructor(readonly render: () => void) {\n }\n\n addReformEventListener(listener: EventListener) {\n this.eventTarget.addEventListener(ReformSetValueEventType, listener)\n }\n\n removeReformEventListener(listener: EventListener) {\n this.eventTarget.removeEventListener(ReformSetValueEventType, listener)\n }\n\n get initialValuesPending() {\n return this._initialValuesPending\n }\n\n get submitted() {\n return this._submitted\n }\n\n get submitting() {\n return this._submitting\n }\n\n get config() {\n return this._config\n }\n\n get store() {\n return this.yop.store\n }\n\n set initialValuesPending(pending: boolean) {\n this._initialValuesPending = pending\n }\n\n setSubmitting(submitting: boolean): void {\n this._submitting = submitting\n this.render()\n }\n\n commitInitialValues() {\n this._initialValues = clone(this._config.initialValues)\n if (this._config.initialValuesConverter != null)\n this._initialValues = this._config.initialValuesConverter(this._initialValues as T)\n this._values = clone(this._initialValues)\n this.touched = null\n this._statuses = new Map()\n }\n\n onRender(config: FormConfig<T>) {\n this._config = config\n }\n\n get initialValues(): T | null | undefined {\n return this._initialValues as T | null | undefined\n }\n\n get values(): T {\n if (this._values == null && this._config.initialValues != null)\n this.commitInitialValues()\n return this._values as T\n }\n\n getValue<V = any>(path: string | Path): V | undefined {\n return get<V>(this.values, path, this.pathCache)\n }\n\n setValue(path: string | Path, value: unknown, options?: SetValueOptions): SetResult {\n const result = set(this.values, path, value, this.pathCache, { clone: true })\n if (result == null)\n return undefined\n this._values = result.root\n\n const { touch, validate, propagate } = { propagate: true, ...(typeof options === \"boolean\" ? { validate: options } : options) }\n if (touch === false)\n this.untouch(path)\n else if (validate || touch)\n this.touch(path)\n\n if (validate) {\n this.validate()\n this.render()\n }\n\n if (this._config.dispatchEvent !== false && propagate === true) {\n setTimeout(() => {\n this.eventTarget.dispatchEvent(createReformSetValueEvent(\n this,\n typeof path === \"string\" ? path : joinPath(path),\n result.previousValue,\n value,\n { touch, validate, propagate }\n ))\n })\n }\n\n return result\n }\n\n isDirty(path?: string | Path, ignoredPath?: string | Path) {\n if (path == null || path.length === 0)\n return !equal(this.values, this._initialValues, ignoredPath)\n return !equal(get(this.values, path, this.pathCache), get(this._initialValues, path, this.pathCache), ignoredPath)\n }\n\n isTouched(path: string | Path = []) {\n return get(this.touched, path, this.pathCache) != null\n }\n\n touch(path: string | Path = []) {\n this.touched = set(this.touched, path, true, this.pathCache, { condition: currentValue => currentValue === undefined })?.root ?? null\n }\n\n untouch(path: string | Path = []) {\n if (path.length === 0)\n this.touched = null\n else\n unset(this.touched, path, this.pathCache)\n }\n\n getTouchedValue<T = any>(path: string | Path) {\n return get(this.touched, path, this.pathCache) as T\n }\n\n setTouchedValue(path: string | Path, value: any) {\n this.touched = set(this.touched, path, value, this.pathCache)?.root ?? null\n }\n\n get statuses(): Map<string, ValidationStatus> {\n return this._statuses\n }\n\n get errors(): ValidationStatus[] {\n return Array.from(this._statuses.values()).filter(status => status.level === \"error\")\n }\n\n validate(touchedOnly = true, ignore?: (path: Path, form: FormManager<T>) => boolean): Map<string, ValidationStatus> {\n let ignoreFn = ignore\n if (this._config.ignore != null) {\n if (ignore != null)\n ignoreFn = (path, form) => ignore(path, form) || this._config.ignore!(path, form)\n else\n ignoreFn = this._config.ignore\n }\n if (!this._submitted && touchedOnly) {\n if (ignoreFn == null)\n ignoreFn = (path, _form) => !this.isTouched(path)\n else {\n const previousIgnore = ignoreFn\n ignoreFn = (path, form) => !this.isTouched(path) || previousIgnore(path, form)\n }\n }\n\n const schema = this._config.validationSchema ?? ignored()\n const options: ReformValidationSettings = {\n method: \"validate\",\n form: this,\n groups: this._config.validationGroups,\n ignore: ignoreFn != null ? path => ignoreFn(path, this) : undefined\n }\n if (Array.isArray(this._config.validationPath)) {\n this._statuses = new Map()\n for (const path of this._config.validationPath) {\n options.path = path\n this.yop.rawValidate(this.values, schema, options)?.statuses?.forEach((status, path) => this._statuses.set(path, status))\n }\n }\n else {\n options.path = this._config.validationPath\n this._statuses = this.yop.rawValidate(this.values, schema, options)?.statuses ?? new Map()\n }\n return this._statuses\n }\n\n validateAt(path: string | Path, touchedOnly = true, skipAsync = true) {\n if (touchedOnly && !this.submitted && !this.isTouched(path))\n return { changed: false, statuses: new Map<string, ValidationStatus>() }\n\n let changed = false\n const prefix = typeof path === \"string\" ? path : joinPath(path)\n for (const key of this._statuses.keys()) {\n if (key.startsWith(prefix) && (key.length === prefix.length || ['.', '['].includes(key.charAt(prefix.length)))) {\n this._statuses.delete(key)\n changed = true\n }\n }\n \n const options: ReformValidationSettings = {\n method: \"validateAt\",\n form: this,\n path,\n skipAsync,\n groups: this._config.validationGroups,\n ignore: this._config.ignore != null ? path => this._config.ignore!(path, this) : undefined\n }\n \n const statuses = this.yop.rawValidate(this.values, this._config.validationSchema ?? ignored(), options)?.statuses ?? new Map<string, ValidationStatus>()\n statuses.forEach((status, path) => this._statuses.set(path, status))\n return { changed: changed || statuses.size > 0, statuses }\n }\n\n constraintsAt<MinMax = unknown>(path: string | Path, unsafeMetadata?: boolean): ResolvedConstraints<MinMax> | undefined {\n const settings: ReformConstraintsAtSettings = { method: \"constraintsAt\", form: this, path, unsafeMetadata }\n return this.yop.constraintsAt(this._config.validationSchema ?? ignored(), this.values, settings)\n }\n\n updateAsyncStatus(path: string | Path) {\n const status = this.yop.getAsyncStatus(path)\n if (status != null)\n this._statuses.set(status.path, status)\n else {\n path = typeof path === \"string\" ? path : joinPath(path)\n if (this._statuses.get(path)?.level === \"pending\")\n this._statuses.delete(path)\n }\n }\n\n submit(e: FormEvent<HTMLFormElement>): void {\n e.preventDefault()\n e.stopPropagation()\n\n this._submitted = true\n this.setSubmitting(true)\n\n setTimeout(async () => {\n let statuses = Array.from(this.validate(false).values())\n const pendings = statuses.filter(status => status.level === \"pending\")\n \n if (pendings.length > 0) {\n this.render()\n const asyncStatuses = (await Promise.all<ValidationStatus | undefined>(pendings.map(status => status.constraint)))\n .filter(status => status != null)\n if (asyncStatuses.length > 0) {\n asyncStatuses.forEach(status => this._statuses.set(status.path, status))\n statuses = Array.from(this._statuses.values())\n }\n }\n\n const errors = statuses.filter(status => status.level === \"error\" || (status.level === \"unavailable\" && status.message))\n const canSubmit = this._config.submitGuard?.(this)\n if (errors.length === 0 && canSubmit !== false)\n (this._config.onSubmit ?? (form => form.setSubmitting(false)))(this)\n else {\n if (Reform.logFormErrors && errors.length > 0)\n console.error(\"Validation errors\", errors)\n if (canSubmit !== false)\n this.scrollToFirstError(errors)\n this.setSubmitting(false)\n }\n })\n }\n\n scrollToFirstError(errors?: ValidationStatus[]) {\n errors ??= Array.from(this.statuses.values()).filter(status => status.level === \"error\" || (status.level === \"unavailable\" && status.message))\n const element = errors\n .map(status => window.document.getElementById(status.path))\n .filter(elt => elt != null)\n .sort((elt1, elt2) => elt1.compareDocumentPosition(elt2) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1)\n .shift()\n if (element != null) {\n element.scrollIntoView({ behavior: \"smooth\", block: \"center\" })\n element.focus({ preventScroll: true })\n }\n }\n\n array<T = any>(path: string): ArrayHelper<T> | undefined {\n const helper = new ArrayHelper<T>(this, path)\n return helper.isArray() ? helper : undefined\n }\n}\n","/**\n * Defines types and a decorator for observers in the Reform form management system. Observers allow you to react\n * to changes in other fields by specifying a path to observe and a callback function that receives context about\n * the change. The observer paths support a flexible syntax for targeting specific fields, including wildcards and\n * relative paths.\n */\nimport { useObservers } from \"./useObservers\"\nimport { InternalCommonConstraints } from \"../../yop/constraints/CommonConstraints\"\nimport { fieldDecorator } from \"../../yop/Metadata\"\nimport { Path } from \"../../yop/ObjectsUtil\"\nimport { ReformSetValueEvent } from \"../FormManager\"\nimport { FormConfig } from \"../useForm\"\n\n/**\n * Options for observer callback behavior.\n * @category Observers\n */\nexport type ObserverCallbackOptions = {\n\n /** If `true`, marks the field as untouched. */\n untouch?: boolean\n /** If `true`, propagates the value change to other observers. Defaults to `false` to prevent potential infinite loops*/\n propagate?: boolean\n}\n\n/**\n * Context object passed to observer callbacks.\n *\n * @template T - The type of the field value where the observer is attached.\n * @category Observers\n */\nexport type ObserverCallbackContext<T> = {\n \n /** The absolute path of the field value where the observer is attached */\n path: Path\n /** The value being observed. */\n observedValue: unknown\n /** The current value of the field where the observer is attached. */\n currentValue: T\n /** Sets the value of the field where the observer is attached. */\n setValue: (value: T, options?: ObserverCallbackOptions) => void\n /** The event object providing context. See {@link ReformSetValueEvent}. */\n event: ReformSetValueEvent<unknown>\n}\n\n/**\n * Observer callback function type.\n *\n * @template T - The type of the field value where the observer is attached.\n * @param context - The context for the observer callback. See {@link ObserverCallbackContext}.\n * @category Observers\n */\nexport type ObserverCallback<T> = (context: ObserverCallbackContext<T>) => void\n\n/**\n * Metadata for an observer, including its path and callback.\n *\n * @template T - The type of the field value where the observer is attached.\n * @ignore\n */\nexport type ObserverMetadata<T> = {\n\n /** The path of the field being observed. */\n path: string\n /** The observer callback function. */\n callback: ObserverCallback<T>\n}\n\n/**\n * Map of observer metadata, keyed by observed path.\n * @ignore\n */\nexport type Observers = Map<string, ObserverMetadata<any>>\n\n/**\n * Field metadata type that can hold observers in addition to common constraints.\n * @ignore\n */\nexport type ObserversField = InternalCommonConstraints & { observers?: Observers }\n\n/**\n * Decorator to register or remove an observer callback for a field. Observer paths use a syntax similar to Unix file paths,\n * supporting wildcards and array indices, and are relative to the parent object of the field where the observer is attached.\n * Paths can also be absolute (starting with a slash `/`) to observe fields from the root, or use `..` to observe fields from\n * higher up in the object tree.\n * \n * Observers are only triggered if {@link FormConfig.dispatchEvent} isn't set to `false` and if the class holding `observers`\n * decorators is bound to the current form using {@link useObservers}.\n *\n * Examples:\n * - `name` observes the `name` field of the parent object.\n * - `user/name` observes the `name` field of the sibling `user` object.\n * - `items[*]/price` observes the `price` field of all items in the sibling `items` array.\n * - `orders[0]/status` observes the `status` field of the first order in the sibling `orders` array.\n * - `/name` observes the `name` field at the root level.\n * - `../name` observes the `name` field in the parent of the parent object.\n *\n * Example usage:\n * ```tsx\n * class MyFormModel {\n * \n * age: number | null = null\n * \n * @observer(\"age\", (context) => context.setValue(\n * context.observedValue != null ? (context.observedValue as number) >= 18 : null,\n * { untouch: true }\n * ))\n * adult: boolean | null = null\n * }\n * \n * const form = useForm(MyFormModel, ...)\n * \n * ```\n *\n * @template Value - The type of the field value where the observer is attached.\n * @template Parent - The parent type containing the field.\n * @param path - The path to observe.\n * @param callback - The observer callback function, or undefined to remove it.\n * @returns A field decorator function.\n * @category Observers\n */\nexport function observer<Value, Parent>(path: string, callback: ObserverCallback<Value> | undefined) {\n return fieldDecorator<Parent, Value>(field => {\n const metadata = field as ObserversField\n metadata.observers ??= new Map()\n if (callback != null)\n metadata.observers.set(path, { path, callback })\n else\n metadata.observers.delete(path)\n })\n}\n","import { Path } from \"../../yop/ObjectsUtil\"\n\n\n/**\n * State constants for the observer path parser state machine.\n * @ignore\n */\nconst SLASH = 1\nconst OPEN_BRACKET = 2\nconst SINGLE_QUOTE = 3\nconst DOUBLE_QUOTE = 4\nconst CLOSE_QUOTE = 5\nconst CLOSE_BRACKET = 6\n\n\n/**\n * Type representing the parser state.\n * @ignore\n */\ntype State = typeof SLASH | typeof OPEN_BRACKET | typeof SINGLE_QUOTE | typeof DOUBLE_QUOTE | typeof CLOSE_QUOTE | typeof CLOSE_BRACKET | undefined\n\n\n/**\n * Represents a segment of an observer path.\n * @property kind - The type of path segment (e.g., property, index, wildcard).\n * @property value - The value of the segment, if applicable.\n * @ignore\n */\ntype PathElement = {\n kind: 'root' | 'parent' | 'property' | 'key' | 'index' | 'wildcard-index' | 'wildcard' | 'double-wildcard'\n value?: string | number\n}\n\n\n/**\n * Regular expression to match valid JavaScript identifiers.\n * @ignore\n */\nconst identifier = /^[$_\\p{ID_Start}][$\\p{ID_Continue}]*$/u\n\n/**\n * Pushes a property, wildcard, or double-wildcard segment to the segments array.\n * @param segment - The string segment to parse.\n * @param segments - The array to push the parsed PathElement into.\n * @returns True if the segment was valid and pushed, false otherwise.\n * @ignore\n */\nfunction pushProperty(segment: string, segments: PathElement[]): boolean {\n if (identifier.test(segment))\n segments.push({ kind: \"property\", value: segment })\n else if (segment === '*')\n segments.push({ kind: \"wildcard\" })\n else if (segment === '**')\n segments.push({ kind: \"double-wildcard\" })\n else\n return false\n return true\n}\n\n/**\n * Splits an observer path into its constituent segments.\n * @param path - The observer path string.\n * @param cache - Optional cache to store and retrieve previously parsed paths.\n * @returns An array of PathElement objects representing the path segments, or undefined if the path is invalid.\n * @ignore\n */\nexport function splitObserverPath(path: string, cache?: Map<string, PathElement[]>): PathElement[] | undefined {\n\n if (path.length === 0)\n return undefined\n\n if (cache != null) {\n const cached = cache.get(path)\n if (cached != null)\n return cached.slice()\n }\n\n const segments: PathElement[] = []\n\n let state: State = undefined,\n escape = false,\n segment = \"\",\n i = 0\n \n if (path.charAt(0) === '/' ) {\n segments.push({ kind: \"root\" })\n state = SLASH\n i++\n }\n else {\n while (path.startsWith(\"..\", i)) {\n segments.push({ kind: \"parent\" })\n i += 2\n if (i === path.length)\n return segments\n const c = path.charAt(i)\n if (c === '/' ) {\n i++\n state = SLASH\n }\n else if (c === '[') {\n i++\n state = OPEN_BRACKET\n break\n }\n else\n return undefined\n }\n }\n\n for ( ; i < path.length; i++) {\n let c = path.charAt(i)\n\n switch (c) {\n\n case '\\\\':\n if (state !== SINGLE_QUOTE && state !== DOUBLE_QUOTE)\n return undefined\n if (escape)\n segment += '\\\\'\n escape = !escape\n continue\n\n case ' ': case '\\t': case '\\r': case '\\n': case '.':\n if (state !== SINGLE_QUOTE && state !== DOUBLE_QUOTE)\n return undefined\n segment += c\n break\n\n case '/':\n if (state === SINGLE_QUOTE || state === DOUBLE_QUOTE)\n segment += c\n else if (state === CLOSE_BRACKET) {\n if (segment)\n return undefined\n state = SLASH\n }\n else if (state === undefined || state === SLASH) {\n if (!pushProperty(segment, segments))\n return undefined\n segment = \"\"\n state = SLASH\n }\n else\n return undefined\n break\n\n case '[':\n if (state === SINGLE_QUOTE || state === DOUBLE_QUOTE)\n segment += c\n else if (state === SLASH) {\n if (!pushProperty(segment, segments))\n return undefined\n segment = \"\"\n state = OPEN_BRACKET\n }\n else if (state === CLOSE_BRACKET) {\n if (segment)\n return undefined\n state = OPEN_BRACKET\n }\n else if (state === undefined) {\n if (segment) {\n if (!pushProperty(segment, segments))\n return undefined\n segment = \"\"\n }\n state = OPEN_BRACKET\n }\n else\n return undefined\n break\n\n case ']':\n if (state === SINGLE_QUOTE || state === DOUBLE_QUOTE)\n segment += c\n else if (state === OPEN_BRACKET) {\n if (!segment)\n return undefined\n if (segment === '*')\n segments.push({ kind: \"wildcard-index\" })\n else\n segments.push({ kind: \"index\", value: parseInt(segment, 10) })\n segment = \"\"\n state = CLOSE_BRACKET\n }\n else if (state === CLOSE_QUOTE) {\n segments.push({ kind: \"key\", value: segment })\n segment = \"\"\n state = CLOSE_BRACKET\n }\n else\n return undefined\n break\n\n case '\\'':\n if (escape || state === DOUBLE_QUOTE)\n segment += c\n else if (state === SINGLE_QUOTE)\n state = CLOSE_QUOTE\n else if (state === OPEN_BRACKET && !segment)\n state = SINGLE_QUOTE\n else\n return undefined\n break\n\n case '\"':\n if (escape || state === SINGLE_QUOTE)\n segment += c\n else if (state === DOUBLE_QUOTE)\n state = CLOSE_QUOTE\n else if (state === OPEN_BRACKET && !segment)\n state = DOUBLE_QUOTE\n else\n return undefined\n break\n\n default:\n if (state === CLOSE_QUOTE)\n return undefined\n if (state === OPEN_BRACKET) {\n if (c === '*') {\n if (segment.length > 0)\n return undefined\n }\n else if (c >= '0' && c <= '9') {\n if (segment === '*')\n return undefined\n }\n else\n return undefined\n }\n segment += c\n break\n }\n\n escape = false\n }\n\n switch (state) {\n case undefined:\n if (segment && !pushProperty(segment, segments))\n return undefined\n break\n case CLOSE_BRACKET:\n if (segment)\n return undefined\n break\n case SLASH:\n if (segment && !pushProperty(segment, segments))\n return undefined\n break\n default:\n return undefined\n }\n\n if (cache != null) {\n if (cache.size >= 500)\n cache.clear()\n cache.set(path, segments.slice())\n }\n\n return segments\n}\n\n\n/**\n * Regular expression to match RegExp special characters.\n * @ignore\n */\nconst reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g\n/**\n * Precompiled RegExp to test for RegExp special characters.\n * @ignore\n */\nconst reHasRegExpChar = RegExp(reRegExpChar.source)\n/**\n * Escapes RegExp special characters in a string.\n * @param s - The string to escape.\n * @returns The escaped string.\n * @ignore\n */\nconst escapeRegExp = (s: string) => s && reHasRegExpChar.test(s) ? s.replace(reRegExpChar, '\\\\$&') : s\n\n/**\n * Converts an observer path (as PathElement array) to a regular expression string for matching actual paths.\n *\n * @param observerPath - The parsed observer path as an array of PathElement.\n * @param currentPath - The current path context for resolving relative paths.\n * @returns A regular expression string, or undefined if the path is invalid.\n * @ignore\n */\nexport function observerPathToRegexp(observerPath: PathElement[] | undefined, currentPath: Path): string | undefined {\n if (observerPath == null || observerPath.length === 0)\n return undefined\n\n if (observerPath[0].kind === 'root')\n observerPath.shift()\n else {\n const parentPath = currentPath.slice(0, -1)\n while (observerPath[0].kind === 'parent') {\n if (parentPath.pop() == null)\n return undefined\n observerPath.shift()\n }\n observerPath.unshift(...parentPath.map(segment => ({ kind: typeof segment === \"number\" ? \"index\" : \"property\", value: segment } as PathElement)))\n }\n\n const regexPath = observerPath.map((segment, index) => {\n switch (segment.kind) {\n case 'wildcard':\n return (index === 0 ? \"\" : \"\\\\.\") + \"[$_\\\\p{ID_Start}][$\\\\p{ID_Continue}]*\"\n case 'double-wildcard':\n return (index === 0 ? \"\" : \"\\\\.\") + \".*\"\n case 'wildcard-index':\n return \"\\\\[[0-9]+\\\\]\"\n case \"key\":\n return `\\\\['${ escapeRegExp(segment.value as string) }'\\\\]`\n case \"index\":\n return Number.isNaN(segment.value) ? \"\\\\[[0-9]+\\\\]\" : `\\\\[${ (segment.value as number).toFixed(0) }\\\\]`\n default: // case \"property\":\n return (index === 0 ? \"\" : \"\\\\.\") + escapeRegExp(segment.value as string)\n }\n })\n\n return `^${ regexPath.join('') }$`\n}\n","import { useEffect } from \"react\"\nimport { getClassConstructor, getMetadataFields } from \"../../yop/Metadata\"\nimport { Path, splitPath } from \"../../yop/ObjectsUtil\"\nimport { ClassConstructor } from \"../../yop/TypesUtil\"\nimport { FormManager, ReformSetValueEvent, SetValueOptions } from \"../FormManager\"\nimport { ObserverCallbackContext, ObserverCallbackOptions, ObserverMetadata, ObserversField, observer } from \"./observer\"\nimport { observerPathToRegexp, splitObserverPath } from \"./observerPath\"\n\n/**\n * Holds observer metadata and its associated path.\n * @template T - The type of the observed value.\n * @ignore\n */\ntype ObserverData<T> = {\n observer: ObserverMetadata<T>\n path: Path\n}\n\n/**\n * Recursively collects all observers from a model and its fields, populating the observers map.\n * @template T\n * @param path - The current path in the model.\n * @param model - The class constructor to inspect.\n * @param observersMap - The map to populate with observer data.\n * @ignore\n */\nfunction collectObservers<T>(path: Path, model: ClassConstructor<any>, observersMap: Map<string, ObserverData<T>[]>) {\n const metadata = getMetadataFields(model) as Record<string, ObserversField>\n\n Object.entries(metadata ?? {}).forEach(([name, fieldMetadata]) => {\n const isArray = fieldMetadata.kind === \"array\"\n \n path.push(name)\n if (isArray)\n path.push(Number.NaN)\n\n fieldMetadata.observers?.forEach(observer => {\n const observerPath = splitObserverPath(observer.path)\n if (observerPath != null) {\n const pathRegExp = observerPathToRegexp(observerPath, path)\n if (pathRegExp != null) {\n let observersData = observersMap.get(pathRegExp)\n if (observersData == null) {\n observersData = []\n observersMap.set(pathRegExp, observersData)\n }\n observersData.push({ observer, path: path.concat() })\n }\n }\n })\n\n const fieldModel = getClassConstructor(fieldMetadata)\n if (fieldModel != null)\n collectObservers(path, fieldModel as ClassConstructor<any>, observersMap)\n \n if (isArray)\n path.pop()\n path.pop()\n })\n}\n\n\n/**\n * Tracks whether setValue was called during observer execution.\n * @ignore\n */\ntype SetValueCalled = { value: boolean }\n\n/**\n * Creates the context object passed to observer callbacks.\n * @template T\n * @param path - The path to the field being observed.\n * @param value - The current value at the path.\n * @param event - The event that triggered the observer.\n * @param setValueCalled - Tracks if setValue was called.\n * @returns The observer callback context.\n * @ignore\n */\nfunction createCallbackContext<T>(path: Path, value: any, event: ReformSetValueEvent, setValueCalled: SetValueCalled): ObserverCallbackContext<T> {\n return {\n path: path,\n observedValue: event.detail.value,\n currentValue: value,\n setValue: (value: any, options?: ObserverCallbackOptions) => {\n const setValueOptions: SetValueOptions = { touch: true, propagate: false }\n if (options != null) {\n if (options.untouch === true)\n setValueOptions.touch = false\n if (options.propagate === true)\n setValueOptions.propagate = true\n }\n event.detail.form.setValue(path, value, setValueOptions)\n setValueCalled.value = true\n },\n event,\n }\n}\n\n/**\n * Recursively calls observer callbacks for matching paths and values.\n * @param observerData - The observer metadata and path.\n * @param value - The current value at the path.\n * @param startPath - The starting path for recursion.\n * @param path - The remaining path to traverse.\n * @param event - The event that triggered the observer.\n * @param setValueCalled - Tracks if setValue was called.\n * @ignore\n */\nfunction callObservers(observerData: ObserverData<any>, value: any, startPath: Path, path: Path, event: ReformSetValueEvent, setValueCalled: SetValueCalled) {\n if (path.length === 0 || value == null)\n return\n\n const pathElement = path[0]\n if (typeof pathElement === \"string\") {\n if (pathElement in value) {\n value = value[pathElement]\n if (path.length === 1)\n observerData.observer.callback(createCallbackContext(startPath.concat(pathElement), value, event, setValueCalled))\n else if (value != null)\n callObservers(observerData, value, startPath.concat(pathElement), path.slice(1), event, setValueCalled)\n }\n }\n else if (Array.isArray(value)) {\n const itemPath = path.slice(1)\n\n if (Number.isNaN(pathElement)) {\n value.forEach((item, itemIndex) => {\n if (item != null) {\n const newStartPath = startPath.concat(itemIndex)\n if (itemPath.length === 0)\n observerData.observer.callback(createCallbackContext(newStartPath, item, event, setValueCalled))\n else\n callObservers(observerData, item, newStartPath, itemPath, event, setValueCalled)\n }\n })\n }\n else {\n const item = value[pathElement]\n if (item != null) {\n const newStartPath = startPath.concat(pathElement)\n if (itemPath.length === 0)\n observerData.observer.callback(createCallbackContext(newStartPath, item, event, setValueCalled))\n else\n callObservers(observerData, item, newStartPath, itemPath, event, setValueCalled)\n }\n }\n }\n}\n\n/**\n * Creates an event listener that triggers observers for a given model.\n * @param model - The class constructor to observe.\n * @returns An event listener for reform events.\n * @ignore\n */\nfunction createReformEventListener(model: ClassConstructor<any>) {\n const observersMap = new Map<string, ObserverData<any>[]>()\n collectObservers([], model, observersMap)\n const observers = Array.from(observersMap.entries()).map(([path, observerData]) => [new RegExp(path, \"u\"), observerData]) as [RegExp, ObserverData<any>[]][]\n\n return ((event: ReformSetValueEvent) => {\n const values = event.detail.form.values\n if (values == null)\n return\n\n const eventPath = splitPath(event.detail.path) ?? []\n const setValueCalled = { value: false }\n \n observers.forEach(([pathRegExp, observersData]) => {\n if (pathRegExp.test(event.detail.path)) {\n observersData.forEach(observerData => {\n let value: any = values\n const startPath: Path = []\n if (observerData.observer.path[0] !== '/') {\n for (let i = 0; i < observerData.path.length && i < eventPath.length; i++) {\n const pathSegment = observerData.path[i]\n const eventSegment = eventPath[i]\n if (pathSegment !== eventSegment && !(Number.isNaN(pathSegment) && (typeof eventSegment === \"number\")))\n break\n startPath.push(eventSegment)\n value = value[eventSegment]\n if (value == null)\n break\n }\n }\n const path = (startPath.length > 0 ? observerData.path.slice(startPath.length) : observerData.path)\n callObservers(observerData, value, startPath, path, event, setValueCalled)\n })\n }\n })\n \n if (setValueCalled.value) {\n event.detail.form.validate()\n event.detail.form.render()\n }\n }) as EventListener\n}\n\n/**\n * React hook to register reform event listeners for {@link observer}s on a model. This hook scans the provided model class for any observer metadata\n * and registers a single event listener on the form manager instance that will trigger the appropriate observer callbacks when relevant fields\n * are updated.\n * \n * There is no need to use this hook if you are using the {@link useForm} hook with a model class, as observers will be automatically registered on\n * the form manager instance.\n *\n * Example usage:\n * ```tsx\n * const form = useForm({\n * initialValues: new MyFormModel(),\n * validationSchema: instance({ of: MyFormModel }),\n * onSubmit: (form) => { ... }\n * })\n * useObservers(MyFormModel, form)\n * ```\n *\n * @template T\n * @param model - The class constructor to scan for observers.\n * @param form - The form manager instance holding the values to observe.\n * @category Observers\n */\nexport function useObservers<T extends object>(model: ClassConstructor<T> | null | undefined, form: FormManager<unknown>) {\n useEffect(() => {\n if (model != null) {\n const reformEventListener = createReformEventListener(model)\n form.addReformEventListener(reformEventListener)\n return () => {\n form.removeReformEventListener(reformEventListener)\n }\n }\n }, [model])\n}","import { useReducer } from \"react\"\n\n/**\n * React hook that returns a function to force a component re-render.\n * Useful for triggering updates in custom hooks or non-stateful logic.\n *\n * @returns A function that, when called, forces the component to re-render.\n * @category Form Management\n */\nexport function useRender(): () => void {\n return useReducer(() => ({}), {})[1] as () => void\n}","import { useMemo } from \"react\"\nimport { instance } from \"../yop/decorators/instance\"\nimport { Path } from \"../yop/ObjectsUtil\"\nimport { isPromise } from \"../yop/TypesUtil\"\nimport { Group } from \"../yop/ValidationContext\"\nimport { FormManager, InternalFormManager } from \"./FormManager\"\nimport { useRender } from \"./useRender\"\nimport { useObservers } from \"./observers/useObservers\"\n\n/**\n * Configuration options for the useForm hook.\n * @template T - The type of the form values.\n * @category Form Management\n */\nexport type FormConfig<T extends object | any[] | null | undefined> = {\n\n /**\n * Initial values for the form. Can be an object, a function returning an object, or a function returning a promise that\n * resolves to an object. Initial values are cloned and stored internally the first time they are neither `null` nor `undefined`.\n * If a function is provided, it will be called on the first render and whenever the config changes, allowing for dynamic\n * initial values. If the function returns a promise, the form will be in a pending state until the promise resolves, at\n * which point the initial values will be set and the form will re-render.\n * \n * @see {@link FormManager.initialValuesPending}\n * @see {@link FormConfig.initialValuesConverter}\n */\n readonly initialValues?: T | (() => T) | (() => Promise<T>) | null\n\n /**\n * Converter function for initial values. This function is called with the initial values whenever they become neither\n * `null` nor `undefined`. It allows for transformation or normalization of the initial values before they are set in the form.\n * @param values - The initial values.\n * @returns The transformed initial values.\n */\n readonly initialValuesConverter?: (values: T) => T\n\n /**\n * The validation schema for the form. This can be a schema object created with the `instance` or `array` decorator.\n * It defines the rules for validating the form values.\n * \n * Example usage:\n * ```tsx\n * const form = useForm({\n * initialValues: new Person(),\n * validationSchema: instance({ of: Person, required: true }),\n * })\n * ```\n */\n readonly validationSchema?: ((_: unknown, context: ClassFieldDecoratorContext<unknown, T>) => void)\n \n /**\n * Path or paths to validate. This can be a single path string or an array of path strings. If specified, only the values\n * at these paths will be validated. If not specified, the entire form values will be validated.\n */\n readonly validationPath?: string | string[]\n\n /**\n * Validation groups to use during validation. This can be a single group or an array of groups. If specified, the validation\n * rules associated with these groups will be applied. If not specified, only the validation rules of the default group will\n * be applied.\n * \n * For example:\n * ```tsx\n * // will apply validation rules of \"group1\":\n * validationGroups: \"group1\"\n * // will apply validation rules of \"group1\" and \"group2\":\n * validationGroups: [\"group1\", \"group2\"]\n * // will apply validation rules of the default group and \"group2\":\n * validationGroups: [undefined, \"group2\"]\n * ```\n */\n readonly validationGroups?: Group\n\n /**\n * Function to determine if a path should be ignored during validation. This function is called with the path being\n * validated and the form manager instance. If it returns `true`, the path will be ignored and no validation will be\n * performed for it.\n * @param path - The path being validated.\n * @param form - The form manager instance.\n * @returns `true` if the path should be ignored, `false` otherwise.\n */\n readonly ignore?: (path: Path, form: FormManager<T>) => boolean\n\n /**\n * Function to determine if the form can be submitted. This function is called with the form manager instance when a submit\n * is attempted. If it returns `true`, the form will be submitted and the `onSubmit` callback will be called. If it returns\n * `false`, the submit will be aborted and the `onSubmit` callback will not be called.\n * @param form - The form manager instance.\n * @returns `true` if the form can be submitted, `false` otherwise.\n */\n readonly submitGuard?: (form: FormManager<T>) => boolean\n\n /**\n * Callback for form submission. This function is called with the form manager instance when the form is submitted and the\n * `submitGuard` (if provided) returns `true`. It is responsible for handling the form submission logic, such as sending\n * the form values to a server or updating application state. The {@link FormManager.submitting} is automatically set to\n * `true` while this function is called. It is the responsibility of the caller to set it back to `false` when the\n * submission process is complete (see {@link FormManager.setSubmitting}).\n * \n * Example usage:\n * ```tsx\n * const form = useForm({\n * initialValues: new Person(),\n * validationSchema: instance({ of: Person, required: true }),\n * onSubmit: (form) => {\n * console.log(\"Form submitted with values:\", form.values)\n * try {\n * // perform submission logic here\n * }\n * finally {\n * form.setSubmitting(false)\n * }\n * }\n * })\n * ```\n * @param form - The form manager instance.\n * @returns void\n */\n readonly onSubmit?: (form: FormManager<T>) => void\n\n /**\n * Whether to dispatch events for observer propagation. If `true`, when a value changes, an event will be dispatched that can\n * be listened to by observers to react to value changes. Default is `true`.\n */\n readonly dispatchEvent?: boolean\n}\n\n/**\n * Type for a class constructor of a model.\n * @category Form Management\n */\nexport type Model<T> = new (...args: any) => NonNullable<T>\n\n\n/**\n * ## First overload signature\n * \n * React hook to create and manage a form with all configuration options available in {@link FormConfig}. This overload allows for the most flexible\n * usage of the `useForm` hook, with full control over initial values, validation schema, submission logic, and more.\n * \n * However, it doesn't register automatically observers listeners, and you need to use the {@link useObservers} hook manually to register observers on\n * the form manager instance, as shown in the example below.\n *\n * Example usage:\n * ```tsx\n * const form = useForm({\n * initialValues: new Person(),\n * validationSchema: instance({ of: Person, required: true }),\n * onSubmit: (form) => {\n * console.log(\"Form submitted with values:\", form.values) \n * form.setSubmitting(false)\n * }\n * })\n * // Optional, if observers are used in the form:\n * useObservers(Person, form)\n * ```\n * @overload\n * @template T - The type of the form values.\n * @param config - The form configuration object.\n * @param deps - Optional dependency list for memoization of the form manager.\n * @returns The form manager instance.\n * @category Form Management\n */\nexport function useForm<T extends object | null | undefined>(config: FormConfig<T>, deps?: React.DependencyList): FormManager<T>\n\n/**\n * ## Second overload signature\n * \n * React hook to create and manage a form with validation, and automatic observer support. This overload allows for a simpler syntax. The initial values\n * will be created by instantiating the provided model class, and the validation schema will be automatically generated using the `instance` decorator with\n * the provided model class and `required: true`.\n *\n * There is no need to use {@link useObservers} here, observers will be automatically registered on the form manager instance\n * for the provided model class. The code example below is strictly equivalent to the one in the other overload signature,\n * but with a simpler syntax.\n * \n * Example usage:\n * ```tsx\n * const form = useForm(Person, (form) => {\n * console.log(\"Form submitted with values:\", form.values) \n * form.setSubmitting(false)\n * })\n * ```\n * \n * @overload\n * @template T - The type of the form values.\n * @param model - The model class constructor.\n * @param onSubmit - Callback for form submission.\n * @param deps - Optional dependency list for memoization of the form manager.\n * @returns The form manager instance.\n * @category Form Management\n */\nexport function useForm<T extends object | null | undefined>(model: Model<T>, onSubmit: (form: FormManager<T>) => void, deps?: React.DependencyList): FormManager<T>\n\n/*\n * Implementation of the useForm hook. Handles both config and model overloads, supports async initial values,\n * and manages form state, validation, and observer eventing. See the overload signatures for usage details.\n */\nexport function useForm(configOrModel: any, onSubmitOrDeps?: any, deps: React.DependencyList = []) {\n\n const model = typeof configOrModel === \"function\" ? configOrModel : undefined\n const render = useRender()\n\n deps = Array.isArray(onSubmitOrDeps) ? onSubmitOrDeps : deps\n const manager = useMemo(() => {\n const newManager = new InternalFormManager(render)\n \n if (typeof configOrModel === \"function\") {\n configOrModel = {\n initialValues: new configOrModel(),\n validationSchema: instance({ of: configOrModel, required: true }),\n onSubmit: onSubmitOrDeps as ((form: FormManager<any>) => void),\n }\n }\n else if (typeof configOrModel.initialValues === \"function\") {\n let initialValues = configOrModel.initialValues()\n if (isPromise(initialValues)) {\n newManager.initialValuesPending = true\n initialValues.then((value: any) => {\n setTimeout(() => {\n configOrModel = { ...newManager.config, initialValues: value }\n newManager.onRender(configOrModel)\n newManager.commitInitialValues()\n newManager.initialValuesPending = false\n render()\n }, 0)\n })\n initialValues = newManager.initialValues\n }\n configOrModel = { ...configOrModel, initialValues }\n }\n \n newManager.onRender(configOrModel)\n return newManager\n }, deps)\n\n // We need this code to normalize configOrModel when useMemo doesn't re-run.\n if (typeof configOrModel === \"function\")\n configOrModel = { ...manager.config, onSubmit: onSubmitOrDeps as ((form: FormManager<any>) => void) }\n else if (typeof configOrModel.initialValues === \"function\")\n configOrModel = { ...configOrModel, initialValues: manager.initialValues }\n\n manager.onRender(configOrModel)\n useObservers(model, manager)\n return manager\n}","import { useRef } from \"react\";\nimport { isPromise } from \"../yop/TypesUtil\";\nimport { ValidationStatus } from \"../yop/ValidationContext\";\nimport { ResolvedConstraints } from \"../yop/Yop\";\nimport { FormManager } from \"./FormManager\";\nimport { useFormContext } from \"./useFormContext\";\nimport { useRender } from \"./useRender\";\n\n/**\n * Represents the state of a form field, including value, validation, and metadata.\n * @template Value - The type of the field value.\n * @template MinMax - The type for min/max constraints.\n * @template Root - The type of the root form values.\n * @category Form Management\n */\nexport type FieldState<Value, MinMax, Root = any> = {\n /** The current value of the field. */\n value: Value | undefined\n /** Whether the field has been touched. */\n touched: boolean\n /** The validation status of the field, if any. See {@link ValidationStatus} for details. */\n status?: ValidationStatus\n /** The form manager instance. See {@link FormManager} for details. */\n form: FormManager<Root>\n /** Function to trigger a re-render of the component that called {@link useFormField} to get this field state. */\n render: () => void\n /** The resolved constraints for the field, if any. See {@link ResolvedConstraints} for details. */\n constraints?: ResolvedConstraints<MinMax>\n}\n\n/**\n * React hook to access and manage the state of a form field, including value, validation status, and constraints.\n * Handles async validation and triggers re-renders as needed.\n * \n * Example usage:\n * ```tsx\n * function MyTextField(props: { path: string }) {\n * const { constraints, status, value, form } = useFormField<string, number>(props.path)\n * // render input with value, display validation status, etc.\n * }\n * ```\n *\n * @template Value - The type of the field value.\n * @template MinMax - The type for min/max constraints.\n * @template Root - The type of the root form values.\n * @param name - The field name or path.\n * @param unsafeMetadata - Whether to use unsafe metadata for constraints.\n * @returns The current state of the field. See {@link FieldState} for details.\n * @category Form Management\n */\nexport function useFormField<Value, MinMax, Root = any>(name: string, unsafeMetadata = false): FieldState<Value, MinMax, Root> {\n const render = useRender()\n const form = useFormContext<Root>()\n const promiseRef = useRef<Promise<unknown>>(undefined)\n\n const status = form.statuses.get(name)\n if (status?.level === \"pending\" && isPromise(status.constraint) && promiseRef.current !== status.constraint) {\n promiseRef.current = status.constraint\n status.constraint.finally(() => {\n if (promiseRef.current === status.constraint) {\n form.updateAsyncStatus(name)\n form.render()\n }\n })\n }\n\n return {\n value: form.getValue<Value>(name),\n touched: form.isTouched(name),\n status,\n form,\n render,\n constraints: form.constraintsAt(name, unsafeMetadata),\n }\n}","import React, { InputHTMLAttributes, useRef } from \"react\"\nimport { InputAttributes, ReformEvents } from \"./InputHTMLProps\"\nimport { useFormField } from \"../useFormField\"\n\n/**\n * @ignore\n */\nexport type BaseCheckboxFieldHTMLAttributes = Omit<InputAttributes<'checkbox'>,\n 'accept' |\n 'alt' |\n 'autocomplete' |\n 'capture' |\n 'dirname' |\n 'height' |\n 'list' |\n 'max' |\n 'maxLength' |\n 'min' |\n 'minLength' |\n 'multiple' |\n 'placeholder' |\n 'readOnly' |\n 'size' |\n 'src' |\n 'step' |\n 'type' |\n 'width'\n>\n\n/**\n * @category Base Inputs Components\n */\nexport type BaseCheckboxFieldProps = BaseCheckboxFieldHTMLAttributes & Omit<ReformEvents<boolean>, 'onBlur'> & {\n render: () => void\n}\n\n/**\n * A base checkbox field component that can be used to create custom checkbox input components connected to the form state.\n * @category Base Inputs Components\n */\nexport function BaseCheckboxField(props: BaseCheckboxFieldProps) {\n const { onChange, render, ...inputProps } = props\n const { value: fieldValue, form } = useFormField<boolean | null, unknown>(props.name)\n\n const inputRef = useRef<HTMLInputElement>(null)\n\n const internalOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const value = event.currentTarget.checked\n if (value !== fieldValue) {\n form.setValue(props.name, value, true)\n onChange?.(value, form)\n }\n }\n\n // If this is the first render or if this input isn't currently edited\n if (inputRef.current == null || inputRef.current !== document.activeElement) {\n const value = fieldValue ?? false\n if (inputRef.current)\n inputRef.current.checked = value\n else\n (inputProps as InputHTMLAttributes<HTMLInputElement>).defaultChecked = value\n }\n\n return (\n <input\n { ...inputProps }\n type=\"checkbox\"\n ref={ inputRef }\n onChange={ internalOnChange }\n />\n )\n}","import { InputHTMLAttributes, useRef } from \"react\"\nimport { useFormField } from \"../useFormField\"\nimport { BaseTextFieldHTMLAttributes } from \"./BaseTextField\"\nimport { ReformEvents } from \"./InputHTMLProps\"\n\n/**\n * @ignore\n */\nexport const localDateToString = (date: Date | null | undefined) => {\n if (date && !isNaN(date.getTime())) {\n const year = date.getFullYear().toString().padStart(4, '0')\n const month = (date.getMonth() + 1).toString().padStart(2, '0')\n const day = date.getDate().toString().padStart(2, '0')\n return `${ year }-${ month }-${ day }`\n }\n return null\n}\n\n/**\n * @ignore\n */\nexport const stringToLocalDate = (value: unknown) => {\n if (value == null || typeof value !== \"string\")\n return null\n const timeIndex = value.indexOf(\"T\")\n if (timeIndex >= 0)\n value = value.substring(0, timeIndex)\n const date = new Date(value + \"T00:00:00\")\n return isNaN(date.getTime()) ? null : date\n}\n\n/**\n * @category Base Inputs Components\n */\ntype BaseDateFieldProps = BaseTextFieldHTMLAttributes & ReformEvents<Date> & {\n render: () => void\n}\n\n/**\n * A base date field component that can be used to create custom date input components connected to the form state.\n * @category Base Inputs Components\n */\nexport function BaseDateField(props: BaseDateFieldProps) {\n\n const { onChange, onBlur, render, ...inputProps } = props\n const { value: fieldValue, form } = useFormField<Date | null, number>(props.name)\n\n const inputRef = useRef<HTMLInputElement>(null)\n\n const getInputValue = (event: React.SyntheticEvent<HTMLInputElement>) => {\n const value = event.currentTarget.value\n return stringToLocalDate(value)\n }\n\n const internalOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (!event.currentTarget.validity.badInput) {\n const value = getInputValue(event)\n if (value !== fieldValue) {\n form.setValue(props.name, value)\n if (form.validateAt(props.name).changed)\n render()\n onChange?.(value, form)\n }\n }\n }\n\n const internalOnBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n const { valid, valueMissing, badInput } = event.currentTarget.validity \n const value = valid ? getInputValue(event) : valueMissing && !badInput ? null : fieldValue ?? null\n form.setValue(props.name, value, true)\n onBlur?.(value, form)\n }\n\n // If this is the first render or if this input isn't currently edited\n if (inputRef.current == null || inputRef.current !== document.activeElement) {\n const value = localDateToString(fieldValue) ?? \"\"\n if (inputRef.current)\n inputRef.current.value = value\n else\n (inputProps as InputHTMLAttributes<HTMLInputElement>).defaultValue = value\n }\n\n return <input { ...inputProps } ref={ inputRef } onChange={ internalOnChange } onBlur={ internalOnBlur } />\n}","import React, { InputHTMLAttributes, useRef } from \"react\"\nimport { InputAttributes, ReformEvents } from \"./InputHTMLProps\"\nimport { useFormField } from \"../..\"\n\n/**\n * @ignore\n */\nexport type BaseRadioFieldHTMLAttributes = Omit<InputAttributes<'radio'>,\n 'accept' |\n 'alt' |\n 'autocomplete' |\n 'capture' |\n 'dirname' |\n 'height' |\n 'list' |\n 'max' |\n 'maxLength' |\n 'min' |\n 'minLength' |\n 'multiple' |\n 'placeholder' |\n 'readOnly' |\n 'size' |\n 'src' |\n 'step' |\n 'type' |\n 'width'\n>\n\n/**\n * @category Base Inputs Components\n */\nexport type BaseRadioFieldProps<V> = BaseRadioFieldHTMLAttributes & ReformEvents<V> & {\n modelValue: V\n render: () => void\n}\n\n/**\n * A base radio field component that can be used to create custom radio input components connected to the form state.\n * @category Base Inputs Components\n */\nexport function BaseRadioField<V = any>(props: BaseRadioFieldProps<V>) {\n const { onChange, onBlur, modelValue, render, ...inputProps } = props\n const { value: fieldValue, form } = useFormField<V | null, number>(props.name)\n\n const inputRef = useRef<HTMLInputElement>(null)\n\n const internalOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (event.currentTarget.checked && modelValue !== fieldValue) {\n form.setValue(props.name, modelValue, true)\n onChange?.(modelValue, form)\n }\n }\n\n // If this is the first render or if this input isn't currently edited\n if (inputRef.current == null || inputRef.current !== document.activeElement) {\n const value = fieldValue === modelValue\n if (inputRef.current)\n inputRef.current.checked = value\n else\n (inputProps as InputHTMLAttributes<HTMLInputElement>).defaultChecked = value\n }\n\n return (\n <input\n { ...inputProps }\n type=\"radio\"\n ref={ inputRef }\n onChange={ internalOnChange }\n />\n )\n}","import React, { DOMAttributes, SelectHTMLAttributes, useRef } from \"react\"\nimport { ReformEvents } from \"./InputHTMLProps\"\nimport { useFormField } from \"../useFormField\"\n\n/**\n * @ignore\n */\nexport type BaseSelectFieldHTMLAttributes = (\n Omit<SelectHTMLAttributes<HTMLSelectElement>,\n // HTMLAttributes\n 'name' |\n\n 'value' |\n\n 'defaultValue' |\n 'defaultChecked' |\n 'suppressContentEditableWarning' |\n 'suppressHydrationWarning' |\n\n 'contentEditable' |\n 'contextMenu' |\n 'hidden' |\n 'is' |\n\n // SelectHTMLAttributes\n 'autoComplete' |\n 'form' | \n 'multiple' |\n\n keyof DOMAttributes<HTMLSelectElement>\n > &\n {\n name: string\n }\n)\n\n/**\n * @category Base Inputs Components\n */\nexport type BaseSelectFieldProps<V> = BaseSelectFieldHTMLAttributes & ReformEvents<V> & {\n modelValues: V[]\n toOptionValue: (modelValue: V) => string\n toOptionContent: (modelValue: V) => string\n toModelValue: (optionValue: string) => V\n render: () => void\n}\n\n/**\n * A base select field component that can be used to create custom select input components connected to the form state.\n * \n * To use it with with a basic { value, label } pair, you can use the following props:\n * ```tsx\n * <BaseSelectField\n * name=\"mySelectId\"\n * modelValues={[ null, \"1\", \"2\" ]}\n * toOptionValue={ modelValue => modelValue ?? \"\" }\n * toOptionContent={ modelValue => modelValue == null ? \"Select...\" : `Option ${modelValue}` }\n * toModelValue={ optionValue => optionValue === \"\" ? null : optionValue }\n * render={ myRenderFunction } />\n * ```\n * @category Base Inputs Components\n */\nexport function BaseSelectField<Value = string>(props: BaseSelectFieldProps<Value | null>) {\n\n const { onChange, onBlur, toModelValue, render, modelValues, toOptionValue, toOptionContent, ...selectProps } = props\n const { value: fieldValue, form } = useFormField<Value | null, number>(props.name)\n\n const selectRef = useRef<HTMLSelectElement>(null)\n\n const internalOnChange = (event: React.ChangeEvent<HTMLSelectElement>) => {\n const value = toModelValue(event.currentTarget.value)\n if (value !== fieldValue) {\n form.setValue(props.name, value, true)\n onChange?.(value, form)\n }\n }\n\n // If this is the first render or if this select isn't currently edited\n if (selectRef.current == null || selectRef.current !== document.activeElement) {\n const value = toOptionValue(fieldValue ?? null)\n if (selectRef.current != null)\n selectRef.current.value = value\n else\n (selectProps as SelectHTMLAttributes<HTMLSelectElement>).defaultValue = value\n }\n\n return (\n <select\n { ...selectProps }\n ref={ selectRef }\n onChange={ internalOnChange }\n >\n { modelValues.map(modelValue => {\n const optionValue = toOptionValue(modelValue)\n return (\n <option key={ optionValue } value={ optionValue }>\n { toOptionContent(modelValue)}\n </option>\n )\n })}\n </select>\n )\n}","import React, { DOMAttributes, TextareaHTMLAttributes, useRef } from \"react\"\nimport { useFormField } from \"../useFormField\"\nimport { ReformEvents } from \"./InputHTMLProps\"\n\n/**\n * @ignore\n */\nexport type BaseTextAreaFieldHTMLAttributes = (\n Omit<TextareaHTMLAttributes<HTMLTextAreaElement>,\n // HTMLAttributes\n 'name' |\n\n 'value' |\n\n 'defaultValue' |\n 'defaultChecked' |\n 'suppressContentEditableWarning' |\n 'suppressHydrationWarning' |\n\n 'contentEditable' |\n 'contextMenu' |\n 'hidden' |\n 'is' |\n\n // TextareaHTMLAttributes\n 'autoComplete' |\n 'dirName' |\n 'form' | \n\n keyof DOMAttributes<HTMLTextAreaElement>\n > &\n {\n name: string\n }\n)\n\n/**\n * @category Base Inputs Components\n */\nexport type BaseTextAreaFieldProps = BaseTextAreaFieldHTMLAttributes & ReformEvents<string> & {\n render: () => void\n}\n\n/**\n * A base text area component that can be used to create custom text area input components connected to the form state.\n * @category Base Inputs Components\n */\nexport function BaseTextAreaField(props: BaseTextAreaFieldProps) {\n\n const { render, onChange, onBlur, ...textAreaProps } = props\n const { value: fieldValue, form } = useFormField<string | null, number>(props.name)\n\n const textAreaRef = useRef<HTMLTextAreaElement>(null)\n\n const internalOnChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n const value = event.currentTarget.value || null\n if (value !== fieldValue) {\n form.setValue(props.name, value)\n form.validateAt(props.name) && render()\n onChange?.(value, form)\n }\n }\n\n const internalOnBlur = (event: React.FocusEvent<HTMLTextAreaElement>) => {\n const value = event.currentTarget.value || null\n form.setValue(props.name, value, true)\n onBlur?.(value, form)\n }\n\n // If this is the first render or if this textarea isn't currently edited\n if (textAreaRef.current == null || textAreaRef.current !== document.activeElement) {\n const value = fieldValue ?? \"\"\n if (textAreaRef.current != null)\n textAreaRef.current.value = value\n else\n (textAreaProps as TextareaHTMLAttributes<HTMLTextAreaElement>).defaultValue = value\n }\n\n return (\n <textarea\n { ...textAreaProps }\n ref={ textAreaRef }\n onChange={ internalOnChange }\n onBlur={ internalOnBlur }\n />\n )\n}","import React, { InputHTMLAttributes, useRef } from \"react\"\nimport { InputAttributes, ReformEvents } from \"./InputHTMLProps\"\nimport { useFormField } from \"../useFormField\"\n\n/**\n * @ignore\n */\nexport interface InputSelection {\n start: number | null\n end: number | null\n direction?: \"forward\" | \"backward\" | \"none\"\n}\n\n/**\n * @ignore\n */\nexport type BaseTextFieldHTMLAttributes = Omit<InputAttributes<\"text\" | \"search\" | \"number\" | \"date\" | \"email\" | \"password\" | \"tel\" | \"time\">,\n 'accept' |\n 'alt' |\n 'capture' |\n 'height' |\n 'multiple' |\n 'src' |\n 'step' |\n 'width'\n>\n\n/**\n * @category Base Inputs Components\n */\nexport type BaseTextFieldProps<V> = BaseTextFieldHTMLAttributes & ReformEvents<V> & {\n toModelValue?: (value: string) => V | null\n toTextValue?: (value: V | null) => string\n acceptInputValue?: (value: string) => boolean\n formatDisplayedValue?: (value: string) => string\n formatOnEdit?: boolean\n render: () => void\n}\n\n/**\n * A base text field component that can be used to create custom text input components connected to the form state. It handles change and blur events,\n * converts between the input value and the model value using the provided `toModelValue` and `toTextValue` functions, and calls the provided `render`\n * function to update the form state when the value changes. It also supports an `acceptInputValue` function to validate the input value on each change\n * and a `formatDisplayedValue` function to format the displayed value while editing.\n * @category Base Inputs Components\n */\nexport function BaseTextField<Value = string>(props: BaseTextFieldProps<Value>) {\n\n const { onChange, onBlur, toModelValue, toTextValue, acceptInputValue, formatDisplayedValue, formatOnEdit, render, ...inputProps } = props\n const { value: fieldValue, form } = useFormField<Value | null, number>(props.name)\n\n const inputRef = useRef<HTMLInputElement>(null)\n const previousInputValue = useRef('')\n const previousInputSelection = useRef<InputSelection>({ start: null, end: null })\n\n const getInputValue = (event: React.SyntheticEvent<HTMLInputElement>) => {\n const value = event.currentTarget.value.replace(/\\0/g, '')\n if (toModelValue)\n return toModelValue(value)\n return value === '' ? null : value as Value\n }\n\n const internalOnSelect = (event: React.FormEvent<HTMLInputElement>) => {\n const target = event.currentTarget\n \n previousInputSelection.current = {\n start: target.selectionStart,\n end: target.selectionEnd,\n direction: target.selectionDirection ?? undefined\n }\n \n // format displayed value when cursor is moved at the end of typed text\n if (formatOnEdit !== false && formatDisplayedValue && target.selectionStart === target.value.length) {\n const formattedValue = formatDisplayedValue(target.value)\n if (target.value !== formattedValue)\n target.value = formattedValue\n }\n }\n\n const internalOnInput = (event: React.FormEvent<HTMLInputElement>) => {\n const target = event.currentTarget\n \n // Discard changes if it doesn't conform to acceptInputValue (could also be handled by a beforeInput event)\n if (acceptInputValue?.(target.value) === false) {\n target.value = previousInputValue.current\n const selection = previousInputSelection.current!\n target.setSelectionRange(selection.start, selection.end, selection.direction)\n }\n // format displayed value when cursor is at the end of typed text\n else if (formatOnEdit !== false && formatDisplayedValue && target.selectionStart === target.value.length) {\n const formattedValue = formatDisplayedValue(target.value)\n if (target.value !== formattedValue)\n target.value = formattedValue\n }\n }\n\n const internalOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n previousInputValue.current = event.currentTarget.value\n const value = getInputValue(event)\n if (value !== fieldValue) {\n form.setValue(props.name, value)\n if (form.validateAt(props.name).changed)\n render()\n onChange?.(value, form)\n }\n }\n\n const internalOnBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n const value = getInputValue(event)\n form.setValue(props.name, value, true)\n onBlur?.(value, form)\n }\n\n // If this is the first render or if this input isn't currently edited\n if (inputRef.current == null || inputRef.current !== document.activeElement) {\n const convertedValue = toTextValue?.(fieldValue ?? null) ?? String(fieldValue ?? '')\n const value = formatDisplayedValue?.(convertedValue) ?? convertedValue\n if (inputRef.current)\n inputRef.current.value = value\n else\n (inputProps as InputHTMLAttributes<HTMLInputElement>).defaultValue = value\n previousInputValue.current = value\n }\n\n return (\n <input\n { ...inputProps }\n ref={ inputRef }\n onSelect={ internalOnSelect }\n onInput={ internalOnInput }\n onChange={ internalOnChange }\n onBlur={ internalOnBlur }\n />\n )\n}\n","import { Constraint, validateConstraint } from \"./Constraint\"\nimport { InternalValidationContext, ValuedContext } from \"../ValidationContext\"\n\n/**\n * Interface for a constraint that checks if a value is one of a set of allowed values.\n * @template Value - The type of the value being validated.\n * @template Parent - The type of the parent object.\n * @property oneOf - Constraint for allowed values, if any.\n * @category Shared Constraints\n */\nexport interface OneOfConstraint<Value, Parent = unknown> {\n oneOf?: Constraint<NonNullable<Value>, NoInfer<NonNullable<Value>>[], Parent>\n}\n\n/**\n * Validates the oneOf constraint for a value.\n * @template Value - The type of the value being validated.\n * @template OneOfType - The type for the allowed values array.\n * @template Parent - The type of the parent object.\n * @param context - The validation context.\n * @param constraints - The oneOf constraint to validate.\n * @param isConstraintValue - Type guard for the allowed values array.\n * @param equals - Optional equality function for comparing values.\n * @returns True if the value is one of the allowed values, false otherwise.\n * @ignore\n */\nexport function validateOneOfConstraint<Value, OneOfType extends NoInfer<NonNullable<Value>>[], Parent>(\n context: InternalValidationContext<Value, Parent>,\n constraints: OneOfConstraint<Value, Parent>,\n isConstraintValue: (value: any) => value is OneOfType,\n equals?: (value1: NonNullable<Value>, value2: NonNullable<Value>) => boolean\n) {\n return validateConstraint(\n context as ValuedContext<Value, Parent>,\n constraints,\n \"oneOf\",\n isConstraintValue,\n (value, array) => equals == null ? array.includes(value) : array.some((item) => equals(value, item))\n )\n}\n","import { CommonConstraints, validateTypeConstraint } from \"../constraints/CommonConstraints\"\nimport { OneOfConstraint, validateOneOfConstraint } from \"../constraints/OneOfConstraint\"\nimport { TestConstraint, validateTestConstraint } from \"../constraints/TestConstraint\"\nimport { isBoolean, isBooleanArray } from \"../TypesUtil\"\nimport { InternalValidationContext } from \"../ValidationContext\"\nimport { fieldValidationDecorator, Groups } from \"../Metadata\"\n\n/**\n * Type for a boolean value, which can be true, false, null, or undefined.\n * @ignore\n */\nexport type BooleanValue = boolean | null | undefined\n\n/**\n * Interface for boolean field constraints, combining common, oneOf, and test constraints.\n * @template Value - The type of the boolean value.\n * @template Parent - The type of the parent object.\n * @see {@link CommonConstraints}\n * @see {@link OneOfConstraint}\n * @see {@link TestConstraint}\n * @category Property Decorators\n */\nexport interface BooleanConstraints<Value extends BooleanValue, Parent> extends\n CommonConstraints<Value, Parent>,\n OneOfConstraint<Value, Parent>,\n TestConstraint<Value, Parent> {\n}\n\n/**\n * Validates a boolean field against its constraints.\n * @template Value - The type of the boolean value.\n * @template Parent - The type of the parent object.\n * @param context - The validation context.\n * @param constraints - The boolean constraints to validate.\n * @returns True if all constraints pass, false otherwise.\n * @ignore\n */\nfunction validateBoolean<Value extends BooleanValue, Parent>(context: InternalValidationContext<Value, Parent>, constraints: BooleanConstraints<Value, Parent>) {\n return (\n validateTypeConstraint(context, isBoolean, \"boolean\") &&\n validateOneOfConstraint(context, constraints, isBooleanArray) &&\n validateTestConstraint(context, constraints)\n )\n}\n\n/**\n * Decorator for applying validation rules to a boolean field.\n * \n * Example usage:\n * ```tsx\n * class Person {\n * @boolean({ required: true, oneOf: [[true], \"Must be an adult\"] })\n * adult: boolean | null = null\n * }\n * const form = useForm(Person, ...)\n * \n * // the boolean decorator can also be used as a function to allow standalone validation:\n * Yop.validate(false, boolean({ oneOf: [true] })) // error: \"Must be one of: true\"\n * ```\n * @template Value - The type of the boolean value.\n * @template Parent - The type of the parent object.\n * @param constraints - The boolean constraints to apply.\n * @param groups - Optional validation groups.\n * @returns A field decorator function with validation.\n * @category Property Decorators\n */\nexport function boolean<Value extends BooleanValue, Parent>(constraints?: BooleanConstraints<Value, Parent>, groups?: Groups<BooleanConstraints<Value, Parent>>) {\n return fieldValidationDecorator(\"boolean\", constraints ?? {}, groups, validateBoolean)\n}\n","import { CommonConstraints, validateTypeConstraint } from \"../constraints/CommonConstraints\"\nimport { MinMaxConstraints, validateMinMaxConstraints } from \"../constraints/MinMaxConstraints\"\nimport { OneOfConstraint, validateOneOfConstraint } from \"../constraints/OneOfConstraint\"\nimport { TestConstraint, validateTestConstraint } from \"../constraints/TestConstraint\"\nimport { isDate, isDateArray } from \"../TypesUtil\"\nimport { InternalValidationContext } from \"../ValidationContext\"\nimport { fieldValidationDecorator, Groups } from \"../Metadata\"\n\n/**\n * Type for a date value, which can be a Date object, null, or undefined.\n * @ignore\n */\nexport type DateValue = Date | null | undefined\n\n/**\n * Interface for date field constraints, combining common, min/max, oneOf, and test constraints.\n * @template Value - The type of the date value.\n * @template Parent - The type of the parent object.\n * @see {@link CommonConstraints}\n * @see {@link MinMaxConstraints}\n * @see {@link OneOfConstraint}\n * @see {@link TestConstraint}\n * @category Property Decorators\n */\nexport interface DateConstraints<Value extends DateValue, Parent> extends\n CommonConstraints<Value, Parent>,\n MinMaxConstraints<Value, Date, Parent>,\n OneOfConstraint<Value, Parent>,\n TestConstraint<Value, Parent> {\n}\n\n/**\n * Validates a date field against its constraints.\n * @template Value - The type of the date value.\n * @template Parent - The type of the parent object.\n * @param context - The validation context.\n * @param constraints - The date constraints to validate.\n * @returns True if all constraints pass, false otherwise.\n * @ignore\n */\nfunction validateDate<Value extends DateValue, Parent>(context: InternalValidationContext<Value, Parent>, constraints: DateConstraints<Value, Parent>) {\n return (\n validateTypeConstraint(context, isDate, \"date\") &&\n validateMinMaxConstraints(context, constraints, isDate, (value, min) => value >= min, (value, max) => value <= max) &&\n validateOneOfConstraint(context, constraints, isDateArray, (date1, date2) => date1.getTime() === date2.getTime()) &&\n validateTestConstraint(context, constraints)\n )\n}\n\n/**\n * Decorator for applying validation rules to a Date field.\n * \n * Example usage:\n * ```tsx\n * class Person {\n * @date({ required: true, min: new Date(\"1900-01-01\") })\n * dateOfBirth: Date | null = null\n * }\n * const form = useForm(Person, ...)\n * \n * // the date decorator can also be used as a function to allow standalone validation:\n * Yop.validate(null, date({ required: true })) // error: \"Required field\"\n * ```\n * @template Value - The type of the date value.\n * @template Parent - The type of the parent object.\n * @param constraints - The date constraints to apply.\n * @param groups - Optional validation groups.\n * @returns A field decorator function with validation.\n * @category Property Decorators\n */\nexport function date<Value extends DateValue, Parent>(constraints?: DateConstraints<Value, Parent>, groups?: Groups<DateConstraints<Value, Parent>>) {\n return fieldValidationDecorator(\"date\", constraints ?? {}, groups, validateDate, isDate)\n}\n","import { CommonConstraints, validateTypeConstraint } from \"../constraints/CommonConstraints\"\nimport { Constraint, Message, validateConstraint } from \"../constraints/Constraint\"\nimport { MinMaxConstraints, validateMinMaxConstraints } from \"../constraints/MinMaxConstraints\"\nimport { OneOfConstraint, validateOneOfConstraint } from \"../constraints/OneOfConstraint\"\nimport { TestConstraint, validateTestConstraint } from \"../constraints/TestConstraint\"\nimport { isNumber, isRegExp, isString, isStringArray } from \"../TypesUtil\"\nimport { InternalValidationContext, ValuedContext } from \"../ValidationContext\"\nimport { fieldValidationDecorator, Groups } from \"../Metadata\"\n\n/**\n * Type for a string value, which can be a string, null, or undefined.\n * @ignore\n */\nexport type StringValue = string | null | undefined\n\n/**\n * Interface for string field constraints, combining common, min/max, oneOf, test, and match constraints.\n * @template Value - The type of the string value.\n * @template Parent - The type of the parent object.\n * @property match - Constraint for matching a regular expression.\n * @see {@link CommonConstraints}\n * @see {@link MinMaxConstraints}\n * @see {@link OneOfConstraint}\n * @see {@link TestConstraint}\n * @category Property Decorators\n */\nexport interface StringConstraints<Value extends StringValue, Parent> extends\n CommonConstraints<Value, Parent>,\n MinMaxConstraints<Value, number, Parent>,\n OneOfConstraint<Value, Parent>,\n TestConstraint<Value, Parent> {\n /**\n * Constraint for matching a regular expression. The constraint value can be a RegExp, a function that returns a RegExp.\n */\n match?: Constraint<NonNullable<Value>, RegExp, Parent>\n}\n\n/**\n * Validates a string field against its constraints.\n * @template Value - The type of the string value.\n * @template Parent - The type of the parent object.\n * @param context - The validation context.\n * @param constraints - The string constraints to validate.\n * @param defaultRegexp - Optional default regular expression for matching.\n * @param defaultMatchMessage - Optional default error message for match failures.\n * @param type - Optional type name for error reporting.\n * @returns True if all constraints pass, false otherwise.\n * @ignore\n */\nexport function validateString<Value extends StringValue, Parent>(\n context: InternalValidationContext<Value, Parent>,\n constraints: StringConstraints<Value, Parent>,\n defaultRegexp?: RegExp,\n defaultMatchMessage?: Message<Value, Parent>,\n type?: string\n) {\n return (\n validateTypeConstraint(context, isString, type ?? \"string\") &&\n validateMinMaxConstraints(context, constraints, isNumber, (value, min) => value.length >= min, (value, max) => value.length <= max) &&\n validateConstraint(context as ValuedContext<Value, Parent>, constraints, \"match\", isRegExp, (value, re) => re.test(value), defaultRegexp, defaultMatchMessage) &&\n validateOneOfConstraint(context, constraints, isStringArray) &&\n validateTestConstraint(context, constraints)\n )\n}\n\n/**\n * Decorator for applying validation rules to a string field. A required string field can be an empty string, but neither `null` nor `undefined`.\n * To enforce non-empty strings, use the `min` constraint with a value of 1.\n * \n * Example usage:\n * ```tsx\n * class Person {\n * @string({ required: true, min: 1 })\n * name: string | null = null\n * }\n * const form = useForm(Person, ...)\n * \n * // the string decorator can also be used as a function to allow standalone validation:\n * Yop.validate(\"\", string({ required: true, min: 1 })) // error: \"Minimum 1 character\"\n * ```\n * @template Value - The type of the string value.\n * @template Parent - The type of the parent object.\n * @param constraints - The string constraints to apply.\n * @param groups - Optional validation groups.\n * @returns A field decorator function with validation.\n * @category Property Decorators\n */\nexport function string<Value extends StringValue, Parent>(constraints?: StringConstraints<Value, Parent>, groups?: Groups<StringConstraints<Value, Parent>>) {\n return fieldValidationDecorator(\"string\", constraints ?? {}, groups, validateString, isNumber)\n}\n","import { Message } from \"../constraints/Constraint\"\nimport { InternalValidationContext } from \"../ValidationContext\"\nimport { fieldValidationDecorator, Groups } from \"../Metadata\"\nimport { StringConstraints, StringValue, validateString } from \"./string\"\nimport { isNumber } from \"../TypesUtil\"\n\n/**\n * Interface for email field constraints, extending string constraints but omitting 'match'.\n * @template Value - The type of the string value.\n * @template Parent - The type of the parent object.\n * @property formatError - Custom error message for invalid email format.\n * @see {@link StringConstraints}\n * @category Property Decorators\n */\nexport interface EmailConstraints<Value extends StringValue, Parent> extends\n Omit<StringConstraints<Value, Parent>, \"match\"> {\n /**\n * Custom error message for invalid email format. `formatError` can be a {@link Message} or a function that returns a {@link Message}.\n * @see {@link emailRegex}\n */\n formatError?: Message<Value, Parent>\n}\n\n/**\n * Regular expression for validating email addresses (RFC 5322 compliant).\n * @ignore\n */\nexport const emailRegex = /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i\n\n/**\n * Validates an email field against its constraints and the email regex.\n * @template Value - The type of the string value.\n * @template Parent - The type of the parent object.\n * @param context - The validation context.\n * @param constraints - The email constraints to validate.\n * @returns True if the value is a valid email, false otherwise.\n * @ignore\n */\nexport function validateEmail<Value extends StringValue, Parent>(context: InternalValidationContext<Value, Parent>, constraints: EmailConstraints<Value, Parent>) {\n return validateString(context, constraints, emailRegex, constraints.formatError, \"email\")\n}\n\n/**\n * Decorator for applying validation rules to an email field. Emails are validated against a standard email regex pattern (RFC 5322 compliant).\n * \n * Example usage:\n * ```tsx\n * class Person {\n * @email({ required: true, formatError: \"Invalid email address\" })\n * email: string | null = null\n * }\n * const form = useForm(Person, ...)\n * \n * // the email decorator can also be used as a function to allow standalone validation:\n * Yop.validate(null, email({ required: true })) // error: \"Required field\"\n * ```\n * @template Value - The type of the string value.\n * @template Parent - The type of the parent object.\n * @param constraints - The email constraints to apply.\n * @param groups - Optional validation groups.\n * @returns A field decorator function with validation.\n * @category Property Decorators\n */\nexport function email<Value extends StringValue, Parent>(constraints?: EmailConstraints<Value, Parent>, groups?: Groups<EmailConstraints<Value, Parent>>) {\n return fieldValidationDecorator(\"email\", constraints ?? {}, groups, validateEmail, isNumber)\n}\n","import { CommonConstraints, validateTypeConstraint } from \"../constraints/CommonConstraints\"\nimport { MinMaxConstraints, validateMinMaxConstraints } from \"../constraints/MinMaxConstraints\"\nimport { TestConstraint, validateTestConstraint } from \"../constraints/TestConstraint\"\nimport { isFile, isNumber } from \"../TypesUtil\"\nimport { InternalValidationContext } from \"../ValidationContext\"\nimport { fieldValidationDecorator, Groups } from \"../Metadata\"\n\n/**\n * Type for a file value, which can be a File object, null, or undefined.\n * @ignore\n */\nexport type FileValue = File | null | undefined\n\n/**\n * Interface for file field constraints, combining common, min/max, and test constraints.\n * @template Value - The type of the file value.\n * @template Parent - The type of the parent object.\n * @see {@link CommonConstraints}\n * @see {@link MinMaxConstraints}\n * @see {@link TestConstraint}\n * @category Property Decorators\n */\nexport interface FileConstraints<Value extends FileValue, Parent> extends\n CommonConstraints<Value, Parent>,\n MinMaxConstraints<Value, number, Parent>,\n TestConstraint<Value, Parent> {\n}\n\n/**\n * Validates a file field against its constraints.\n * @template Value - The type of the file value.\n * @template Parent - The type of the parent object.\n * @param context - The validation context.\n * @param constraints - The file constraints to validate.\n * @returns True if all constraints pass, false otherwise.\n * @ignore\n */\nfunction validateFile<Value extends FileValue, Parent>(context: InternalValidationContext<Value, Parent>, constraints: FileConstraints<Value, Parent>) {\n return (\n validateTypeConstraint(context, isFile, \"file\") &&\n validateMinMaxConstraints(context, constraints, isNumber, (value, min) => value.size >= min, (value, max) => value.size <= max) &&\n validateTestConstraint(context, constraints)\n )\n}\n\n/**\n * Decorator for applying validation rules to a File field.\n * \n * Example usage:\n * ```tsx\n * class Person {\n * @file({ required: true, min: [1024, \"Picture size must be at least 1KB\"] })\n * profilePicture: File | null = null\n * }\n * const form = useForm(Person, ...)\n * \n * // the file decorator can also be used as a function to allow standalone validation:\n * Yop.validate(null, file({ required: true })) // error: \"Required field\"\n * ```\n * @template Value - The type of the file value.\n * @template Parent - The type of the parent object.\n * @param constraints - The file constraints to apply.\n * @param groups - Optional validation groups.\n * @returns A field decorator function with validation.\n * @category Property Decorators\n */\nexport function file<Value extends FileValue, Parent>(constraints?: FileConstraints<Value, Parent>, groups?: Groups<FileConstraints<Value, Parent>>) {\n return fieldValidationDecorator(\"file\", constraints ?? {}, groups, validateFile, isNumber)\n}\n","import { Constructor } from \"../TypesUtil\"\nimport { Yop } from \"../Yop\"\nimport { ArrayConstraints } from \"./array\"\nimport { InstanceConstraints } from \"./instance\"\n\n/**\n * Class decorator to register a class with a unique identifier in the Yop registry. It can be used when you need to reference\n * classes by an identifier to prevent circular references.\n * \n * Example usage:\n * ```tsx\n * @id(\"Person\")\n * class Person {\n * \n * @instance({ of: \"Person\" }) // circular reference to itself using the class id\n * friend: Person | null = null\n * \n * @array({ of: \"Person\" }) // circular reference to itself using the class id\n * friends: Person[] | null = null\n * }\n * ```\n * \n * @template Type - The type of the class instance.\n * @template Class - The constructor type of the class.\n * @param id - The unique identifier for the class.\n * @returns A class decorator function that registers the class in the Yop registry.\n * @see {@link InstanceConstraints}\n * @see {@link ArrayConstraints}\n * @category Class Decorators\n */\nexport function id<Type extends object, Class extends Constructor<Type>>(id: string) {\n return function decorateClass(target: Class, _: ClassDecoratorContext<Class>) {\n Yop.registerClass(id, target)\n }\n}\n","import { CommonConstraints, validateTypeConstraint } from \"../constraints/CommonConstraints\"\nimport { MinMaxConstraints, validateMinMaxConstraints } from \"../constraints/MinMaxConstraints\"\nimport { OneOfConstraint, validateOneOfConstraint } from \"../constraints/OneOfConstraint\"\nimport { TestConstraint, validateTestConstraint } from \"../constraints/TestConstraint\"\nimport { isNumber, isNumberArray } from \"../TypesUtil\"\nimport { InternalValidationContext } from \"../ValidationContext\"\nimport { fieldValidationDecorator, Groups } from \"../Metadata\"\n\n/**\n * Type for a number value, which can be a number, null, or undefined.\n * @ignore\n */\nexport type NumberValue = number | null | undefined\n\n/**\n * Interface for number field constraints, combining common, min/max, oneOf, and test constraints.\n * @template Value - The type of the number value.\n * @template Parent - The type of the parent object.\n * @see {@link CommonConstraints}\n * @see {@link MinMaxConstraints}\n * @see {@link OneOfConstraint}\n * @see {@link TestConstraint}\n * @category Property Decorators\n */\nexport interface NumberConstraints<Value extends NumberValue, Parent> extends\n CommonConstraints<Value, Parent>,\n MinMaxConstraints<Value, number, Parent>,\n OneOfConstraint<Value, Parent>,\n TestConstraint<Value, Parent> {\n}\n\n/**\n * Validates a number field against its constraints.\n * @template Value - The type of the number value.\n * @template Parent - The type of the parent object.\n * @param context - The validation context.\n * @param constraints - The number constraints to validate.\n * @returns True if all constraints pass, false otherwise.\n * @ignore\n */\nfunction validateNumber<Value extends NumberValue, Parent>(context: InternalValidationContext<Value, Parent>, constraints: NumberConstraints<Value, Parent>) {\n return (\n validateTypeConstraint(context, isNumber, \"number\") &&\n validateMinMaxConstraints(context, constraints, isNumber, (value, min) => value >= min, (value, max) => value <= max) &&\n validateOneOfConstraint(context, constraints, isNumberArray) &&\n validateTestConstraint(context, constraints)\n )\n}\n\n/**\n * Decorator for applying validation rules to a number field.\n * \n * Example usage:\n * ```tsx\n * class Person {\n * @number({ required: true, min: 0 })\n * age: number | null = null\n * }\n * const form = useForm(Person, ...)\n * \n * // the number decorator can also be used as a function to allow standalone validation:\n * Yop.validate(-1, number({ required: true, min: 0 })) // error: \"Must be greater or equal to 0\"\n * ```\n * @template Value - The type of the number value.\n * @template Parent - The type of the parent object.\n * @param constraints - The number constraints to apply.\n * @param groups - Optional validation groups.\n * @returns A field decorator function with validation.\n * @category Property Decorators\n */\nexport function number<Value extends NumberValue, Parent>(constraints?: NumberConstraints<Value, Parent>, groups?: Groups<NumberConstraints<Value, Parent>>) {\n return fieldValidationDecorator(\"number\", constraints ?? {}, groups, validateNumber, isNumber)\n}\n","import { TestConstraintFunction } from \"../constraints/TestConstraint\"\nimport { initClassConstraints } from \"../Metadata\"\nimport { Constructor } from \"../TypesUtil\"\n\n/**\n * Utility type to extract the instance type from a constructor.\n * @template Class - The constructor type.\n * @category Class Decorators\n */\nexport type InstanceType<Class> = Class extends Constructor<infer Type> ? Type : never\n\n/**\n * Class decorator to add a test constraint function to a class for validation. The test function will be called with the\n * class instance after all field validations have passed, allowing for complex custom validation logic that depends on \n * the entire object state.\n * \n * Example usage:\n * ```tsx\n * @test(credentials => credentials.password === credentials.confirmPassword ? true : \"Passwords do not match\")\n * class Credentials {\n * @string({ required: true, min: 8 })\n * username: string | null = null\n * @string({ required: true, min: 8, test: checkPasswordStrength })\n * password: string | null = null\n * @string({ required: true, min: 8 })\n * confirmPassword: string | null = null\n * }\n * const form = useForm(Credentials, ...)\n * ```\n * @template Class - The constructor type of the class.\n * @param test - The test constraint function to apply to the class instance.\n * @returns A class decorator function that sets the test constraint.\n * @see {@link TestConstraintFunction}\n * @category Class Decorators\n */\nexport function test<Class extends Constructor>(test: TestConstraintFunction<InstanceType<Class>>) {\n return function decorateClass(_: Class, context: ClassDecoratorContext<Class>) {\n const classConstraints = initClassConstraints(context.metadata)\n classConstraints.test = test\n }\n}\n","import { InternalValidationContext } from \"../ValidationContext\"\nimport { fieldValidationDecorator, Groups } from \"../Metadata\"\nimport { StringValue } from \"./string\"\nimport { MinMaxConstraints, validateMinMaxConstraints } from \"../constraints/MinMaxConstraints\"\nimport { CommonConstraints, validateTypeConstraint } from \"../constraints/CommonConstraints\"\nimport { isFunction, isString, isStringArray } from \"../TypesUtil\"\nimport { OneOfConstraint, validateOneOfConstraint } from \"../constraints/OneOfConstraint\"\nimport { TestConstraint, validateTestConstraint } from \"../constraints/TestConstraint\"\nimport { Message } from \"../constraints/Constraint\"\n\n/**\n * Interface for time field constraints, combining common, min/max, oneOf, and test constraints.\n * @template Value - The type of the string value.\n * @template Parent - The type of the parent object.\n * @property formatError - Optional custom error message for invalid time format.\n * @see {@link CommonConstraints}\n * @see {@link MinMaxConstraints}\n * @see {@link OneOfConstraint}\n * @see {@link TestConstraint}\n * @category Property Decorators\n */\nexport interface TimeConstraints<Value extends StringValue, Parent> extends\n CommonConstraints<Value, Parent>,\n MinMaxConstraints<Value, string, Parent>,\n OneOfConstraint<Value, Parent>,\n TestConstraint<Value, Parent> {\n /**\n * Optional custom error message for invalid time format. `formatError` can be a {@link Message} or a function that returns a {@link Message}.\n * @see {@link timeRegex}\n */\n formatError?: Message<Value, Parent>\n}\n\n/**\n * Regular expression for validating time strings in the format HH:mm[:ss[.sss]].\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Date_and_time_formats#time_strings\n * @ignore\n */\nexport const timeRegex = /^([01][0-9]|2[0-3]):([0-5][0-9])(?::([0-5][0-9])(?:\\.([0-9]{1,3}))?)?$/\n\n/**\n * Converts a time string (HH:mm[:ss[.sss]]) to milliseconds since midnight.\n * @param time - The time string to convert.\n * @returns The number of milliseconds since midnight, or undefined if invalid.\n * @ignore\n */\nexport function timeToMillis(time: string) {\n const matches = timeRegex.exec(time)\n return (\n matches != null ?\n (+matches[1] * 3600 * 1000) + (+matches[2] * 60 * 1000) + (+(matches[3] ?? 0) * 1000) + (+(matches[4] ?? 0)) :\n undefined\n )\n}\n\n/**\n * Maximum number of milliseconds in a day (23:59:59.999).\n * @ignore\n */\nconst MAX_MILLIS = (24 * 3600 * 1000) - 1\n\n/**\n * Validates a time field against its constraints.\n * @template Value - The type of the string value.\n * @template Parent - The type of the parent object.\n * @param context - The validation context.\n * @param constraints - The time constraints to validate.\n * @returns True if all constraints pass, false otherwise.\n * @ignore\n */\nexport function validateTime<Value extends StringValue, Parent>(context: InternalValidationContext<Value, Parent>, constraints: TimeConstraints<Value, Parent>) {\n if (!validateTypeConstraint(context, isString, \"time\"))\n return false\n \n const millis = timeToMillis(context.value!)\n if (millis == null) {\n const message = isFunction(constraints.formatError) ? constraints.formatError(context) : constraints.formatError\n return context.setStatus(\"match\", timeRegex, message) == null\n }\n\n return (\n validateMinMaxConstraints(context, constraints, isString, (_, min) => millis >= (timeToMillis(min) ?? 0), (_, max) => millis <= (timeToMillis(max) ?? MAX_MILLIS)) &&\n validateOneOfConstraint(context, constraints, isStringArray) &&\n validateTestConstraint(context, constraints)\n )\n}\n\n/**\n * Decorator for applying validation rules to a time field. A valid time value must be a string in the format HH:mm[:ss[.sss]] (24-hour clock).\n * \n * Example usage:\n * ```tsx\n * class Person {\n * @time({ required: true, formatError: \"Invalid wake up time format\", max: \"18:00\" })\n * wakeUpTime: string | null = null\n * }\n * const form = useForm(Person, ...)\n * \n * // the time decorator can also be used as a function to allow standalone validation:\n * Yop.validate(\"00:00\", time({ min: \"01:00\" })) // error: \"Must be after or equal to 01:00\"\n * ```\n * @template Value - The type of the string value.\n * @template Parent - The type of the parent object.\n * @param constraints - The time constraints to apply.\n * @param groups - Optional validation groups.\n * @returns A field decorator function with validation.\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Date_and_time_formats#time_strings\n * @category Property Decorators\n */\nexport function time<Value extends StringValue, Parent>(constraints?: TimeConstraints<Value, Parent>, groups?: Groups<TimeConstraints<Value, Parent>>) {\n return fieldValidationDecorator(\"time\", constraints ?? {}, groups, validateTime, isString)\n}\n"],"mappings":"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"}