@regle/schemas 1.2.0-beta.2 β†’ 1.2.0-beta.4

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.
package/README.md CHANGED
@@ -27,7 +27,7 @@ It's heavily inspired by Vuelidate.
27
27
  - 🧰 Modular
28
28
  - πŸ”„ Async validation
29
29
  - 🌐 Plug any i18n library
30
- - πŸ“— Vuelidate compatible API
30
+ - πŸ“— Vuelidate like API
31
31
  - Standard Schemas spec support
32
32
  - πŸ¦Έβ€β™‚οΈ [Zod](https://zod.dev/)
33
33
  - πŸ€– [Valibot](https://valibot.dev/)
@@ -1,6 +1,7 @@
1
- import { Maybe, PrimitiveTypes, RegleShortcutDefinition, RegleCommonStatus, RegleRuleStatus, JoinDiscriminatedUnions, RegleCollectionErrors, RegleErrorTree, DeepReactiveState, NoInferLegacy, RegleBehaviourOptions } from '@regle/core';
1
+ import * as _regle_core from '@regle/core';
2
+ import { Maybe, PrimitiveTypes, RegleShortcutDefinition, RegleCommonStatus, RegleRuleStatus, JoinDiscriminatedUnions, RegleCollectionErrors, RegleErrorTree, DeepReactiveState, DeepMaybeRef, RegleBehaviourOptions, LocalRegleBehaviourOptions, NoInferLegacy, ScopedInstancesRecordLike, MergedScopedRegles } from '@regle/core';
2
3
  import { StandardSchemaV1 } from '@standard-schema/spec';
3
- import { Raw, MaybeRef, UnwrapNestedRefs } from 'vue';
4
+ import { Raw, MaybeRef, UnwrapNestedRefs, MaybeRefOrGetter, Ref } from 'vue';
4
5
 
5
6
  /**
6
7
  Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).
@@ -53,6 +54,46 @@ Unfortunately, `Record<string, never>`, `Record<keyof any, never>` and `Record<n
53
54
  */
54
55
  type EmptyObject = {[emptyObjectSymbol]?: never};
55
56
 
57
+ /**
58
+ Extract all optional keys from the given type.
59
+
60
+ This is useful when you want to create a new type that contains different type values for the optional keys only.
61
+
62
+ @example
63
+ ```
64
+ import type {OptionalKeysOf, Except} from 'type-fest';
65
+
66
+ interface User {
67
+ name: string;
68
+ surname: string;
69
+
70
+ luckyNumber?: number;
71
+ }
72
+
73
+ const REMOVE_FIELD = Symbol('remove field symbol');
74
+ type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & {
75
+ [Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD;
76
+ };
77
+
78
+ const update1: UpdateOperation<User> = {
79
+ name: 'Alice'
80
+ };
81
+
82
+ const update2: UpdateOperation<User> = {
83
+ name: 'Bob',
84
+ luckyNumber: REMOVE_FIELD
85
+ };
86
+ ```
87
+
88
+ @category Utilities
89
+ */
90
+ type OptionalKeysOf<BaseType extends object> =
91
+ BaseType extends unknown // For distributing `BaseType`
92
+ ? (keyof {
93
+ [Key in keyof BaseType as BaseType extends Record<Key, BaseType[Key]> ? never : Key]: never
94
+ }) & (keyof BaseType) // Intersect with `keyof BaseType` to ensure result of `OptionalKeysOf<BaseType>` is always assignable to `keyof BaseType`
95
+ : never; // Should never happen
96
+
56
97
  /**
57
98
  Extract all required keys from the given type.
58
99
 
@@ -77,11 +118,10 @@ const validator2 = createValidation<User>('surname', value => value.length < 25)
77
118
 
78
119
  @category Utilities
79
120
  */
80
- type RequiredKeysOf<BaseType extends object> = Exclude<{
81
- [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]>
82
- ? Key
83
- : never
84
- }[keyof BaseType], undefined>;
121
+ type RequiredKeysOf<BaseType extends object> =
122
+ BaseType extends unknown // For distributing `BaseType`
123
+ ? Exclude<keyof BaseType, OptionalKeysOf<BaseType>>
124
+ : never; // Should never happen
85
125
 
86
126
  /**
87
127
  Returns a boolean for whether the given type is `never`.
@@ -466,45 +506,6 @@ type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = (
466
506
  IsAny<T> extends true ? TypeIfAny : TypeIfNotAny
467
507
  );
468
508
 
469
- /**
470
- Extract all optional keys from the given type.
471
-
472
- This is useful when you want to create a new type that contains different type values for the optional keys only.
473
-
474
- @example
475
- ```
476
- import type {OptionalKeysOf, Except} from 'type-fest';
477
-
478
- interface User {
479
- name: string;
480
- surname: string;
481
-
482
- luckyNumber?: number;
483
- }
484
-
485
- const REMOVE_FIELD = Symbol('remove field symbol');
486
- type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & {
487
- [Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD;
488
- };
489
-
490
- const update1: UpdateOperation<User> = {
491
- name: 'Alice'
492
- };
493
-
494
- const update2: UpdateOperation<User> = {
495
- name: 'Bob',
496
- luckyNumber: REMOVE_FIELD
497
- };
498
- ```
499
-
500
- @category Utilities
501
- */
502
- type OptionalKeysOf<BaseType extends object> = Exclude<{
503
- [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]>
504
- ? never
505
- : Key
506
- }[keyof BaseType], undefined>;
507
-
508
509
  /**
509
510
  Matches any primitive, `void`, `Date`, or `RegExp` value.
510
511
  */
@@ -571,7 +572,11 @@ type ApplyDefaultOptions<
571
572
  IfNever<SpecifiedOptions, Defaults,
572
573
  Simplify<Merge<Defaults, {
573
574
  [Key in keyof SpecifiedOptions
574
- as Key extends OptionalKeysOf<Options> ? undefined extends SpecifiedOptions[Key] ? never : Key : Key
575
+ as Key extends OptionalKeysOf<Options>
576
+ ? Extract<SpecifiedOptions[Key], undefined> extends never
577
+ ? Key
578
+ : never
579
+ : Key
575
580
  ]: SpecifiedOptions[Key]
576
581
  }> & Required<Options>> // `& Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>`
577
582
  >>;
@@ -671,27 +676,29 @@ const partialSettings: PartialDeep<Settings, {recurseIntoArrays: true}> = {
671
676
  type PartialDeep<T, Options extends PartialDeepOptions = {}> =
672
677
  _PartialDeep<T, ApplyDefaultOptions<PartialDeepOptions, DefaultPartialDeepOptions, Options>>;
673
678
 
674
- type _PartialDeep<T, Options extends Required<PartialDeepOptions>> = T extends BuiltIns | (((...arguments_: any[]) => unknown)) | (new (...arguments_: any[]) => unknown)
679
+ type _PartialDeep<T, Options extends Required<PartialDeepOptions>> = T extends BuiltIns | ((new (...arguments_: any[]) => unknown))
675
680
  ? T
676
- : T extends Map<infer KeyType, infer ValueType>
677
- ? PartialMapDeep<KeyType, ValueType, Options>
678
- : T extends Set<infer ItemType>
679
- ? PartialSetDeep<ItemType, Options>
680
- : T extends ReadonlyMap<infer KeyType, infer ValueType>
681
- ? PartialReadonlyMapDeep<KeyType, ValueType, Options>
682
- : T extends ReadonlySet<infer ItemType>
683
- ? PartialReadonlySetDeep<ItemType, Options>
684
- : T extends object
685
- ? T extends ReadonlyArray<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156
686
- ? Options['recurseIntoArrays'] extends true
687
- ? ItemType[] extends T // Test for arrays (non-tuples) specifically
688
- ? readonly ItemType[] extends T // Differentiate readonly and mutable arrays
689
- ? ReadonlyArray<_PartialDeep<Options['allowUndefinedInNonTupleArrays'] extends false ? ItemType : ItemType | undefined, Options>>
690
- : Array<_PartialDeep<Options['allowUndefinedInNonTupleArrays'] extends false ? ItemType : ItemType | undefined, Options>>
691
- : PartialObjectDeep<T, Options> // Tuples behave properly
692
- : T // If they don't opt into array testing, just use the original type
693
- : PartialObjectDeep<T, Options>
694
- : unknown;
681
+ : IsNever<keyof T> extends true // For functions with no properties
682
+ ? T
683
+ : T extends Map<infer KeyType, infer ValueType>
684
+ ? PartialMapDeep<KeyType, ValueType, Options>
685
+ : T extends Set<infer ItemType>
686
+ ? PartialSetDeep<ItemType, Options>
687
+ : T extends ReadonlyMap<infer KeyType, infer ValueType>
688
+ ? PartialReadonlyMapDeep<KeyType, ValueType, Options>
689
+ : T extends ReadonlySet<infer ItemType>
690
+ ? PartialReadonlySetDeep<ItemType, Options>
691
+ : T extends object
692
+ ? T extends ReadonlyArray<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156
693
+ ? Options['recurseIntoArrays'] extends true
694
+ ? ItemType[] extends T // Test for arrays (non-tuples) specifically
695
+ ? readonly ItemType[] extends T // Differentiate readonly and mutable arrays
696
+ ? ReadonlyArray<_PartialDeep<Options['allowUndefinedInNonTupleArrays'] extends false ? ItemType : ItemType | undefined, Options>>
697
+ : Array<_PartialDeep<Options['allowUndefinedInNonTupleArrays'] extends false ? ItemType : ItemType | undefined, Options>>
698
+ : PartialObjectDeep<T, Options> // Tuples behave properly
699
+ : T // If they don't opt into array testing, just use the original type
700
+ : PartialObjectDeep<T, Options>
701
+ : unknown;
695
702
 
696
703
  /**
697
704
  Same as `PartialDeep`, but accepts only `Map`s and as inputs. Internal helper for `PartialDeep`.
@@ -716,19 +723,22 @@ type PartialReadonlySetDeep<T, Options extends Required<PartialDeepOptions>> = {
716
723
  /**
717
724
  Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.
718
725
  */
719
- type PartialObjectDeep<ObjectType extends object, Options extends Required<PartialDeepOptions>> = {
720
- [KeyType in keyof ObjectType]?: _PartialDeep<ObjectType[KeyType], Options>
721
- };
722
-
723
- interface RegleSchema<TState extends Record<string, any>, TSchema extends Record<string, any>, TShortcuts extends RegleShortcutDefinition = {}> {
726
+ type PartialObjectDeep<ObjectType extends object, Options extends Required<PartialDeepOptions>> =
727
+ (ObjectType extends (...arguments_: any) => unknown
728
+ ? (...arguments_: Parameters<ObjectType>) => ReturnType<ObjectType>
729
+ : {}) & ({
730
+ [KeyType in keyof ObjectType]?: _PartialDeep<ObjectType[KeyType], Options>
731
+ });
732
+
733
+ type RegleSchema<TState extends Record<string, any>, TSchema extends Record<string, any>, TShortcuts extends RegleShortcutDefinition = {}, TAdditionalReturnProperties extends Record<string, any> = {}> = {
724
734
  /**
725
735
  * r$ is a reactive object containing the values, errors, dirty state and all the necessary validations properties you'll need to display information.
726
736
  *
727
737
  * To see the list of properties: {@link https://reglejs.dev/core-concepts/validation-properties}
728
738
  */
729
739
  r$: Raw<RegleSchemaStatus<TState, TSchema, TShortcuts, true>>;
730
- }
731
- interface RegleSingleFieldSchema<TState extends Maybe<PrimitiveTypes>, TSchema extends unknown, TShortcuts extends RegleShortcutDefinition = {}> {
740
+ } & TAdditionalReturnProperties;
741
+ type RegleSingleFieldSchema<TState extends Maybe<PrimitiveTypes>, TSchema extends unknown, TShortcuts extends RegleShortcutDefinition = {}, TAdditionalReturnProperties extends Record<string, any> = {}> = {
732
742
  /**
733
743
  * r$ is a reactive object containing the values, errors, dirty state and all the necessary validations properties you'll need to display information.
734
744
  *
@@ -738,7 +748,7 @@ interface RegleSingleFieldSchema<TState extends Maybe<PrimitiveTypes>, TSchema e
738
748
  /** Sets all properties as dirty, triggering all rules. It returns a promise that will either resolve to false or a type safe copy of your form state. Values that had the required rule will be transformed into a non-nullable value (type only). */
739
749
  $validate: () => Promise<RegleSchemaResult<TSchema>>;
740
750
  }>;
741
- }
751
+ } & TAdditionalReturnProperties;
742
752
  type RegleSchemaResult<TSchema extends unknown> = {
743
753
  valid: false;
744
754
  data: PartialDeep<TSchema>;
@@ -817,12 +827,28 @@ type RegleSchemaCollectionStatus<TSchema extends Record<string, any>, TState ext
817
827
  [K in keyof TShortcuts['collections']]: ReturnType<NonNullable<TShortcuts['collections']>[K]>;
818
828
  });
819
829
 
820
- interface useRegleSchemaFn<TShortcuts extends RegleShortcutDefinition<any> = never> {
830
+ type RegleSchemaBehaviourOptions = {
831
+ /**
832
+ * Settings for applying transforms and default to the current state
833
+ */
834
+ syncState?: {
835
+ /**
836
+ * Applies every transform on every update to the state
837
+ */
838
+ onUpdate?: boolean;
839
+ /**
840
+ * Applies every transform only when calling `$validate`
841
+ */
842
+ onValidate?: boolean;
843
+ };
844
+ };
845
+
846
+ interface useRegleSchemaFn<TShortcuts extends RegleShortcutDefinition<any> = never, TAdditionalReturnProperties extends Record<string, any> = {}, TAdditionalOptions extends Record<string, any> = {}> {
821
847
  <TSchema extends StandardSchemaV1, TState extends StandardSchemaV1.InferInput<TSchema> | undefined>(state: MaybeRef<PartialDeep<TState, {
822
848
  recurseIntoArrays: true;
823
849
  }>> | DeepReactiveState<PartialDeep<TState, {
824
850
  recurseIntoArrays: true;
825
- }>>, rulesFactory: MaybeRef<TSchema>): NonNullable<TState> extends PrimitiveTypes ? RegleSingleFieldSchema<NonNullable<TState>, StandardSchemaV1.InferInput<TSchema>, TShortcuts> : RegleSchema<UnwrapNestedRefs<NonNullable<TState>>, UnwrapNestedRefs<NonNullable<StandardSchemaV1.InferInput<TSchema>>>, TShortcuts>;
851
+ }>>, rulesFactory: MaybeRef<TSchema>, options?: Omit<Partial<DeepMaybeRef<RegleBehaviourOptions>> & LocalRegleBehaviourOptions<Record<string, any>, {}, never>, 'validationGroups' | 'lazy' | 'rewardEarly' | 'silent'> & RegleSchemaBehaviourOptions & TAdditionalOptions): NonNullable<TState> extends PrimitiveTypes ? RegleSingleFieldSchema<NonNullable<TState>, StandardSchemaV1.InferInput<TSchema>, TShortcuts, TAdditionalReturnProperties> : RegleSchema<UnwrapNestedRefs<NonNullable<TState>>, UnwrapNestedRefs<NonNullable<StandardSchemaV1.InferInput<TSchema>>>, TShortcuts, TAdditionalReturnProperties>;
826
852
  }
