@regle/schemas 1.2.0-beta.3 β†’ 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).
@@ -729,15 +730,15 @@ type PartialObjectDeep<ObjectType extends object, Options extends Required<Parti
729
730
  [KeyType in keyof ObjectType]?: _PartialDeep<ObjectType[KeyType], Options>
730
731
  });
731
732
 
732
- interface RegleSchema<TState extends Record<string, any>, TSchema extends Record<string, any>, TShortcuts extends RegleShortcutDefinition = {}> {
733
+ type RegleSchema<TState extends Record<string, any>, TSchema extends Record<string, any>, TShortcuts extends RegleShortcutDefinition = {}, TAdditionalReturnProperties extends Record<string, any> = {}> = {
733
734
  /**
734
735
  * r$ is a reactive object containing the values, errors, dirty state and all the necessary validations properties you'll need to display information.
735
736
  *
736
737
  * To see the list of properties: {@link https://reglejs.dev/core-concepts/validation-properties}
737
738
  */
738
739
  r$: Raw<RegleSchemaStatus<TState, TSchema, TShortcuts, true>>;
739
- }
740
- 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> = {}> = {
741
742
  /**
742
743
  * r$ is a reactive object containing the values, errors, dirty state and all the necessary validations properties you'll need to display information.
743
744
  *
@@ -747,7 +748,7 @@ interface RegleSingleFieldSchema<TState extends Maybe<PrimitiveTypes>, TSchema e
747
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). */
748
749
  $validate: () => Promise<RegleSchemaResult<TSchema>>;
749
750
  }>;
750
- }
751
+ } & TAdditionalReturnProperties;
751
752
  type RegleSchemaResult<TSchema extends unknown> = {
752
753
  valid: false;
753
754
  data: PartialDeep<TSchema>;
@@ -826,12 +827,28 @@ type RegleSchemaCollectionStatus<TSchema extends Record<string, any>, TState ext
826
827
  [K in keyof TShortcuts['collections']]: ReturnType<NonNullable<TShortcuts['collections']>[K]>;
827
828
  });
828
829
 
829
- 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> = {}> {
830
847
  <TSchema extends StandardSchemaV1, TState extends StandardSchemaV1.InferInput<TSchema> | undefined>(state: MaybeRef<PartialDeep<TState, {
831
848
  recurseIntoArrays: true;
832
849
  }>> | DeepReactiveState<PartialDeep<TState, {
833
850
  recurseIntoArrays: true;
834
- }>>, 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>;
835
852
  }
836
853
  /**
837
854
  * useRegle serves as the foundation for validation logic.
@@ -852,7 +869,7 @@ interface useRegleSchemaFn<TShortcuts extends RegleShortcutDefinition<any> = nev
852
869
  * ```
853
870
  * Docs: {@link https://reglejs.dev/integrations/valibot#usage}
854
871
  */
855
- declare const useRegleSchema: useRegleSchemaFn<RegleShortcutDefinition<any>>;
872
+ declare const useRegleSchema: useRegleSchemaFn<RegleShortcutDefinition<any>, {}, {}>;
856
873
 
857
874
  /**
858
875
  *
@@ -906,4 +923,23 @@ declare function defineRegleSchemaConfig<TShortcuts extends RegleShortcutDefinit
906
923
  inferSchema: inferSchemaFn;
907
924
  };
908
925
 
909
- 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.3",
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.3",
8
- "@regle/rules": "1.2.0-beta.3"
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",