@regle/core 0.0.3 → 0.0.4-beta.0
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/index.cjs +633 -277
- package/dist/index.d.cts +128 -26
- package/dist/index.d.ts +128 -26
- package/dist/index.js +641 -279
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/core/createRule/unwrapRuleParameters.ts
|
|
2
|
-
import { unref } from "vue";
|
|
2
|
+
import { isRef, toRef, unref } from "vue";
|
|
3
3
|
function unwrapRuleParameters(params) {
|
|
4
4
|
return params.map((param) => {
|
|
5
5
|
if (param instanceof Function) {
|
|
@@ -8,6 +8,16 @@ function unwrapRuleParameters(params) {
|
|
|
8
8
|
return unref(param);
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
|
+
function createReactiveParams(params) {
|
|
12
|
+
return params.map((param) => {
|
|
13
|
+
if (param instanceof Function) {
|
|
14
|
+
return param;
|
|
15
|
+
} else if (isRef(param)) {
|
|
16
|
+
return param;
|
|
17
|
+
}
|
|
18
|
+
return toRef(() => param);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
11
21
|
|
|
12
22
|
// src/core/createRule/defineRuleProcessors.ts
|
|
13
23
|
function defineRuleProcessors(definition, ...params) {
|
|
@@ -15,26 +25,17 @@ function defineRuleProcessors(definition, ...params) {
|
|
|
15
25
|
const processors = {
|
|
16
26
|
message(value, ...args) {
|
|
17
27
|
if (typeof definition.message === "function") {
|
|
18
|
-
return definition.message(
|
|
19
|
-
value,
|
|
20
|
-
...unwrapRuleParameters(args.length ? args : params)
|
|
21
|
-
);
|
|
28
|
+
return definition.message(value, ...args.length ? args : params);
|
|
22
29
|
} else {
|
|
23
30
|
return definition.message;
|
|
24
31
|
}
|
|
25
32
|
},
|
|
26
33
|
validator(value, ...args) {
|
|
27
|
-
return definition.validator(
|
|
28
|
-
value,
|
|
29
|
-
...unwrapRuleParameters(args.length ? args : params)
|
|
30
|
-
);
|
|
34
|
+
return definition.validator(value, ...args.length ? args : params);
|
|
31
35
|
},
|
|
32
36
|
active(value, ...args) {
|
|
33
37
|
if (typeof definition.active === "function") {
|
|
34
|
-
return definition.active(
|
|
35
|
-
value,
|
|
36
|
-
...unwrapRuleParameters(args.length ? args : params)
|
|
37
|
-
);
|
|
38
|
+
return definition.active(value, ...args.length ? args : params);
|
|
38
39
|
} else {
|
|
39
40
|
return definition.active ?? true;
|
|
40
41
|
}
|
|
@@ -46,7 +47,7 @@ function defineRuleProcessors(definition, ...params) {
|
|
|
46
47
|
_active: definition.active,
|
|
47
48
|
_type: definition.type,
|
|
48
49
|
_patched: false,
|
|
49
|
-
_params: params
|
|
50
|
+
_params: createReactiveParams(params)
|
|
50
51
|
}
|
|
51
52
|
};
|
|
52
53
|
return processors;
|
|
@@ -79,18 +80,21 @@ function createRule(definition) {
|
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
// src/core/useRegle/useRegle.ts
|
|
82
|
-
import { computed as
|
|
83
|
+
import { computed as computed5, isRef as isRef2, shallowRef as shallowRef2, toRaw } from "vue";
|
|
83
84
|
|
|
84
85
|
// src/core/useRegle/useStateProperties/useStateProperties.ts
|
|
85
|
-
import {
|
|
86
|
+
import { reactive as reactive5 } from "vue";
|
|
86
87
|
|
|
87
|
-
// src/core/useRegle/
|
|
88
|
-
import { computed
|
|
88
|
+
// src/core/useRegle/useErrors.ts
|
|
89
|
+
import { computed } from "vue";
|
|
89
90
|
|
|
90
91
|
// src/utils/object.utils.ts
|
|
91
92
|
function isObject(obj) {
|
|
92
93
|
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
93
94
|
}
|
|
95
|
+
function isRefObject(obj) {
|
|
96
|
+
return isObject(obj.value);
|
|
97
|
+
}
|
|
94
98
|
|
|
95
99
|
// src/utils/isEmpty.ts
|
|
96
100
|
function isEmpty(value) {
|
|
@@ -115,6 +119,9 @@ function isEmpty(value) {
|
|
|
115
119
|
return !String(value).trim().length;
|
|
116
120
|
}
|
|
117
121
|
|
|
122
|
+
// src/utils/composables.ts
|
|
123
|
+
import { effectScope, getCurrentScope, onScopeDispose } from "vue";
|
|
124
|
+
|
|
118
125
|
// src/core/useRegle/guards/ruleDef.guards.ts
|
|
119
126
|
function isNestedRulesDef(state, rule) {
|
|
120
127
|
return isObject(state.value) && isObject(rule.value) && !Object.entries(rule.value).some((rule2) => isRuleDef(rule2));
|
|
@@ -131,9 +138,6 @@ function isRuleDef(rule) {
|
|
|
131
138
|
function isFormRuleDefinition(rule) {
|
|
132
139
|
return !(typeof rule.value === "function");
|
|
133
140
|
}
|
|
134
|
-
function isFormInline(rule) {
|
|
135
|
-
return typeof rule.value === "function";
|
|
136
|
-
}
|
|
137
141
|
|
|
138
142
|
// src/core/useRegle/guards/rule.status.guards.ts
|
|
139
143
|
function isNestedRulesStatus(rule) {
|
|
@@ -146,8 +150,72 @@ function isFieldStatus(rule) {
|
|
|
146
150
|
return !!rule && "$rules" in rule;
|
|
147
151
|
}
|
|
148
152
|
|
|
153
|
+
// src/core/useRegle/useErrors.ts
|
|
154
|
+
function extractRulesErrors(rules) {
|
|
155
|
+
return Object.entries(rules).map(([ruleKey, rule]) => {
|
|
156
|
+
if (!rule.$valid) {
|
|
157
|
+
return rule.$message;
|
|
158
|
+
}
|
|
159
|
+
return null;
|
|
160
|
+
}).filter((msg) => !!msg);
|
|
161
|
+
}
|
|
162
|
+
function processFieldErrors(fieldStatus) {
|
|
163
|
+
if (isNestedRulesStatus(fieldStatus)) {
|
|
164
|
+
return extractNestedErrors(fieldStatus.$fields);
|
|
165
|
+
} else if (isCollectionRulesStatus(fieldStatus)) {
|
|
166
|
+
return {
|
|
167
|
+
$errors: fieldStatus.$rules ? extractRulesErrors(fieldStatus.$rules) : [],
|
|
168
|
+
$each: fieldStatus.$each.map(processFieldErrors)
|
|
169
|
+
};
|
|
170
|
+
} else if (isFieldStatus(fieldStatus) && fieldStatus.$error) {
|
|
171
|
+
return extractRulesErrors(fieldStatus.$rules);
|
|
172
|
+
}
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
function extractCollectionError(field) {
|
|
176
|
+
return field.$each.map(processFieldErrors);
|
|
177
|
+
}
|
|
178
|
+
function extractNestedErrors(fields) {
|
|
179
|
+
return Object.fromEntries(
|
|
180
|
+
Object.entries(fields).map(([fieldKey, fieldStatus]) => {
|
|
181
|
+
if (isNestedRulesStatus(fieldStatus)) {
|
|
182
|
+
return [fieldKey, extractNestedErrors(fieldStatus.$fields)];
|
|
183
|
+
} else if (isCollectionRulesStatus(fieldStatus)) {
|
|
184
|
+
return [
|
|
185
|
+
fieldKey,
|
|
186
|
+
{
|
|
187
|
+
...fieldStatus.$rules && { $errors: extractRulesErrors(fieldStatus.$rules) },
|
|
188
|
+
$each: extractCollectionError(fieldStatus)
|
|
189
|
+
}
|
|
190
|
+
];
|
|
191
|
+
} else if (isFieldStatus(fieldStatus) && fieldStatus.$error) {
|
|
192
|
+
return [fieldKey, extractRulesErrors(fieldStatus.$rules)];
|
|
193
|
+
}
|
|
194
|
+
return [fieldKey, []];
|
|
195
|
+
})
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
function useErrors($regle) {
|
|
199
|
+
const errors = computed(() => {
|
|
200
|
+
return extractNestedErrors($regle.$fields);
|
|
201
|
+
});
|
|
202
|
+
return errors;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// src/core/useRegle/useStateProperties/createReactiveNestedStatus.ts
|
|
206
|
+
import {
|
|
207
|
+
computed as computed4,
|
|
208
|
+
effectScope as effectScope4,
|
|
209
|
+
reactive as reactive4,
|
|
210
|
+
toRef as toRef4,
|
|
211
|
+
watch as watch4
|
|
212
|
+
} from "vue";
|
|
213
|
+
|
|
214
|
+
// src/core/useRegle/useStateProperties/createReactiveFieldStatus.ts
|
|
215
|
+
import { computed as computed3, effectScope as effectScope3, reactive as reactive2, ref as ref2, toRef as toRef2, watch as watch2 } from "vue";
|
|
216
|
+
|
|
149
217
|
// src/core/useRegle/useStateProperties/createReactiveRuleStatus.ts
|
|
150
|
-
import { computed,
|
|
218
|
+
import { computed as computed2, effectScope as effectScope2, reactive, watch } from "vue";
|
|
151
219
|
|
|
152
220
|
// src/types/rules/rule.internal.types.ts
|
|
153
221
|
var InternalRuleType = /* @__PURE__ */ ((InternalRuleType2) => {
|
|
@@ -162,311 +230,595 @@ function createReactiveRuleStatus({
|
|
|
162
230
|
customMessages,
|
|
163
231
|
rule,
|
|
164
232
|
ruleKey,
|
|
165
|
-
state
|
|
233
|
+
state,
|
|
234
|
+
path,
|
|
235
|
+
storage
|
|
166
236
|
}) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const $
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
});
|
|
180
|
-
const $message = computed(() => {
|
|
181
|
-
let message = "";
|
|
182
|
-
const customMessageRule = customMessages[ruleKey]?.message;
|
|
183
|
-
if (customMessageRule) {
|
|
184
|
-
if (typeof customMessageRule === "function") {
|
|
185
|
-
message = customMessageRule(state.value, ...$params.value);
|
|
186
|
-
} else {
|
|
187
|
-
message = customMessageRule;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
if (isFormRuleDefinition(rule)) {
|
|
191
|
-
if (!(customMessageRule && !rule.value._patched)) {
|
|
192
|
-
if (typeof rule.value.message === "function") {
|
|
193
|
-
message = rule.value.message(state.value, ...$params.value);
|
|
237
|
+
let scope = effectScope2();
|
|
238
|
+
let scopeState;
|
|
239
|
+
const { $pending, $valid } = storage.trySetRuleStatusRef(`${path}.${ruleKey}`);
|
|
240
|
+
function $watch() {
|
|
241
|
+
scopeState = scope.run(() => {
|
|
242
|
+
const $active = computed2(() => {
|
|
243
|
+
if (isFormRuleDefinition(rule)) {
|
|
244
|
+
if (typeof rule.value.active === "function") {
|
|
245
|
+
return rule.value.active(state.value, ...$params.value);
|
|
246
|
+
} else {
|
|
247
|
+
return rule.value.active;
|
|
248
|
+
}
|
|
194
249
|
} else {
|
|
195
|
-
|
|
250
|
+
return true;
|
|
196
251
|
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
if (isFormInline(rule)) {
|
|
207
|
-
return ruleKey;
|
|
208
|
-
} else {
|
|
209
|
-
return Object.values(InternalRuleType).includes(rule.value.type) ? ruleKey : rule.value.type;
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
const $validator = computed(
|
|
213
|
-
() => {
|
|
214
|
-
if (isFormInline(rule)) {
|
|
215
|
-
return rule.value;
|
|
216
|
-
} else {
|
|
217
|
-
return rule.value.validator;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
);
|
|
221
|
-
const $params = computed(() => {
|
|
222
|
-
if (typeof rule.value === "function") {
|
|
223
|
-
return [];
|
|
224
|
-
}
|
|
225
|
-
return unwrapRuleParameters(rule.value._params ?? []);
|
|
226
|
-
});
|
|
227
|
-
watch(
|
|
228
|
-
[state, $dirty, $params],
|
|
229
|
-
async () => {
|
|
230
|
-
const validator = $validator.value;
|
|
231
|
-
let ruleResult = false;
|
|
232
|
-
const resultOrPromise = validator(state.value, ...$params.value);
|
|
233
|
-
if (resultOrPromise instanceof Promise) {
|
|
234
|
-
if ($dirty.value) {
|
|
235
|
-
try {
|
|
236
|
-
$valid.value = true;
|
|
237
|
-
$pending.value = true;
|
|
238
|
-
const promiseResult = await resultOrPromise;
|
|
239
|
-
ruleResult = promiseResult;
|
|
240
|
-
} catch (e) {
|
|
241
|
-
ruleResult = false;
|
|
242
|
-
} finally {
|
|
243
|
-
$pending.value = false;
|
|
252
|
+
});
|
|
253
|
+
const $message = computed2(() => {
|
|
254
|
+
let message = "";
|
|
255
|
+
const customMessageRule = customMessages[ruleKey]?.message;
|
|
256
|
+
if (customMessageRule) {
|
|
257
|
+
if (typeof customMessageRule === "function") {
|
|
258
|
+
message = customMessageRule(state.value, ...$params.value);
|
|
259
|
+
} else {
|
|
260
|
+
message = customMessageRule;
|
|
244
261
|
}
|
|
245
262
|
}
|
|
246
|
-
|
|
247
|
-
|
|
263
|
+
if (isFormRuleDefinition(rule)) {
|
|
264
|
+
if (!(customMessageRule && !rule.value._patched)) {
|
|
265
|
+
if (typeof rule.value.message === "function") {
|
|
266
|
+
message = rule.value.message(state.value, ...$params.value);
|
|
267
|
+
} else {
|
|
268
|
+
message = rule.value.message;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (isEmpty(message)) {
|
|
273
|
+
message = "Error";
|
|
274
|
+
console.warn(`No error message defined for ${ruleKey}`);
|
|
275
|
+
}
|
|
276
|
+
return message;
|
|
277
|
+
});
|
|
278
|
+
const $type = computed2(() => {
|
|
279
|
+
if (isFormRuleDefinition(rule)) {
|
|
280
|
+
return Object.values(InternalRuleType).includes(rule.value.type) ? ruleKey : rule.value.type;
|
|
281
|
+
} else {
|
|
282
|
+
return ruleKey;
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
const $validator = computed2(() => {
|
|
286
|
+
if (isFormRuleDefinition(rule)) {
|
|
287
|
+
return rule.value.validator;
|
|
288
|
+
} else {
|
|
289
|
+
return rule.value;
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
const $params = computed2(() => {
|
|
293
|
+
if (typeof rule.value === "function") {
|
|
294
|
+
return [];
|
|
295
|
+
}
|
|
296
|
+
return unwrapRuleParameters(rule.value._params ?? []);
|
|
297
|
+
});
|
|
298
|
+
const $path = computed2(() => `${path}.${$type.value}`);
|
|
299
|
+
return {
|
|
300
|
+
$active,
|
|
301
|
+
$message,
|
|
302
|
+
$type,
|
|
303
|
+
$validator,
|
|
304
|
+
$params,
|
|
305
|
+
$path
|
|
306
|
+
};
|
|
307
|
+
});
|
|
308
|
+
$validate();
|
|
309
|
+
}
|
|
310
|
+
$watch();
|
|
311
|
+
const $unwatchState = watch(scopeState.$params, $validate, {
|
|
312
|
+
deep: true
|
|
313
|
+
});
|
|
314
|
+
async function $validate() {
|
|
315
|
+
const validator = scopeState.$validator.value;
|
|
316
|
+
let ruleResult = false;
|
|
317
|
+
const resultOrPromise = validator(state.value, ...scopeState.$params.value);
|
|
318
|
+
if (resultOrPromise instanceof Promise) {
|
|
319
|
+
if ($dirty.value && !$pending.value) {
|
|
320
|
+
try {
|
|
321
|
+
$valid.value = true;
|
|
322
|
+
$pending.value = true;
|
|
323
|
+
const promiseResult = await resultOrPromise;
|
|
324
|
+
ruleResult = promiseResult;
|
|
325
|
+
} catch (e) {
|
|
326
|
+
ruleResult = false;
|
|
327
|
+
} finally {
|
|
328
|
+
$pending.value = false;
|
|
329
|
+
}
|
|
248
330
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
331
|
+
} else {
|
|
332
|
+
ruleResult = resultOrPromise;
|
|
333
|
+
}
|
|
334
|
+
$valid.value = ruleResult;
|
|
335
|
+
return ruleResult;
|
|
336
|
+
}
|
|
337
|
+
function $unwatch() {
|
|
338
|
+
$unwatchState();
|
|
339
|
+
scope.stop();
|
|
340
|
+
scope = effectScope2();
|
|
341
|
+
scopeState = null;
|
|
342
|
+
}
|
|
253
343
|
return reactive({
|
|
254
|
-
|
|
255
|
-
$active,
|
|
344
|
+
...scopeState,
|
|
256
345
|
$pending,
|
|
257
|
-
$type,
|
|
258
346
|
$valid,
|
|
259
|
-
$
|
|
260
|
-
|
|
347
|
+
$validate,
|
|
348
|
+
$unwatch,
|
|
349
|
+
$watch
|
|
261
350
|
});
|
|
262
351
|
}
|
|
263
352
|
|
|
264
|
-
// src/core/useRegle/useStateProperties/
|
|
265
|
-
function
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
353
|
+
// src/core/useRegle/useStateProperties/createReactiveFieldStatus.ts
|
|
354
|
+
function createReactiveFieldStatus({
|
|
355
|
+
state,
|
|
356
|
+
rulesDef,
|
|
357
|
+
customMessages,
|
|
358
|
+
path,
|
|
359
|
+
storage
|
|
360
|
+
}) {
|
|
361
|
+
let scope = effectScope3();
|
|
362
|
+
let scopeState;
|
|
363
|
+
const $dirty = ref2(false);
|
|
364
|
+
const $anyDirty = computed3(() => $dirty.value);
|
|
365
|
+
function createReactiveRulesResult() {
|
|
366
|
+
const declaredRules = rulesDef.value;
|
|
367
|
+
const storeResult = storage.checkRuleDeclEntry(path, declaredRules);
|
|
368
|
+
$rules.value = Object.fromEntries(
|
|
369
|
+
Object.entries(declaredRules).map(([ruleKey, rule]) => {
|
|
370
|
+
if (rule) {
|
|
371
|
+
const ruleRef = toRef2(() => rule);
|
|
272
372
|
return [
|
|
273
|
-
|
|
274
|
-
|
|
373
|
+
ruleKey,
|
|
374
|
+
createReactiveRuleStatus({
|
|
375
|
+
$dirty,
|
|
376
|
+
customMessages,
|
|
377
|
+
rule: ruleRef,
|
|
378
|
+
ruleKey,
|
|
379
|
+
state,
|
|
380
|
+
path,
|
|
381
|
+
storage
|
|
382
|
+
})
|
|
275
383
|
];
|
|
276
384
|
}
|
|
277
385
|
return [];
|
|
278
|
-
}).filter(
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
)
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
const $anyDirty = computed2(() => {
|
|
289
|
-
return Object.entries($fields).some(([key, statusOrField]) => {
|
|
290
|
-
return statusOrField.$dirty;
|
|
291
|
-
});
|
|
292
|
-
});
|
|
293
|
-
const $invalid = computed2(() => {
|
|
294
|
-
return Object.entries($fields).some(([key, statusOrField]) => {
|
|
295
|
-
return statusOrField.$invalid;
|
|
296
|
-
});
|
|
386
|
+
}).filter((ruleDef) => !!ruleDef.length)
|
|
387
|
+
);
|
|
388
|
+
$watch();
|
|
389
|
+
if (storeResult?.valid != null) {
|
|
390
|
+
$dirty.value = storage.getDirtyState(path);
|
|
391
|
+
}
|
|
392
|
+
storage.addRuleDeclEntry(path, declaredRules);
|
|
393
|
+
}
|
|
394
|
+
const $unwatchDirty = watch2($dirty, () => {
|
|
395
|
+
storage.setDirtyEntry(path, $dirty.value);
|
|
297
396
|
});
|
|
298
|
-
const $
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
397
|
+
const $unwatchState = watch2(state, () => {
|
|
398
|
+
if (!$dirty.value) {
|
|
399
|
+
$dirty.value = true;
|
|
400
|
+
}
|
|
401
|
+
$validate();
|
|
302
402
|
});
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
403
|
+
function $unwatch() {
|
|
404
|
+
if ($rules.value) {
|
|
405
|
+
Object.entries($rules.value).forEach(([_, rule]) => {
|
|
406
|
+
rule.$unwatch();
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
$unwatchDirty();
|
|
410
|
+
if ($dirty.value) {
|
|
411
|
+
storage.setDirtyEntry(path, $dirty.value);
|
|
412
|
+
}
|
|
413
|
+
$unwatchState();
|
|
414
|
+
scope.stop();
|
|
415
|
+
scope = effectScope3();
|
|
416
|
+
scopeState = null;
|
|
417
|
+
}
|
|
418
|
+
function $watch() {
|
|
419
|
+
scopeState = scope.run(() => {
|
|
420
|
+
const $error = computed3(() => {
|
|
421
|
+
return $invalid.value && !$pending.value && $dirty.value;
|
|
422
|
+
});
|
|
423
|
+
const $pending = computed3(() => {
|
|
424
|
+
return Object.entries($rules.value).some(([key, rule]) => {
|
|
425
|
+
return rule.$pending;
|
|
426
|
+
});
|
|
427
|
+
});
|
|
428
|
+
const $invalid = computed3(() => {
|
|
429
|
+
return Object.entries($rules.value).some(([key, ruleResult]) => {
|
|
430
|
+
return !ruleResult.$valid;
|
|
431
|
+
});
|
|
432
|
+
});
|
|
433
|
+
const $valid = computed3(() => !$invalid.value);
|
|
434
|
+
return {
|
|
435
|
+
$error,
|
|
436
|
+
$pending,
|
|
437
|
+
$invalid,
|
|
438
|
+
$valid
|
|
439
|
+
};
|
|
306
440
|
});
|
|
307
|
-
}
|
|
441
|
+
}
|
|
442
|
+
const $rules = ref2();
|
|
443
|
+
createReactiveRulesResult();
|
|
308
444
|
function $reset() {
|
|
309
|
-
|
|
310
|
-
statusOrField.$reset();
|
|
311
|
-
});
|
|
445
|
+
$dirty.value = false;
|
|
312
446
|
}
|
|
313
447
|
function $touch() {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
448
|
+
$dirty.value = true;
|
|
449
|
+
$validate();
|
|
450
|
+
}
|
|
451
|
+
async function $validate() {
|
|
452
|
+
try {
|
|
453
|
+
const results = await Promise.all(
|
|
454
|
+
Object.entries($rules.value).map(([key, rule]) => {
|
|
455
|
+
return rule.$validate();
|
|
456
|
+
})
|
|
457
|
+
);
|
|
458
|
+
return results.every((value) => !!value);
|
|
459
|
+
} catch (e) {
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
317
462
|
}
|
|
318
|
-
const $valid = computed2(() => !$invalid.value);
|
|
319
463
|
return reactive2({
|
|
320
464
|
$dirty,
|
|
321
465
|
$anyDirty,
|
|
322
|
-
$invalid,
|
|
323
|
-
$
|
|
324
|
-
$
|
|
325
|
-
$
|
|
466
|
+
$invalid: scopeState.$invalid,
|
|
467
|
+
$error: scopeState.$error,
|
|
468
|
+
$pending: scopeState.$pending,
|
|
469
|
+
$valid: scopeState.$valid,
|
|
326
470
|
$value: state,
|
|
327
|
-
$
|
|
471
|
+
$rules,
|
|
328
472
|
$reset,
|
|
329
|
-
$touch
|
|
473
|
+
$touch,
|
|
474
|
+
$validate,
|
|
475
|
+
$unwatch,
|
|
476
|
+
$watch
|
|
330
477
|
});
|
|
331
478
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
479
|
+
|
|
480
|
+
// src/core/useRegle/useStateProperties/createReactiveCollectionStatus.ts
|
|
481
|
+
import { reactive as reactive3, ref as ref3, toRef as toRef3, watch as watch3 } from "vue";
|
|
482
|
+
function createReactiveCollectionStatus({
|
|
483
|
+
state,
|
|
484
|
+
rulesDef,
|
|
485
|
+
customMessages,
|
|
486
|
+
path,
|
|
487
|
+
storage
|
|
488
|
+
}) {
|
|
489
|
+
if (Array.isArray(state.value) && !rulesDef.value.$each) {
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
let $unwatchState = null;
|
|
493
|
+
const $fieldStatus = ref3({});
|
|
494
|
+
const $eachStatus = storage.getCollectionsEntry(path);
|
|
495
|
+
createStatus();
|
|
496
|
+
$watch();
|
|
497
|
+
function createStatus() {
|
|
498
|
+
const { $each, ...otherFields } = rulesDef.value;
|
|
499
|
+
$fieldStatus.value = createReactiveFieldStatus({
|
|
500
|
+
state,
|
|
501
|
+
rulesDef: toRef3(() => otherFields),
|
|
502
|
+
customMessages,
|
|
503
|
+
path,
|
|
504
|
+
storage
|
|
505
|
+
});
|
|
506
|
+
if (Array.isArray(state.value) && $each) {
|
|
507
|
+
$eachStatus.value = state.value.map((value, index) => {
|
|
508
|
+
const $path = `${path}.${index}`;
|
|
509
|
+
return createReactiveChildrenStatus({
|
|
510
|
+
state: toRef3(() => value),
|
|
511
|
+
rulesDef: toRef3(() => $each),
|
|
512
|
+
customMessages,
|
|
513
|
+
path: $path,
|
|
514
|
+
storage
|
|
515
|
+
});
|
|
516
|
+
}).filter((f) => !!f);
|
|
517
|
+
} else {
|
|
518
|
+
$eachStatus.value = [];
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
function $unwatch() {
|
|
522
|
+
if ($unwatchState) {
|
|
523
|
+
$unwatchState();
|
|
524
|
+
}
|
|
525
|
+
if ($fieldStatus.value) {
|
|
526
|
+
$fieldStatus.value.$unwatch();
|
|
527
|
+
}
|
|
528
|
+
if ($eachStatus.value) {
|
|
529
|
+
$eachStatus.value.forEach((element) => {
|
|
530
|
+
element.$unwatch();
|
|
342
531
|
});
|
|
343
532
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
533
|
+
}
|
|
534
|
+
function $watch() {
|
|
535
|
+
$unwatchState = watch3(
|
|
536
|
+
state,
|
|
537
|
+
() => {
|
|
538
|
+
createStatus();
|
|
539
|
+
},
|
|
540
|
+
{ deep: true, flush: "sync" }
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
return reactive3({
|
|
544
|
+
...$fieldStatus.value,
|
|
545
|
+
$each: $eachStatus,
|
|
546
|
+
$unwatch,
|
|
547
|
+
$watch
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// src/core/useRegle/useStateProperties/createReactiveNestedStatus.ts
|
|
552
|
+
function createReactiveNestedStatus({
|
|
553
|
+
scopeRules,
|
|
554
|
+
state,
|
|
555
|
+
customMessages,
|
|
556
|
+
path = "",
|
|
557
|
+
rootRules,
|
|
558
|
+
storage
|
|
559
|
+
}) {
|
|
560
|
+
let scope = effectScope4();
|
|
561
|
+
let scopeState;
|
|
562
|
+
let $unwatchFields;
|
|
563
|
+
function createReactiveFieldsStatus() {
|
|
564
|
+
$fields.value = Object.fromEntries(
|
|
565
|
+
Object.entries(scopeRules.value).map(([statePropKey, statePropRules]) => {
|
|
566
|
+
if (statePropRules) {
|
|
567
|
+
const stateRef = toRef4(state.value, statePropKey);
|
|
568
|
+
const statePropRulesRef = toRef4(() => statePropRules);
|
|
569
|
+
return [
|
|
570
|
+
statePropKey,
|
|
571
|
+
createReactiveChildrenStatus({
|
|
572
|
+
state: stateRef,
|
|
573
|
+
rulesDef: statePropRulesRef,
|
|
574
|
+
customMessages,
|
|
575
|
+
path: path ? `${path}.${statePropKey}` : statePropKey,
|
|
576
|
+
storage
|
|
577
|
+
})
|
|
578
|
+
];
|
|
579
|
+
}
|
|
580
|
+
return [];
|
|
581
|
+
}).filter(
|
|
582
|
+
(rule) => !!rule.length && rule[1] != null
|
|
375
583
|
)
|
|
376
584
|
);
|
|
377
|
-
|
|
378
|
-
|
|
585
|
+
$watch();
|
|
586
|
+
}
|
|
587
|
+
const $fields = storage.getFieldsEntry(path);
|
|
588
|
+
createReactiveFieldsStatus();
|
|
589
|
+
function $reset() {
|
|
590
|
+
Object.entries($fields.value).forEach(([_, statusOrField]) => {
|
|
591
|
+
statusOrField.$reset();
|
|
379
592
|
});
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
593
|
+
}
|
|
594
|
+
function $touch() {
|
|
595
|
+
Object.entries($fields.value).forEach(([_, statusOrField]) => {
|
|
596
|
+
statusOrField.$touch();
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
async function $validate() {
|
|
600
|
+
try {
|
|
601
|
+
const results = await Promise.all(
|
|
602
|
+
Object.entries($fields.value).map(([_, statusOrField]) => {
|
|
603
|
+
return statusOrField.$validate();
|
|
604
|
+
})
|
|
605
|
+
);
|
|
606
|
+
return results.every((value) => !!value);
|
|
607
|
+
} catch (e) {
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
function $watch() {
|
|
612
|
+
if (rootRules) {
|
|
613
|
+
$unwatchFields = watch4(
|
|
614
|
+
rootRules,
|
|
615
|
+
() => {
|
|
616
|
+
$unwatch();
|
|
617
|
+
createReactiveFieldsStatus();
|
|
618
|
+
},
|
|
619
|
+
{ deep: true, flush: "post" }
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
scopeState = scope.run(() => {
|
|
623
|
+
const $dirty = computed4(() => {
|
|
624
|
+
return Object.entries($fields.value).every(([key, statusOrField]) => {
|
|
625
|
+
return statusOrField.$dirty;
|
|
626
|
+
});
|
|
627
|
+
});
|
|
628
|
+
const $anyDirty = computed4(() => {
|
|
629
|
+
return Object.entries($fields.value).some(([key, statusOrField]) => {
|
|
630
|
+
return statusOrField.$dirty;
|
|
631
|
+
});
|
|
632
|
+
});
|
|
633
|
+
const $invalid = computed4(() => {
|
|
634
|
+
return Object.entries($fields.value).some(([key, statusOrField]) => {
|
|
635
|
+
return statusOrField.$invalid;
|
|
636
|
+
});
|
|
637
|
+
});
|
|
638
|
+
const $valid = computed4(() => !$invalid.value);
|
|
639
|
+
const $error = computed4(() => {
|
|
640
|
+
return Object.entries($fields.value).some(([key, statusOrField]) => {
|
|
641
|
+
return statusOrField.$error;
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
const $pending = computed4(() => {
|
|
645
|
+
return Object.entries($fields.value).some(([key, statusOrField]) => {
|
|
646
|
+
return statusOrField.$pending;
|
|
647
|
+
});
|
|
383
648
|
});
|
|
649
|
+
return {
|
|
650
|
+
$dirty,
|
|
651
|
+
$anyDirty,
|
|
652
|
+
$invalid,
|
|
653
|
+
$valid,
|
|
654
|
+
$error,
|
|
655
|
+
$pending
|
|
656
|
+
};
|
|
384
657
|
});
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
658
|
+
}
|
|
659
|
+
function $unwatch() {
|
|
660
|
+
if ($fields.value) {
|
|
661
|
+
Object.entries($fields.value).forEach(([_, field]) => {
|
|
662
|
+
field.$unwatch();
|
|
388
663
|
});
|
|
664
|
+
}
|
|
665
|
+
if ($unwatchFields) {
|
|
666
|
+
$unwatchFields();
|
|
667
|
+
}
|
|
668
|
+
scope.stop();
|
|
669
|
+
scope = effectScope4();
|
|
670
|
+
scopeState = null;
|
|
671
|
+
}
|
|
672
|
+
return reactive4({
|
|
673
|
+
...scopeState,
|
|
674
|
+
$fields,
|
|
675
|
+
$reset,
|
|
676
|
+
$touch,
|
|
677
|
+
$validate,
|
|
678
|
+
$unwatch,
|
|
679
|
+
$watch
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
function createReactiveChildrenStatus({
|
|
683
|
+
state,
|
|
684
|
+
rulesDef,
|
|
685
|
+
customMessages,
|
|
686
|
+
path,
|
|
687
|
+
storage
|
|
688
|
+
}) {
|
|
689
|
+
if (isCollectionRulesDef(rulesDef)) {
|
|
690
|
+
return createReactiveCollectionStatus({
|
|
691
|
+
state,
|
|
692
|
+
rulesDef,
|
|
693
|
+
customMessages,
|
|
694
|
+
path,
|
|
695
|
+
storage
|
|
389
696
|
});
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
697
|
+
} else if (isNestedRulesDef(state, rulesDef) && isRefObject(state)) {
|
|
698
|
+
return createReactiveNestedStatus({
|
|
699
|
+
scopeRules: rulesDef,
|
|
700
|
+
state,
|
|
701
|
+
customMessages,
|
|
702
|
+
path,
|
|
703
|
+
storage
|
|
396
704
|
});
|
|
397
|
-
|
|
398
|
-
return
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
$valid,
|
|
405
|
-
$reset: $reset2,
|
|
406
|
-
$touch: $touch2,
|
|
407
|
-
$value: state,
|
|
408
|
-
$rules
|
|
705
|
+
} else if (isValidatorRulesDef(rulesDef)) {
|
|
706
|
+
return createReactiveFieldStatus({
|
|
707
|
+
state,
|
|
708
|
+
rulesDef,
|
|
709
|
+
customMessages,
|
|
710
|
+
path,
|
|
711
|
+
storage
|
|
409
712
|
});
|
|
410
713
|
}
|
|
411
714
|
return null;
|
|
412
715
|
}
|
|
413
716
|
|
|
414
|
-
// src/core/
|
|
415
|
-
import {
|
|
416
|
-
function
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
717
|
+
// src/core/useStorage/useStorage.ts
|
|
718
|
+
import { ref as ref5, shallowRef } from "vue";
|
|
719
|
+
function useStorage() {
|
|
720
|
+
const ruleDeclStorage = shallowRef(/* @__PURE__ */ new Map());
|
|
721
|
+
const fieldsStorage = shallowRef(
|
|
722
|
+
/* @__PURE__ */ new Map()
|
|
723
|
+
);
|
|
724
|
+
const collectionsStorage = shallowRef(/* @__PURE__ */ new Map());
|
|
725
|
+
const dirtyStorage = shallowRef(/* @__PURE__ */ new Map());
|
|
726
|
+
const ruleStatusStorage = shallowRef(/* @__PURE__ */ new Map());
|
|
727
|
+
function getFieldsEntry($path) {
|
|
728
|
+
const existingFields = fieldsStorage.value.get($path);
|
|
729
|
+
if (existingFields) {
|
|
730
|
+
return existingFields;
|
|
731
|
+
} else {
|
|
732
|
+
const $fields = ref5({});
|
|
733
|
+
fieldsStorage.value.set($path, $fields);
|
|
734
|
+
return $fields;
|
|
420
735
|
}
|
|
421
|
-
return null;
|
|
422
|
-
}).filter((msg) => !!msg);
|
|
423
|
-
}
|
|
424
|
-
function processFieldErrors(fieldStatus) {
|
|
425
|
-
if (isNestedRulesStatus(fieldStatus)) {
|
|
426
|
-
return extractNestedErrors(fieldStatus.$fields);
|
|
427
|
-
} else if (isCollectionRulesStatus(fieldStatus)) {
|
|
428
|
-
return {
|
|
429
|
-
$errors: fieldStatus.$error ? extractRulesErrors(fieldStatus.$rules) : [],
|
|
430
|
-
$each: fieldStatus.$each.map(processFieldErrors)
|
|
431
|
-
};
|
|
432
|
-
} else if (isFieldStatus(fieldStatus) && fieldStatus.$error) {
|
|
433
|
-
return extractRulesErrors(fieldStatus.$rules);
|
|
434
736
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
return
|
|
463
|
-
}
|
|
464
|
-
|
|
737
|
+
function getCollectionsEntry($path) {
|
|
738
|
+
const existingEach = collectionsStorage.value.get($path);
|
|
739
|
+
if (existingEach) {
|
|
740
|
+
return existingEach;
|
|
741
|
+
} else {
|
|
742
|
+
const $each = ref5([]);
|
|
743
|
+
collectionsStorage.value.set($path, $each);
|
|
744
|
+
return $each;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
function setDirtyEntry($path, dirty) {
|
|
748
|
+
dirtyStorage.value.set($path, dirty);
|
|
749
|
+
}
|
|
750
|
+
function getDirtyState(path) {
|
|
751
|
+
return dirtyStorage.value.get(path) ?? false;
|
|
752
|
+
}
|
|
753
|
+
function addRuleDeclEntry($path, options) {
|
|
754
|
+
ruleDeclStorage.value.set($path, options);
|
|
755
|
+
}
|
|
756
|
+
function checkRuleDeclEntry($path, newRules) {
|
|
757
|
+
const storedRulesDefs = ruleDeclStorage.value.get($path);
|
|
758
|
+
if (!storedRulesDefs)
|
|
759
|
+
return void 0;
|
|
760
|
+
const storedRules = storedRulesDefs;
|
|
761
|
+
const isValidCache = areRulesChanged(newRules, storedRules);
|
|
762
|
+
if (!isValidCache)
|
|
763
|
+
return { valid: false };
|
|
764
|
+
return { valid: true };
|
|
765
|
+
}
|
|
766
|
+
function areRulesChanged(newRules, storedRules) {
|
|
767
|
+
const storedRulesKeys = Object.keys(storedRules);
|
|
768
|
+
const newRulesKeys = Object.keys(newRules);
|
|
769
|
+
if (newRulesKeys.length !== storedRulesKeys.length)
|
|
770
|
+
return false;
|
|
771
|
+
const hasAllValidators = newRulesKeys.every((ruleKey) => storedRulesKeys.includes(ruleKey));
|
|
772
|
+
if (!hasAllValidators)
|
|
773
|
+
return false;
|
|
774
|
+
return newRulesKeys.every((ruleKey) => {
|
|
775
|
+
const newRuleElement = newRules[ruleKey];
|
|
776
|
+
const storedRuleElement = storedRules[ruleKey];
|
|
777
|
+
if (!storedRuleElement || !newRuleElement || typeof newRuleElement === "function" || typeof storedRuleElement === "function")
|
|
778
|
+
return false;
|
|
779
|
+
if (!newRuleElement._params)
|
|
780
|
+
return true;
|
|
781
|
+
return newRuleElement._params?.every((paramKey, index) => {
|
|
782
|
+
const storedParams = unwrapRuleParameters(storedRuleElement._params);
|
|
783
|
+
const newParams = unwrapRuleParameters(newRuleElement._params);
|
|
784
|
+
return storedParams?.[index] === newParams?.[index];
|
|
785
|
+
});
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
function trySetRuleStatusRef(path) {
|
|
789
|
+
const ruleStatus = ruleStatusStorage.value.get(path);
|
|
790
|
+
if (ruleStatus) {
|
|
791
|
+
return ruleStatus;
|
|
792
|
+
} else {
|
|
793
|
+
const $pending = ref5(false);
|
|
794
|
+
const $valid = ref5(true);
|
|
795
|
+
ruleStatusStorage.value.set(path, { $pending, $valid });
|
|
796
|
+
return { $pending, $valid };
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
return {
|
|
800
|
+
addRuleDeclEntry,
|
|
801
|
+
setDirtyEntry,
|
|
802
|
+
checkRuleDeclEntry,
|
|
803
|
+
getDirtyState,
|
|
804
|
+
trySetRuleStatusRef,
|
|
805
|
+
getFieldsEntry,
|
|
806
|
+
getCollectionsEntry
|
|
807
|
+
};
|
|
465
808
|
}
|
|
466
809
|
|
|
467
810
|
// src/core/useRegle/useStateProperties/useStateProperties.ts
|
|
468
811
|
function useStateProperties(scopeRules, state, customRules) {
|
|
469
|
-
const
|
|
812
|
+
const storage = useStorage();
|
|
813
|
+
const $regle = reactive5(
|
|
814
|
+
createReactiveNestedStatus({
|
|
815
|
+
rootRules: scopeRules,
|
|
816
|
+
scopeRules,
|
|
817
|
+
state,
|
|
818
|
+
customMessages: customRules(),
|
|
819
|
+
storage
|
|
820
|
+
})
|
|
821
|
+
);
|
|
470
822
|
const errors = useErrors($regle);
|
|
471
823
|
return { $regle, errors };
|
|
472
824
|
}
|
|
@@ -474,17 +826,27 @@ function useStateProperties(scopeRules, state, customRules) {
|
|
|
474
826
|
// src/core/useRegle/useRegle.ts
|
|
475
827
|
function createUseRegleComposable(customRules) {
|
|
476
828
|
function useRegle(state, rulesFactory) {
|
|
477
|
-
const scopeRules =
|
|
478
|
-
const initialState =
|
|
829
|
+
const scopeRules = isRef2(rulesFactory) ? rulesFactory : computed5(rulesFactory);
|
|
830
|
+
const initialState = shallowRef2(structuredClone(toRaw(state.value)));
|
|
479
831
|
const { $regle, errors } = useStateProperties(
|
|
480
832
|
scopeRules,
|
|
481
833
|
state,
|
|
482
834
|
customRules
|
|
483
835
|
);
|
|
836
|
+
function resetForm() {
|
|
837
|
+
state.value = toRaw(initialState.value);
|
|
838
|
+
$regle.$reset();
|
|
839
|
+
}
|
|
840
|
+
async function validateForm() {
|
|
841
|
+
$regle.$touch();
|
|
842
|
+
return await $regle.$validate();
|
|
843
|
+
}
|
|
484
844
|
return {
|
|
485
845
|
state,
|
|
486
846
|
$regle,
|
|
487
|
-
errors
|
|
847
|
+
errors,
|
|
848
|
+
resetForm,
|
|
849
|
+
validateForm
|
|
488
850
|
};
|
|
489
851
|
}
|
|
490
852
|
return useRegle;
|