@regle/schemas 1.18.0-beta.1 → 1.18.0-beta.3
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/dist/regle-schemas.d.ts +3 -3
- package/dist/regle-schemas.js +70 -66
- package/dist/regle-schemas.min.js +2 -2
- package/package.json +3 -3
package/dist/regle-schemas.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @regle/schemas v1.18.0-beta.
|
|
2
|
+
* @regle/schemas v1.18.0-beta.3
|
|
3
3
|
* (c) 2026 Victor Garcia
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -48,7 +48,7 @@ type ProcessNestedFields<TState extends Record<string, any> | undefined, TShortc
|
|
|
48
48
|
*/
|
|
49
49
|
type RegleSchemaStatus<TState extends Record<string, any> | undefined = Record<string, any>, TSchema extends StandardSchemaV1 = StandardSchemaV1, TShortcuts extends RegleShortcutDefinition = {}, IsRoot extends boolean = false> = Omit<RegleCommonStatus<TState>, IsRoot extends false ? '$pending' : ''> & {
|
|
50
50
|
/** Represents all the children of your object. You can access any nested child at any depth to get the relevant data you need for your form. */
|
|
51
|
-
readonly $fields: ProcessNestedFields<TState
|
|
51
|
+
readonly $fields: ProcessNestedFields<JoinDiscriminatedUnions<TState>, TShortcuts>;
|
|
52
52
|
/** Collection of all issues, collected for all children properties and nested forms.
|
|
53
53
|
*
|
|
54
54
|
* Only contains errors from properties where $dirty equals true. */
|
|
@@ -61,7 +61,7 @@ type RegleSchemaStatus<TState extends Record<string, any> | undefined = Record<s
|
|
|
61
61
|
readonly $silentErrors: RegleErrorTree<TState, false, true>;
|
|
62
62
|
/** Will return a copy of your state with only the fields that are dirty. By default it will filter out nullish values or objects, but you can override it with the first parameter $extractDirtyFields(false). */
|
|
63
63
|
$extractDirtyFields: (filterNullishValues?: boolean) => DeepPartial<TState>;
|
|
64
|
-
} & ProcessNestedFields<TState
|
|
64
|
+
} & ProcessNestedFields<JoinDiscriminatedUnions<TState>, TShortcuts> & (IsRoot extends true ? {
|
|
65
65
|
/** 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). */
|
|
66
66
|
$validate: (forceValues?: TState extends EmptyObject ? (HasNamedKeys<TState> extends true ? TState : any) : TState) => Promise<RegleSchemaResult<StandardSchemaV1.InferOutput<TSchema>>>;
|
|
67
67
|
} : {}) & ([TShortcuts['nested']] extends [never] ? {} : { [K in keyof TShortcuts['nested']]: ReturnType<NonNullable<TShortcuts['nested']>[K]> });
|
package/dist/regle-schemas.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @regle/schemas v1.18.0-beta.
|
|
2
|
+
* @regle/schemas v1.18.0-beta.3
|
|
3
3
|
* (c) 2026 Victor Garcia
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -14,71 +14,6 @@ function isFile(value) {
|
|
|
14
14
|
return value?.constructor?.name == "File";
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
/**
|
|
18
|
-
* Checks if a value is empty in any way (including arrays and objects).
|
|
19
|
-
* This is the inverse of `isFilled`.
|
|
20
|
-
*
|
|
21
|
-
* `isEmpty` also acts as a type guard.
|
|
22
|
-
*
|
|
23
|
-
* By default, it considers an empty array as `true`. You can override this behavior with `considerEmptyArrayInvalid`.
|
|
24
|
-
*
|
|
25
|
-
* @param value - The target value to check
|
|
26
|
-
* @param considerEmptyArrayInvalid - When `false`, empty arrays are not considered empty (default: `true`)
|
|
27
|
-
* @returns `true` if the value is empty, `false` otherwise
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* ```ts
|
|
31
|
-
* import { createRule, type Maybe } from '@regle/core';
|
|
32
|
-
* import { isEmpty } from '@regle/rules';
|
|
33
|
-
*
|
|
34
|
-
* const rule = createRule({
|
|
35
|
-
* validator(value: Maybe<string>) {
|
|
36
|
-
* if (isEmpty(value)) {
|
|
37
|
-
* return true;
|
|
38
|
-
* }
|
|
39
|
-
* return check(value);
|
|
40
|
-
* },
|
|
41
|
-
* message: 'Error'
|
|
42
|
-
* })
|
|
43
|
-
* ```
|
|
44
|
-
*
|
|
45
|
-
* @see {@link https://reglejs.dev/core-concepts/rules/validations-helpers#isempty Documentation}
|
|
46
|
-
*/
|
|
47
|
-
function isEmpty(value, considerEmptyArrayInvalid = true) {
|
|
48
|
-
if (value === void 0 || value === null) return true;
|
|
49
|
-
if (value instanceof Date) return isNaN(value.getTime());
|
|
50
|
-
else if (isFile(value)) return value.size <= 0;
|
|
51
|
-
else if (Array.isArray(value)) {
|
|
52
|
-
if (considerEmptyArrayInvalid) return value.length === 0;
|
|
53
|
-
return false;
|
|
54
|
-
} else if (typeof value === "object" && value != null) return Object.keys(value).length === 0;
|
|
55
|
-
return !String(value).length;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function getRegExpFlags(regExp) {
|
|
59
|
-
let flags = [];
|
|
60
|
-
regExp.global && flags.push("g");
|
|
61
|
-
regExp.ignoreCase && flags.push("i");
|
|
62
|
-
regExp.multiline && flags.push("m");
|
|
63
|
-
regExp.sticky && flags.push("y");
|
|
64
|
-
regExp.unicode && flags.push("u");
|
|
65
|
-
return flags.join("");
|
|
66
|
-
}
|
|
67
|
-
function cloneDeep(obj, dep = 0) {
|
|
68
|
-
if (dep > 20) return obj;
|
|
69
|
-
let result = obj;
|
|
70
|
-
let type = {}.toString.call(obj).slice(8, -1);
|
|
71
|
-
if (type == "Set") result = new Set([...obj].map((value) => cloneDeep(value, dep++)));
|
|
72
|
-
if (type == "Map") result = new Map([...obj].map((kv) => [cloneDeep(kv[0]), cloneDeep(kv[1])]));
|
|
73
|
-
if (type == "Date") result = new Date(obj.getTime());
|
|
74
|
-
if (type == "RegExp") result = RegExp(obj.source, getRegExpFlags(obj));
|
|
75
|
-
if (type == "Array" || type == "Object") {
|
|
76
|
-
result = Array.isArray(obj) ? [] : {};
|
|
77
|
-
for (let key in obj) result[key] = cloneDeep(obj[key], dep++);
|
|
78
|
-
}
|
|
79
|
-
return result;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
17
|
function isObject(obj) {
|
|
83
18
|
if (obj && (obj instanceof Date || obj.constructor.name == "File" || obj.constructor.name == "FileList")) return false;
|
|
84
19
|
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
@@ -148,6 +83,75 @@ function merge(_obj1, ..._objs) {
|
|
|
148
83
|
return result;
|
|
149
84
|
}
|
|
150
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Checks if a value is empty in any way (including arrays and objects).
|
|
88
|
+
* This is the inverse of `isFilled`.
|
|
89
|
+
*
|
|
90
|
+
* `isEmpty` also acts as a type guard.
|
|
91
|
+
*
|
|
92
|
+
* By default, it considers an empty array as `true`. You can override this behavior with `considerEmptyArrayInvalid`.
|
|
93
|
+
*
|
|
94
|
+
* @param value - The target value to check
|
|
95
|
+
* @param considerEmptyArrayInvalid - When `false`, empty arrays are not considered empty (default: `true`)
|
|
96
|
+
* @returns `true` if the value is empty, `false` otherwise
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* import { createRule, type Maybe } from '@regle/core';
|
|
101
|
+
* import { isEmpty } from '@regle/rules';
|
|
102
|
+
*
|
|
103
|
+
* const rule = createRule({
|
|
104
|
+
* validator(value: Maybe<string>) {
|
|
105
|
+
* if (isEmpty(value)) {
|
|
106
|
+
* return true;
|
|
107
|
+
* }
|
|
108
|
+
* return check(value);
|
|
109
|
+
* },
|
|
110
|
+
* message: 'Error'
|
|
111
|
+
* })
|
|
112
|
+
* ```
|
|
113
|
+
*
|
|
114
|
+
* @see {@link https://reglejs.dev/core-concepts/rules/validations-helpers#isempty Documentation}
|
|
115
|
+
*/
|
|
116
|
+
function isEmpty(value, considerEmptyArrayInvalid = true, considerEmptyObjectInvalid = true) {
|
|
117
|
+
if (value === void 0 || value === null) return true;
|
|
118
|
+
if (value instanceof Date) return isNaN(value.getTime());
|
|
119
|
+
else if (isFile(value)) return value.size <= 0;
|
|
120
|
+
else if (Array.isArray(value)) {
|
|
121
|
+
if (considerEmptyArrayInvalid) return value.length === 0;
|
|
122
|
+
return false;
|
|
123
|
+
} else if (isObject(value)) {
|
|
124
|
+
if (value == null) return true;
|
|
125
|
+
if (considerEmptyObjectInvalid) return Object.keys(value).length === 0;
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
return !String(value).length;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function getRegExpFlags(regExp) {
|
|
132
|
+
let flags = [];
|
|
133
|
+
if (regExp.global) flags.push("g");
|
|
134
|
+
if (regExp.ignoreCase) flags.push("i");
|
|
135
|
+
if (regExp.multiline) flags.push("m");
|
|
136
|
+
if (regExp.sticky) flags.push("y");
|
|
137
|
+
if (regExp.unicode) flags.push("u");
|
|
138
|
+
return flags.join("");
|
|
139
|
+
}
|
|
140
|
+
function cloneDeep(obj, dep = 0) {
|
|
141
|
+
if (dep > 20) return obj;
|
|
142
|
+
let result = obj;
|
|
143
|
+
let type = {}.toString.call(obj).slice(8, -1);
|
|
144
|
+
if (type == "Set") result = new Set([...obj].map((value) => cloneDeep(value, dep++)));
|
|
145
|
+
if (type == "Map") result = new Map([...obj].map((kv) => [cloneDeep(kv[0]), cloneDeep(kv[1])]));
|
|
146
|
+
if (type == "Date") result = new Date(obj.getTime());
|
|
147
|
+
if (type == "RegExp") result = RegExp(obj.source, getRegExpFlags(obj));
|
|
148
|
+
if (type == "Array" || type == "Object") {
|
|
149
|
+
result = Array.isArray(obj) ? [] : {};
|
|
150
|
+
for (let key in obj) result[key] = cloneDeep(obj[key], dep++);
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
|
|
151
155
|
function createUseRegleSchemaComposable(params) {
|
|
152
156
|
const { options, shortcuts, overrides } = params ?? {};
|
|
153
157
|
const globalOptions = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @regle/schemas v1.18.0-beta.
|
|
2
|
+
* @regle/schemas v1.18.0-beta.3
|
|
3
3
|
* (c) 2026 Victor Garcia
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import{createScopedUseRegle as e,useRootStorage as t}from"@regle/core";import{computed as n,getCurrentScope as r,isRef as i,onScopeDispose as a,ref as o,unref as s,watch as c}from"vue";function l(e){return e?.constructor?.name==`File`}function u(e
|
|
7
|
+
import{createScopedUseRegle as e,useRootStorage as t}from"@regle/core";import{computed as n,getCurrentScope as r,isRef as i,onScopeDispose as a,ref as o,unref as s,watch as c}from"vue";function l(e){return e?.constructor?.name==`File`}function u(e){return e&&(e instanceof Date||e.constructor.name==`File`||e.constructor.name==`FileList`)?!1:typeof e==`object`&&!!e&&!Array.isArray(e)}function d(e,t,n,r){var i,a;if(Array.isArray(t)&&(i=t.slice(0)),typeof t==`string`&&(i=t.split(`.`)),typeof t==`symbol`&&(i=[t]),!Array.isArray(i))throw Error(`props arg must be an array, a string or a symbol`);if(a=i.pop(),!a)return!1;p(a);for(var o;o=i.shift();)if(p(o),isNaN(parseInt(o))?(e[o]===void 0&&(e[o]={}),e=e[o]):(e.$each??=[],h(e.$each[o])&&(e.$each[o]={}),e=e.$each[o]),!e||typeof e!=`object`)return!1;return r?e[a]?e[a].$self=(e[a].$self??=[]).concat(n):e[a]={$self:n}:isNaN(parseInt(a))?Array.isArray(e[a])?e[a]=e[a].concat(n):e[a]=n:(e.$each??=[],e.$each[a]=(e.$each[a]??=[]).concat(n)),!0}function f(e,t,n){if(!e)return n;var r,i;if(Array.isArray(t)&&(r=t.slice(0)),typeof t==`string`&&(r=t.split(`.`)),typeof t==`symbol`&&(r=[t]),!Array.isArray(r))throw Error(`props arg must be an array, a string or a symbol`);for(;r.length;)if(i=r.shift(),!e||!i||(e=e[i],e===void 0))return n;return e}function p(e){if(e==`__proto__`||e==`constructor`||e==`prototype`)throw Error(`setting of prototype values not supported`)}function m(e,...t){for(var n=[].slice.call(arguments),r,i=n.length;r=n[i-1],i--;)if(!r||typeof r!=`object`&&typeof r!=`function`)throw Error(`expected object, got `+r);for(var a=n[0],o=n.slice(1),s=o.length,i=0;i<s;i++){var c=o[i];for(var l in c)a[l]=c[l]}return a}function h(e,t=!0,n=!0){return e==null?!0:e instanceof Date?isNaN(e.getTime()):l(e)?e.size<=0:Array.isArray(e)?t?e.length===0:!1:u(e)?e==null?!0:n?Object.keys(e).length===0:!1:!String(e).length}function g(e){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 _(e,t=0){if(t>20)return e;let n=e,r={}.toString.call(e).slice(8,-1);if(r==`Set`&&(n=new Set([...e].map(e=>_(e,t++)))),r==`Map`&&(n=new Map([...e].map(e=>[_(e[0]),_(e[1])]))),r==`Date`&&(n=new Date(e.getTime())),r==`RegExp`&&(n=RegExp(e.source,g(e))),r==`Array`||r==`Object`)for(let r in n=Array.isArray(e)?[]:{},e)n[r]=_(e[r],t++);return n}function v(e){let{options:l,shortcuts:p,overrides:h}=e??{},g={autoDirty:l?.autoDirty,lazy:l?.lazy,rewardEarly:l?.rewardEarly,clearExternalErrorsOnChange:l?.clearExternalErrorsOnChange};function v(e,l,v){let y=n(()=>s(l)),{syncState:b={onUpdate:!1,onValidate:!1},...x}=v??{},{onUpdate:S=!1,onValidate:C=!1}=b,w={...g,...x},T=n(()=>!u(E.value)),E=i(e)?e:o(e),D=o(u(E.value)?{..._(E.value)}:_(E.value)),O=u(E.value)?{..._(E.value)}:_(E.value),k=o({}),A=o([]),j;function M(e){let t=N(e),n=e.path?.[e.path.length-1],r=typeof n==`object`?n.key:n;return{isArray:(typeof n==`object`&&`value`in n?Array.isArray(n.value):!1)||(`type`in e?e.type===`array`:!1)||Array.isArray(f(E.value,t)),$path:t,lastItemKey:r,lastItem:n}}function N(e){return e.path?.map(e=>typeof e==`object`?e.key:e.toString()).join(`.`)??``}function P(e){let t=e.path?.at(-1);return typeof t==`object`?t.key:t}function F(e){let t=e.path?.at(-1),n=typeof t==`object`?typeof t.key==`string`:typeof t==`string`,r=e.path?.findLastIndex(e=>typeof e==`object`?typeof e.key==`number`:typeof e==`number`);if(!(!n&&r===-1)&&r!=null){let t=e.path?.slice(0,r+1);return{...e,path:t}}}if(!y.value?.[`~standard`])throw Error(`Only "standard-schema" compatible libraries are supported`);function I(e,t=!1){return!t&&w.rewardEarly?A.value.length?A.value.reduce((t,n)=>{if(`$currentArrayValue`in n&&u(n.$currentArrayValue)&&`$id`in n.$currentArrayValue){let r=n.$currentArrayValue.$id,i=P(n),a=e.find(e=>e?.$currentArrayValue?.$id===r&&P(e)===i);a&&t.push({...n,path:a?.path??[]})}else e.some(e=>N(e)===N(n))&&t.push(n);return t},[]):[]:e}function L(e,t=!1){let n={},r=e.issues?.map(e=>{let t=F(e);if(t){let n=f(E.value,N(t));Object.defineProperty(e,`$currentArrayValue`,{value:n,enumerable:!0,configurable:!0,writable:!0})}return e}),i=I(r??[],t);if(r?.length){let e=i.map(e=>{let{isArray:t,$path:n,lastItemKey:r}=M(e);return{...e,$path:n,isArray:t,$property:r,$rule:`schema`,$message:e.message}});e.forEach(({isArray:e,$path:t,...r})=>{d(n,t,[r],e)}),A.value=e}else A.value=[];return n}async function R(e=!1){let t=y.value[`~standard`].validate(E.value);return t instanceof Promise&&(t=await t),T.value?k.value=I(t.issues??[],e)?.map(e=>({$message:e.message,$property:e.path?.[e.path.length-1]?.toString()??`-`,$rule:`schema`,...e}))??[]:k.value=L(t,e),t.issues||(e&&C||!e&&S)&&(z?.(),u(E.value)?E.value=m(E.value,t.value):E.value=t.value,B()),t}let z;function B(){z=c([E,y],()=>{w.silent||R()},{deep:!0})}B(),R(),j=async()=>{try{let e=await R(!0);return V?.regle?.$touch(),{valid:!e.issues?.length,data:E.value,errors:V?.regle?.$errors,issues:k.value}}catch(e){return Promise.reject(e)}},r()&&a(()=>{z()});let V=t({scopeRules:n(()=>({})),state:E,options:w,schemaErrors:k,initialState:D,originalState:O,shortcuts:p,schemaMode:!0,onValidate:j,overrides:h});return{r$:V.regle}}return v}const y=v();function b(e,t){return e}function x(){function e(e,t){return t}return e}const S=x();function C({modifiers:e,shortcuts:t,overrides:n}){return{useRegleSchema:v({options:e,shortcuts:t,overrides:n}),inferSchema:x()}}const w=t=>{let{customStore:n,customUseRegle:r=y,asRecord:i=!1}=t??{};return e({customStore:n,customUseRegle:r,asRecord:i})},{useCollectScope:T,useScopedRegle:E}=e({customUseRegle:y}),D=T,O=E;export{w as createScopedUseRegleSchema,C as defineRegleSchemaConfig,S as inferSchema,D as useCollectSchemaScope,y as useRegleSchema,O as useScopedRegleSchema,b as withDeps};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@regle/schemas",
|
|
3
|
-
"version": "1.18.0-beta.
|
|
3
|
+
"version": "1.18.0-beta.3",
|
|
4
4
|
"description": "Schemas adapter for Regle",
|
|
5
5
|
"homepage": "https://reglejs.dev/",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@standard-schema/spec": "1.1.0",
|
|
39
39
|
"type-fest": "5.4.1",
|
|
40
|
-
"@regle/core": "1.18.0-beta.
|
|
41
|
-
"@regle/rules": "1.18.0-beta.
|
|
40
|
+
"@regle/core": "1.18.0-beta.3",
|
|
41
|
+
"@regle/rules": "1.18.0-beta.3"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@total-typescript/ts-reset": "0.6.1",
|