827
853
  /**
828
854
  * useRegle serves as the foundation for validation logic.
@@ -843,7 +869,7 @@ interface useRegleSchemaFn<TShortcuts extends RegleShortcutDefinition<any> = nev
843
869
  * ```
844
870
  * Docs: {@link https://reglejs.dev/integrations/valibot#usage}
845
871
  */
846
- declare const useRegleSchema: useRegleSchemaFn<RegleShortcutDefinition<any>>;
872
+ declare const useRegleSchema: useRegleSchemaFn<RegleShortcutDefinition<any>, {}, {}>;
847
873
 
848
874
  /**
849
875
  *
@@ -897,4 +923,23 @@ declare function defineRegleSchemaConfig<TShortcuts extends RegleShortcutDefinit
897
923
  inferSchema: inferSchemaFn;
898
924
  };
899
925
 
900
- export { type InferRegleSchemaStatusType, type RegleSchema, type RegleSchemaCollectionStatus, type RegleSchemaFieldStatus, type RegleSchemaResult, type RegleSchemaStatus, type RegleSingleFieldSchema, defineRegleSchemaConfig, inferSchema, useRegleSchema, withDeps };
926
+ declare const useCollectSchemaScope: <TValue extends Record<string, unknown>[] = Record<string, unknown>[]>(namespace?: MaybeRefOrGetter<string>) => {
927
+ r$: MergedScopedRegles<TValue>;
928
+ };
929
+ declare const useScopedRegleSchema: useRegleSchemaFn<_regle_core.RegleShortcutDefinition<any>, {}, {}>;
930
+ declare const createScopedUseRegleSchema: <TCustomRegle extends useRegleSchemaFn = useRegleSchemaFn, TReturnedRegle extends useRegleSchemaFn = TCustomRegle extends useRegleSchemaFn<infer S> ? useRegleSchemaFn<S, {
931
+ dispose: () => void;
932
+ register: () => void;
933
+ }, {
934
+ namespace?: MaybeRefOrGetter<string>;
935
+ }> : useRegleSchemaFn>(options?: {
936
+ customUseRegle?: TCustomRegle;
937
+ customStore?: Ref<ScopedInstancesRecordLike>;
938
+ }) => {
939
+ useScopedRegle: TReturnedRegle;
940
+ useCollectScope<TValue extends Record<string, unknown>[] = Record<string, unknown>[]>(namespace?: MaybeRefOrGetter<string>): {
941
+ r$: MergedScopedRegles<TValue>;
942
+ };
943
+ };
944
+
945
+ export { type InferRegleSchemaStatusType, type RegleSchema, type RegleSchemaBehaviourOptions, type RegleSchemaCollectionStatus, type RegleSchemaFieldStatus, type RegleSchemaResult, type RegleSchemaStatus, type RegleSingleFieldSchema, createScopedUseRegleSchema, defineRegleSchemaConfig, inferSchema, useCollectSchemaScope, useRegleSchema, useScopedRegleSchema, withDeps };
@@ -1 +1 @@
1
- import {useRootStorage}from'@regle/core';import {ref,computed,unref,isRef,watch}from'vue';function k(e){if(typeof e.source.flags=="string")return e.source.flags;{let t=[];return e.global&&t.push("g"),e.ignoreCase&&t.push("i"),e.multiline&&t.push("m"),e.sticky&&t.push("y"),e.unicode&&t.push("u"),t.join("")}}function f(e){let t=e,r={}.toString.call(e).slice(8,-1);if(r=="Set"&&(t=new Set([...e].map(a=>f(a)))),r=="Map"&&(t=new Map([...e].map(a=>[f(a[0]),f(a[1])]))),r=="Date"&&(t=new Date(e.getTime())),r=="RegExp"&&(t=RegExp(e.source,k(e))),r=="Array"||r=="Object"){t=Array.isArray(e)?[]:{};for(let a in e)t[a]=f(e[a]);}return t}function S(e){return e&&(e instanceof Date||e.constructor.name=="File"||e.constructor.name=="FileList")?false:typeof e=="object"&&e!==null&&!Array.isArray(e)}function v(e,t,r,a){var n,o;if(Array.isArray(t)&&(n=t.slice(0)),typeof t=="string"&&(n=t.split(".")),typeof t=="symbol"&&(n=[t]),!Array.isArray(n))throw new Error("props arg must be an array, a string or a symbol");if(o=n.pop(),!o)return false;w(o);for(var s;s=n.shift();)if(w(s),isNaN(parseInt(s))?(typeof e[s]>"u"&&(e[s]={}),e=e[s]):((e.$each??=[])[s]={},e=e.$each[s]),!e||typeof e!="object")return false;return a?e[o]?e[o].$self=(e[o].$self??=[]).concat(r):e[o]={...e[o],$self:r}:Array.isArray(e[o])?e[o]=e[o].concat(r):e[o]=r,true}function b(e,t,r){if(!e)return r;var a,n;if(Array.isArray(t)&&(a=t.slice(0)),typeof t=="string"&&(a=t.split(".")),typeof t=="symbol"&&(a=[t]),!Array.isArray(a))throw new Error("props arg must be an array, a string or a symbol");for(;a.length;)if(n=a.shift(),!e||!n||(e=e[n],e===void 0))return r;return e}function w(e){if(e=="__proto__"||e=="constructor"||e=="prototype")throw new Error("setting of prototype values not supported")}function g(e,t){let r={autoDirty:e?.autoDirty,lazy:e?.lazy,rewardEarly:e?.rewardEarly,silent:e?.silent,clearExternalErrorsOnChange:e?.clearExternalErrorsOnChange};function a(n,o,s){let I=ref({}),p=computed(()=>unref(o)),A={...r,...s},M=computed(()=>!S(l.value)),l=isRef(n)?n:ref(n),C=ref(S(l.value)?{...f(l.value)}:f(l.value)),y=ref({}),T;if(!p.value?.["~standard"])throw new Error('Only "standard-schema" compatible libraries are supported');function V(i){let u={};return i.issues&&i.issues.map(c=>{let x=c.path?.map(d=>typeof d=="object"?d.key:d.toString()).join(".")??"",h=c.path?.[c.path.length-1],B=(typeof h=="object"&&"value"in h?Array.isArray(h.value):false)||("type"in c?c.type==="array":false)||Array.isArray(b(l.value,x));return {path:x,message:c.message,isArray:B}}).forEach(c=>{v(u,c.path,[c.message],c.isArray);}),u}async function D(){let i=p.value["~standard"].validate(l.value);return i instanceof Promise&&(i=await i),M.value?y.value=i.issues?.map(u=>u.message)??[]:y.value=V(i),i}return watch([l,p],D,{deep:true,immediate:true}),T=async()=>{try{return {valid:!(await D()).issues?.length,data:l.value}}catch(i){return Promise.reject(i)}},{r$:useRootStorage({scopeRules:I,state:l,options:A,schemaErrors:y,initialState:C,shortcuts:t,schemaMode:true,onValidate:T}).regle}}return a}var P=g();function F(e,t){return e}function R(){function e(t,r){return r}return e}var E=R();function N({modifiers:e,shortcuts:t}){let r=g(e,t),a=R();return {useRegleSchema:r,inferSchema:a}}export{N as defineRegleSchemaConfig,E as inferSchema,P as useRegleSchema,F as withDeps};
1
+ import {createScopedUseRegle,useRootStorage}from'@regle/core';import {computed,unref,ref,isRef,watch}from'vue';function q(e){if(typeof e.source.flags=="string")return e.source.flags;{let t=[];return e.global&&t.push("g"),e.ignoreCase&&t.push("i"),e.multiline&&t.push("m"),e.sticky&&t.push("y"),e.unicode&&t.push("u"),t.join("")}}function p(e){let t=e,r={}.toString.call(e).slice(8,-1);if(r=="Set"&&(t=new Set([...e].map(a=>p(a)))),r=="Map"&&(t=new Map([...e].map(a=>[p(a[0]),p(a[1])]))),r=="Date"&&(t=new Date(e.getTime())),r=="RegExp"&&(t=RegExp(e.source,q(e))),r=="Array"||r=="Object"){t=Array.isArray(e)?[]:{};for(let a in e)t[a]=p(e[a]);}return t}function g(e){return e&&(e instanceof Date||e.constructor.name=="File"||e.constructor.name=="FileList")?false:typeof e=="object"&&e!==null&&!Array.isArray(e)}function E(e,t,r,a){var n,o;if(Array.isArray(t)&&(n=t.slice(0)),typeof t=="string"&&(n=t.split(".")),typeof t=="symbol"&&(n=[t]),!Array.isArray(n))throw new Error("props arg must be an array, a string or a symbol");if(o=n.pop(),!o)return false;P(o);for(var i;i=n.shift();)if(P(i),isNaN(parseInt(i))?(typeof e[i]>"u"&&(e[i]={}),e=e[i]):((e.$each??=[])[i]={},e=e.$each[i]),!e||typeof e!="object")return false;return a?e[o]?e[o].$self=(e[o].$self??=[]).concat(r):e[o]={...e[o],$self:r}:Array.isArray(e[o])?e[o]=e[o].concat(r):e[o]=r,true}function I(e,t,r){if(!e)return r;var a,n;if(Array.isArray(t)&&(a=t.slice(0)),typeof t=="string"&&(a=t.split(".")),typeof t=="symbol"&&(a=[t]),!Array.isArray(a))throw new Error("props arg must be an array, a string or a symbol");for(;a.length;)if(n=a.shift(),!e||!n||(e=e[n],e===void 0))return r;return e}function P(e){if(e=="__proto__"||e=="constructor"||e=="prototype")throw new Error("setting of prototype values not supported")}function x(e,t){let r={autoDirty:e?.autoDirty,lazy:e?.lazy,rewardEarly:e?.rewardEarly,clearExternalErrorsOnChange:e?.clearExternalErrorsOnChange};function a(n,o,i){let m=computed(()=>unref(o)),{syncState:k={onUpdate:false,onValidate:false},...L}=i??{},{onUpdate:$=false,onValidate:z=false}=k,G={...r,...L},H=computed(()=>!g(c.value)),c=isRef(n)?n:ref(n),W=ref(g(c.value)?{...p(c.value)}:p(c.value)),y=ref({}),v;if(!m.value?.["~standard"])throw new Error('Only "standard-schema" compatible libraries are supported');function _(u){let s={};return u.issues&&u.issues.map(l=>{let F=l.path?.map(h=>typeof h=="object"?h.key:h.toString()).join(".")??"",S=l.path?.[l.path.length-1],J=(typeof S=="object"&&"value"in S?Array.isArray(S.value):false)||("type"in l?l.type==="array":false)||Array.isArray(I(c.value,F));return {path:F,message:l.message,isArray:J}}).forEach(l=>{E(s,l.path,[l.message],l.isArray);}),s}async function d(u=false){let s=m.value["~standard"].validate(c.value);return s instanceof Promise&&(s=await s),H.value?y.value=s.issues?.map(b=>b.message)??[]:y.value=_(s),s.issues||(u&&z||!u&&$)&&(w?.(),c.value=s.value,O()),s}let w;function O(){w=watch([c,m],()=>d(),{deep:true});}return O(),d(),v=async()=>{try{return {valid:!(await d(!0)).issues?.length,data:c.value}}catch(u){return Promise.reject(u)}},{r$:useRootStorage({scopeRules:computed(()=>({})),state:c,options:G,schemaErrors:y,initialState:W,shortcuts:t,schemaMode:true,onValidate:v}).regle}}return a}var f=x();function A(e,t){return e}function D(){function e(t,r){return r}return e}var C=D();function N({modifiers:e,shortcuts:t}){let r=x(e,t),a=D();return {useRegleSchema:r,inferSchema:a}}var {useCollectScope:U,useScopedRegle:B}=createScopedUseRegle({customUseRegle:f}),V=e=>{let{customStore:t,customUseRegle:r=f}=e??{};return createScopedUseRegle({customStore:t,customUseRegle:r})};export{V as createScopedUseRegleSchema,N as defineRegleSchemaConfig,C as inferSchema,U as useCollectSchemaScope,f as useRegleSchema,B as useScopedRegleSchema,A as withDeps};
@@ -1,5 +1,5 @@
1
- import { useRootStorage } from '@regle/core';
2
- import { ref, computed, unref, isRef, watch } from 'vue';
1
+ import { createScopedUseRegle, useRootStorage } from '@regle/core';
2
+ import { computed, unref, ref, isRef, watch } from 'vue';
3
3
 
4
4
  // src/core/useRegleSchema.ts
5
5
 
@@ -142,15 +142,15 @@ function createUseRegleSchemaComposable(options, shortcuts) {
142
142
  autoDirty: options?.autoDirty,
143
143
  lazy: options?.lazy,
144
144
  rewardEarly: options?.rewardEarly,
145
- silent: options?.silent,
146
145
  clearExternalErrorsOnChange: options?.clearExternalErrorsOnChange
147
146
  };
148
147
  function useRegleSchema2(state, schema, options2) {
149
- const convertedRules = ref({});
150
148
  const computedSchema = computed(() => unref(schema));
149
+ const { syncState = { onUpdate: false, onValidate: false }, ...defaultOptions } = options2 ?? {};
150
+ const { onUpdate: syncOnUpdate = false, onValidate: syncOnValidate = false } = syncState;
151
151
  const resolvedOptions = {
152
152
  ...globalOptions,
153
- ...options2
153
+ ...defaultOptions
154
154
  };
155
155
  const isSingleField = computed(() => !isObject(processedState.value));
156
156
  const processedState = isRef(state) ? state : ref(state);
@@ -181,7 +181,7 @@ function createUseRegleSchemaComposable(options, shortcuts) {
181
181
  }
182
182
  return output;
183
183
  }
184
- async function computeErrors() {
184
+ async function computeErrors(isValidate = false) {
185
185
  let result = computedSchema.value["~standard"].validate(processedState.value);
186
186
  if (result instanceof Promise) {
187
187
  result = await result;
@@ -191,12 +191,24 @@ function createUseRegleSchemaComposable(options, shortcuts) {
191
191
  } else {
192
192
  customErrors.value = issuesToRegleErrors(result);
193
193
  }
194
+ if (!result.issues) {
195
+ if (isValidate && syncOnValidate || !isValidate && syncOnUpdate) {
196
+ unWatchState?.();
197
+ processedState.value = result.value;
198
+ defineWatchState();
199
+ }
200
+ }
194
201
  return result;
195
202
  }
196
- watch([processedState, computedSchema], computeErrors, { deep: true, immediate: true });
203
+ let unWatchState;
204
+ function defineWatchState() {
205
+ unWatchState = watch([processedState, computedSchema], () => computeErrors(), { deep: true });
206
+ }
207
+ defineWatchState();
208
+ computeErrors();
197
209
  onValidate = async () => {
198
210
  try {
199
- const result = await computeErrors();
211
+ const result = await computeErrors(true);
200
212
  return {
201
213
  valid: !result.issues?.length,
202
214
  data: processedState.value
@@ -206,7 +218,7 @@ function createUseRegleSchemaComposable(options, shortcuts) {
206
218
  }
207
219
  };
208
220
  const regle = useRootStorage({
209
- scopeRules: convertedRules,
221
+ scopeRules: computed(() => ({})),
210
222
  state: processedState,
211
223
  options: resolvedOptions,
212
224
  schemaErrors: customErrors,
@@ -242,5 +254,12 @@ function defineRegleSchemaConfig({
242
254
  const inferSchema2 = createInferSchemaHelper();
243
255
  return { useRegleSchema: useRegleSchema2, inferSchema: inferSchema2 };
244
256
  }
257
+ var { useCollectScope: useCollectSchemaScope, useScopedRegle: useScopedRegleSchema } = createScopedUseRegle({
258
+ customUseRegle: useRegleSchema
259
+ });
260
+ var createScopedUseRegleSchema = (options) => {
261
+ const { customStore, customUseRegle = useRegleSchema } = options ?? {};
262
+ return createScopedUseRegle({ customStore, customUseRegle });
263
+ };
245
264
 
246
- export { defineRegleSchemaConfig, inferSchema, useRegleSchema, withDeps };
265
+ export { createScopedUseRegleSchema, defineRegleSchemaConfig, inferSchema, useCollectSchemaScope, useRegleSchema, useScopedRegleSchema, withDeps };
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@regle/schemas",
3
- "version": "1.2.0-beta.2",
3
+ "version": "1.2.0-beta.4",
4
4
  "description": "Schemas adapter for Regle",
5
5
  "dependencies": {
6
6
  "@standard-schema/spec": "1.0.0",
7
- "@regle/core": "1.2.0-beta.2",
8
- "@regle/rules": "1.2.0-beta.2"
7
+ "@regle/core": "1.2.0-beta.4",
8
+ "@regle/rules": "1.2.0-beta.4"
9
9
  },
10
10
  "peerDependencies": {
11
11
  "valibot": "^1.0.0",
@@ -25,23 +25,23 @@
25
25
  },
26
26
  "devDependencies": {
27
27
  "@total-typescript/ts-reset": "0.6.1",
28
- "@types/node": "22.13.17",
28
+ "@types/node": "22.15.3",
29
29
  "@typescript-eslint/eslint-plugin": "8.28.0",
30
30
  "@typescript-eslint/parser": "8.28.0",
31
31
  "@vue/test-utils": "2.4.6",
32
- "eslint": "9.15.0",
32
+ "eslint": "9.25.1",
33
33
  "eslint-config-prettier": "9.1.0",
34
- "eslint-plugin-vue": "9.31.0",
34
+ "eslint-plugin-vue": "9.33.0",
35
35
  "prettier": "3.5.3",
36
36
  "tsup": "8.4.0",
37
- "type-fest": "4.38.0",
38
- "typescript": "5.8.2",
37
+ "type-fest": "4.40.1",
38
+ "typescript": "5.8.3",
39
39
  "valibot": "1.0.0",
40
- "vitest": "3.1.1",
40
+ "vitest": "3.1.2",
41
41
  "vue": "3.5.13",
42
42
  "vue-eslint-parser": "10.1.3",
43
- "vue-tsc": "2.2.8",
44
- "zod": "3.24.2"
43
+ "vue-tsc": "2.2.10",
44
+ "zod": "3.24.3"
45
45
  },
46
46
  "type": "module",
47
47
  "exports": {