vee-validate 4.15.0 → 5.0.0-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/README.md +178 -178
- package/dist/vee-validate.cjs +100 -116
- package/dist/vee-validate.d.ts +44 -50
- package/dist/vee-validate.iife.js +100 -116
- package/dist/vee-validate.iife.prod.js.mjs +3 -3
- package/dist/vee-validate.mjs +101 -117
- package/package.json +3 -1
package/dist/vee-validate.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vee-validate
|
|
3
|
-
* (c)
|
|
2
|
+
* vee-validate v5.0.0-beta.0
|
|
3
|
+
* (c) 2025 Abdelrahman Awad
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
6
6
|
import { getCurrentInstance, inject, warn as warn$1, computed, toValue, ref, watch, nextTick, unref, isRef, reactive, onUnmounted, onMounted, provide, onBeforeUnmount, defineComponent, toRef, resolveDynamicComponent, h, readonly, watchEffect, shallowRef } from 'vue';
|
|
@@ -162,11 +162,8 @@ const isClient = typeof window !== 'undefined';
|
|
|
162
162
|
function isLocator(value) {
|
|
163
163
|
return isCallable(value) && !!value.__locatorRef;
|
|
164
164
|
}
|
|
165
|
-
function
|
|
166
|
-
return
|
|
167
|
-
}
|
|
168
|
-
function isYupValidator(value) {
|
|
169
|
-
return !!value && isCallable(value.validate);
|
|
165
|
+
function isStandardSchema(value) {
|
|
166
|
+
return isObject(value) && '~standard' in value;
|
|
170
167
|
}
|
|
171
168
|
function hasCheckedAttr(type) {
|
|
172
169
|
return type === 'checkbox' || type === 'radio';
|
|
@@ -310,14 +307,16 @@ function isEqual(a, b) {
|
|
|
310
307
|
return a.valueOf() === b.valueOf();
|
|
311
308
|
if (a.toString !== Object.prototype.toString)
|
|
312
309
|
return a.toString() === b.toString();
|
|
310
|
+
// Remove undefined values before object comparison
|
|
311
|
+
a = normalizeObject(a);
|
|
312
|
+
b = normalizeObject(b);
|
|
313
313
|
keys = Object.keys(a);
|
|
314
|
-
length = keys.length
|
|
315
|
-
if (length !== Object.keys(b).length
|
|
314
|
+
length = keys.length;
|
|
315
|
+
if (length !== Object.keys(b).length)
|
|
316
316
|
return false;
|
|
317
|
-
for (i = length; i-- !== 0;)
|
|
317
|
+
for (i = length; i-- !== 0;)
|
|
318
318
|
if (!Object.prototype.hasOwnProperty.call(b, keys[i]))
|
|
319
319
|
return false;
|
|
320
|
-
}
|
|
321
320
|
for (i = length; i-- !== 0;) {
|
|
322
321
|
// eslint-disable-next-line no-var
|
|
323
322
|
var key = keys[i];
|
|
@@ -329,15 +328,13 @@ function isEqual(a, b) {
|
|
|
329
328
|
// true if both NaN, false otherwise
|
|
330
329
|
return a !== a && b !== b;
|
|
331
330
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
return result;
|
|
331
|
+
/**
|
|
332
|
+
* Returns a new object where keys with an `undefined` value are removed.
|
|
333
|
+
*
|
|
334
|
+
* @param a object to normalize
|
|
335
|
+
*/
|
|
336
|
+
function normalizeObject(a) {
|
|
337
|
+
return Object.fromEntries(Object.entries(a).filter(([, value]) => value !== undefined));
|
|
341
338
|
}
|
|
342
339
|
function isFile(a) {
|
|
343
340
|
if (!isClient) {
|
|
@@ -346,6 +343,27 @@ function isFile(a) {
|
|
|
346
343
|
return a instanceof File;
|
|
347
344
|
}
|
|
348
345
|
|
|
346
|
+
// src/getDotPath/getDotPath.ts
|
|
347
|
+
function getDotPath(issue) {
|
|
348
|
+
if (issue.path?.length) {
|
|
349
|
+
let dotPath = "";
|
|
350
|
+
for (const item of issue.path) {
|
|
351
|
+
const key = typeof item === "object" ? item.key : item;
|
|
352
|
+
if (typeof key === "string" || typeof key === "number") {
|
|
353
|
+
if (dotPath) {
|
|
354
|
+
dotPath += `.${key}`;
|
|
355
|
+
} else {
|
|
356
|
+
dotPath += key;
|
|
357
|
+
}
|
|
358
|
+
} else {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return dotPath;
|
|
363
|
+
}
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
|
|
349
367
|
function cleanupNonNestedPath(path) {
|
|
350
368
|
if (isNotNestedPath(path)) {
|
|
351
369
|
return path.replace(/\[|\]/gi, '');
|
|
@@ -586,6 +604,31 @@ function debounceNextTick(inner) {
|
|
|
586
604
|
return new Promise(resolve => resolves.push(resolve));
|
|
587
605
|
};
|
|
588
606
|
}
|
|
607
|
+
function _combineIssueItems(items, getPath) {
|
|
608
|
+
const issueMap = {};
|
|
609
|
+
for (const item of items) {
|
|
610
|
+
const path = getPath(item);
|
|
611
|
+
if (!issueMap[path]) {
|
|
612
|
+
issueMap[path] = {
|
|
613
|
+
path,
|
|
614
|
+
messages: [],
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
if ('messages' in item) {
|
|
618
|
+
issueMap[path].messages.push(...item.messages);
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
issueMap[path].messages.push(item.message);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
return Object.values(issueMap);
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Aggregates standard schema issues by path.
|
|
628
|
+
*/
|
|
629
|
+
function combineStandardIssues(issues) {
|
|
630
|
+
return _combineIssueItems(issues, issue => { var _a; return (issue.path ? (_a = getDotPath(issue)) !== null && _a !== void 0 ? _a : '' : ''); });
|
|
631
|
+
}
|
|
589
632
|
|
|
590
633
|
function normalizeChildren(tag, context, slotProps) {
|
|
591
634
|
if (!context.slots.default) {
|
|
@@ -792,8 +835,8 @@ async function validate(value, rules, options = {}) {
|
|
|
792
835
|
*/
|
|
793
836
|
async function _validate(field, value) {
|
|
794
837
|
const rules = field.rules;
|
|
795
|
-
if (
|
|
796
|
-
return
|
|
838
|
+
if (isStandardSchema(rules)) {
|
|
839
|
+
return validateFieldWithStandardSchema(value, Object.assign(Object.assign({}, field), { rules }));
|
|
797
840
|
}
|
|
798
841
|
// if a generic function or chain of generic functions
|
|
799
842
|
if (isCallable(rules) || Array.isArray(rules)) {
|
|
@@ -855,58 +898,24 @@ async function _validate(field, value) {
|
|
|
855
898
|
errors,
|
|
856
899
|
};
|
|
857
900
|
}
|
|
858
|
-
function isYupError(err) {
|
|
859
|
-
return !!err && err.name === 'ValidationError';
|
|
860
|
-
}
|
|
861
|
-
function yupToTypedSchema(yupSchema) {
|
|
862
|
-
const schema = {
|
|
863
|
-
__type: 'VVTypedSchema',
|
|
864
|
-
async parse(values, context) {
|
|
865
|
-
var _a;
|
|
866
|
-
try {
|
|
867
|
-
const output = await yupSchema.validate(values, { abortEarly: false, context: (context === null || context === void 0 ? void 0 : context.formData) || {} });
|
|
868
|
-
return {
|
|
869
|
-
output,
|
|
870
|
-
errors: [],
|
|
871
|
-
};
|
|
872
|
-
}
|
|
873
|
-
catch (err) {
|
|
874
|
-
// Yup errors have a name prop one them.
|
|
875
|
-
// https://github.com/jquense/yup#validationerrorerrors-string--arraystring-value-any-path-string
|
|
876
|
-
if (!isYupError(err)) {
|
|
877
|
-
throw err;
|
|
878
|
-
}
|
|
879
|
-
if (!((_a = err.inner) === null || _a === void 0 ? void 0 : _a.length) && err.errors.length) {
|
|
880
|
-
return { errors: [{ path: err.path, errors: err.errors }] };
|
|
881
|
-
}
|
|
882
|
-
const errors = err.inner.reduce((acc, curr) => {
|
|
883
|
-
const path = curr.path || '';
|
|
884
|
-
if (!acc[path]) {
|
|
885
|
-
acc[path] = { errors: [], path };
|
|
886
|
-
}
|
|
887
|
-
acc[path].errors.push(...curr.errors);
|
|
888
|
-
return acc;
|
|
889
|
-
}, {});
|
|
890
|
-
return { errors: Object.values(errors) };
|
|
891
|
-
}
|
|
892
|
-
},
|
|
893
|
-
};
|
|
894
|
-
return schema;
|
|
895
|
-
}
|
|
896
901
|
/**
|
|
897
902
|
* Handles yup validation
|
|
898
903
|
*/
|
|
899
|
-
async function
|
|
900
|
-
const
|
|
901
|
-
|
|
904
|
+
async function validateFieldWithStandardSchema(value, context) {
|
|
905
|
+
const result = await context.rules['~standard'].validate(value);
|
|
906
|
+
if (!result.issues) {
|
|
907
|
+
return {
|
|
908
|
+
value: result.value,
|
|
909
|
+
errors: [],
|
|
910
|
+
};
|
|
911
|
+
}
|
|
902
912
|
const messages = [];
|
|
903
|
-
for (const error of result.
|
|
904
|
-
if (error.
|
|
905
|
-
messages.push(
|
|
913
|
+
for (const error of result.issues) {
|
|
914
|
+
if (error.message) {
|
|
915
|
+
messages.push(error.message);
|
|
906
916
|
}
|
|
907
917
|
}
|
|
908
918
|
return {
|
|
909
|
-
value: result.value,
|
|
910
919
|
errors: messages,
|
|
911
920
|
};
|
|
912
921
|
}
|
|
@@ -962,27 +971,33 @@ function fillTargetValues(params, crossTable) {
|
|
|
962
971
|
return acc;
|
|
963
972
|
}, {});
|
|
964
973
|
}
|
|
965
|
-
async function
|
|
966
|
-
const
|
|
967
|
-
const validationResult = await typedSchema.parse(klona(values), { formData: klona(values) });
|
|
974
|
+
async function validateStandardSchema(schema, values) {
|
|
975
|
+
const validationResult = await schema['~standard'].validate(klona(values));
|
|
968
976
|
const results = {};
|
|
969
977
|
const errors = {};
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
978
|
+
if (!validationResult.issues) {
|
|
979
|
+
return {
|
|
980
|
+
valid: true,
|
|
981
|
+
results: {},
|
|
982
|
+
errors: {},
|
|
983
|
+
values: validationResult.value,
|
|
984
|
+
source: 'schema',
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
const combinedIssues = combineStandardIssues(validationResult.issues || []);
|
|
988
|
+
for (const error of combinedIssues) {
|
|
989
|
+
const messages = error.messages;
|
|
990
|
+
const path = error.path;
|
|
976
991
|
results[path] = { valid: !messages.length, errors: messages };
|
|
977
992
|
if (messages.length) {
|
|
978
993
|
errors[path] = messages[0];
|
|
979
994
|
}
|
|
980
995
|
}
|
|
981
996
|
return {
|
|
982
|
-
valid: !
|
|
997
|
+
valid: !combinedIssues.length,
|
|
983
998
|
results,
|
|
984
999
|
errors,
|
|
985
|
-
values:
|
|
1000
|
+
values: undefined,
|
|
986
1001
|
source: 'schema',
|
|
987
1002
|
};
|
|
988
1003
|
}
|
|
@@ -1027,7 +1042,7 @@ function useFieldState(path, init) {
|
|
|
1027
1042
|
if (!init.form) {
|
|
1028
1043
|
const { errors, setErrors } = createFieldErrors();
|
|
1029
1044
|
const id = ID_COUNTER >= Number.MAX_SAFE_INTEGER ? 0 : ++ID_COUNTER;
|
|
1030
|
-
const meta = createFieldMeta(value, initialValue, errors
|
|
1045
|
+
const meta = createFieldMeta(value, initialValue, errors);
|
|
1031
1046
|
function setState(state) {
|
|
1032
1047
|
var _a;
|
|
1033
1048
|
if ('value' in state) {
|
|
@@ -1059,7 +1074,6 @@ function useFieldState(path, init) {
|
|
|
1059
1074
|
label: init.label,
|
|
1060
1075
|
type: init.type,
|
|
1061
1076
|
validate: init.validate,
|
|
1062
|
-
schema: init.schema,
|
|
1063
1077
|
});
|
|
1064
1078
|
const errors = computed(() => state.errors);
|
|
1065
1079
|
function setState(state) {
|
|
@@ -1155,13 +1169,11 @@ function resolveModelValue(modelValue, form, initialValue, path) {
|
|
|
1155
1169
|
/**
|
|
1156
1170
|
* Creates meta flags state and some associated effects with them
|
|
1157
1171
|
*/
|
|
1158
|
-
function createFieldMeta(currentValue, initialValue, errors
|
|
1159
|
-
const isRequired = computed(() => { var _a, _b, _c; return (_c = (_b = (_a = toValue(schema)) === null || _a === void 0 ? void 0 : _a.describe) === null || _b === void 0 ? void 0 : _b.call(_a).required) !== null && _c !== void 0 ? _c : false; });
|
|
1172
|
+
function createFieldMeta(currentValue, initialValue, errors) {
|
|
1160
1173
|
const meta = reactive({
|
|
1161
1174
|
touched: false,
|
|
1162
1175
|
pending: false,
|
|
1163
1176
|
valid: true,
|
|
1164
|
-
required: isRequired,
|
|
1165
1177
|
validated: !!unref(errors).length,
|
|
1166
1178
|
initialValue: computed(() => unref(initialValue)),
|
|
1167
1179
|
dirty: computed(() => {
|
|
@@ -1220,7 +1232,7 @@ async function installDevtoolsPlugin(app) {
|
|
|
1220
1232
|
packageName: 'vee-validate',
|
|
1221
1233
|
homepage: 'https://vee-validate.logaretm.com/v4',
|
|
1222
1234
|
app,
|
|
1223
|
-
logo: 'https://vee-validate.logaretm.com/
|
|
1235
|
+
logo: 'https://vee-validate.logaretm.com/v5/logo.png',
|
|
1224
1236
|
}, api => {
|
|
1225
1237
|
API = api;
|
|
1226
1238
|
api.addInspector({
|
|
@@ -1604,15 +1616,11 @@ function _useField(path, rules, opts) {
|
|
|
1604
1616
|
return undefined;
|
|
1605
1617
|
}
|
|
1606
1618
|
const rulesValue = unref(rules);
|
|
1607
|
-
if (
|
|
1608
|
-
isTypedSchema(rulesValue) ||
|
|
1609
|
-
isCallable(rulesValue) ||
|
|
1610
|
-
Array.isArray(rulesValue)) {
|
|
1619
|
+
if (isStandardSchema(rulesValue) || isCallable(rulesValue) || Array.isArray(rulesValue)) {
|
|
1611
1620
|
return rulesValue;
|
|
1612
1621
|
}
|
|
1613
1622
|
return normalizeRules(rulesValue);
|
|
1614
1623
|
});
|
|
1615
|
-
const isTyped = !isCallable(validator.value) && isTypedSchema(toValue(rules));
|
|
1616
1624
|
const { id, value, initialValue, meta, setState, errors, flags } = useFieldState(name, {
|
|
1617
1625
|
modelValue,
|
|
1618
1626
|
form,
|
|
@@ -1620,7 +1628,6 @@ function _useField(path, rules, opts) {
|
|
|
1620
1628
|
label,
|
|
1621
1629
|
type,
|
|
1622
1630
|
validate: validator.value ? validate$1 : undefined,
|
|
1623
|
-
schema: isTyped ? rules : undefined,
|
|
1624
1631
|
});
|
|
1625
1632
|
const errorMessage = computed(() => errors.value[0]);
|
|
1626
1633
|
if (syncVModel) {
|
|
@@ -1781,12 +1788,8 @@ function _useField(path, rules, opts) {
|
|
|
1781
1788
|
// extract cross-field dependencies in a computed prop
|
|
1782
1789
|
const dependencies = computed(() => {
|
|
1783
1790
|
const rulesVal = validator.value;
|
|
1784
|
-
// is falsy, a function schema or a
|
|
1785
|
-
if (!rulesVal ||
|
|
1786
|
-
isCallable(rulesVal) ||
|
|
1787
|
-
isYupValidator(rulesVal) ||
|
|
1788
|
-
isTypedSchema(rulesVal) ||
|
|
1789
|
-
Array.isArray(rulesVal)) {
|
|
1791
|
+
// is falsy, a function schema or a standard schema
|
|
1792
|
+
if (!rulesVal || isCallable(rulesVal) || isStandardSchema(rulesVal) || Array.isArray(rulesVal)) {
|
|
1790
1793
|
return {};
|
|
1791
1794
|
}
|
|
1792
1795
|
return Object.keys(rulesVal).reduce((acc, rule) => {
|
|
@@ -2165,10 +2168,6 @@ const PRIVATE_PATH_STATE_KEYS = ['bails', 'fieldsCount', 'id', 'multiple', 'type
|
|
|
2165
2168
|
function resolveInitialValues(opts) {
|
|
2166
2169
|
const givenInitial = (opts === null || opts === void 0 ? void 0 : opts.initialValues) || {};
|
|
2167
2170
|
const providedValues = Object.assign({}, toValue(givenInitial));
|
|
2168
|
-
const schema = unref(opts === null || opts === void 0 ? void 0 : opts.validationSchema);
|
|
2169
|
-
if (schema && isTypedSchema(schema) && isCallable(schema.cast)) {
|
|
2170
|
-
return klona(schema.cast(providedValues) || {});
|
|
2171
|
-
}
|
|
2172
2171
|
return klona(providedValues);
|
|
2173
2172
|
}
|
|
2174
2173
|
function useForm(opts) {
|
|
@@ -2303,19 +2302,6 @@ function useForm(opts) {
|
|
|
2303
2302
|
if (unsetBatchIndex !== -1) {
|
|
2304
2303
|
UNSET_BATCH.splice(unsetBatchIndex, 1);
|
|
2305
2304
|
}
|
|
2306
|
-
const isRequired = computed(() => {
|
|
2307
|
-
var _a, _b, _c, _d;
|
|
2308
|
-
const schemaValue = toValue(schema);
|
|
2309
|
-
if (isTypedSchema(schemaValue)) {
|
|
2310
|
-
return (_b = (_a = schemaValue.describe) === null || _a === void 0 ? void 0 : _a.call(schemaValue, toValue(path)).required) !== null && _b !== void 0 ? _b : false;
|
|
2311
|
-
}
|
|
2312
|
-
// Path own schema
|
|
2313
|
-
const configSchemaValue = toValue(config === null || config === void 0 ? void 0 : config.schema);
|
|
2314
|
-
if (isTypedSchema(configSchemaValue)) {
|
|
2315
|
-
return (_d = (_c = configSchemaValue.describe) === null || _c === void 0 ? void 0 : _c.call(configSchemaValue).required) !== null && _d !== void 0 ? _d : false;
|
|
2316
|
-
}
|
|
2317
|
-
return false;
|
|
2318
|
-
});
|
|
2319
2305
|
const id = FIELD_ID_COUNTER++;
|
|
2320
2306
|
const state = reactive({
|
|
2321
2307
|
id,
|
|
@@ -2324,7 +2310,6 @@ function useForm(opts) {
|
|
|
2324
2310
|
pending: false,
|
|
2325
2311
|
valid: true,
|
|
2326
2312
|
validated: !!((_a = initialErrors[pathValue]) === null || _a === void 0 ? void 0 : _a.length),
|
|
2327
|
-
required: isRequired,
|
|
2328
2313
|
initialValue,
|
|
2329
2314
|
errors: shallowRef([]),
|
|
2330
2315
|
bails: (_b = config === null || config === void 0 ? void 0 : config.bails) !== null && _b !== void 0 ? _b : false,
|
|
@@ -2737,7 +2722,6 @@ function useForm(opts) {
|
|
|
2737
2722
|
function resetForm(resetState, opts) {
|
|
2738
2723
|
let newValues = klona((resetState === null || resetState === void 0 ? void 0 : resetState.values) ? resetState.values : originalInitialValues.value);
|
|
2739
2724
|
newValues = (opts === null || opts === void 0 ? void 0 : opts.force) ? newValues : merge(originalInitialValues.value, newValues);
|
|
2740
|
-
newValues = isTypedSchema(schema) && isCallable(schema.cast) ? schema.cast(newValues) : newValues;
|
|
2741
2725
|
setInitialValues(newValues, { force: opts === null || opts === void 0 ? void 0 : opts.force });
|
|
2742
2726
|
mutateAllPathState(state => {
|
|
2743
2727
|
var _a;
|
|
@@ -2855,8 +2839,8 @@ function useForm(opts) {
|
|
|
2855
2839
|
return { valid: true, results: {}, errors: {}, source: 'none' };
|
|
2856
2840
|
}
|
|
2857
2841
|
isValidating.value = true;
|
|
2858
|
-
const formResult =
|
|
2859
|
-
? await
|
|
2842
|
+
const formResult = isStandardSchema(schemaValue)
|
|
2843
|
+
? await validateStandardSchema(schemaValue, formValues)
|
|
2860
2844
|
: await validateObjectSchema(schemaValue, formValues, {
|
|
2861
2845
|
names: fieldNames.value,
|
|
2862
2846
|
bailsMap: fieldBailsMap.value,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vee-validate",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-beta.0",
|
|
4
4
|
"description": "Painless forms for Vue.js",
|
|
5
5
|
"author": "Abdelrahman Awad <logaretm1@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,6 +42,8 @@
|
|
|
42
42
|
"vue": "^3.4.26"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
+
"@standard-schema/spec": "^1.0.0",
|
|
46
|
+
"@standard-schema/utils": "^0.3.0",
|
|
45
47
|
"@vue/devtools-api": "^7.5.2",
|
|
46
48
|
"type-fest": "^4.8.3"
|
|
47
49
|
}
|