@sanity/validation 3.1.4 → 3.1.5-canary.14
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/lib/index.cjs.mjs +7 -0
- package/lib/index.esm.js +76 -46
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +91 -61
- package/lib/index.js.map +1 -1
- package/package.json +44 -30
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import cjs from './index.js';
|
|
2
|
+
|
|
3
|
+
export const Rule = cjs.Rule;
|
|
4
|
+
export const inferFromSchema = cjs.inferFromSchema;
|
|
5
|
+
export const inferFromSchemaType = cjs.inferFromSchemaType;
|
|
6
|
+
export const validateDocument = cjs.validateDocument;
|
|
7
|
+
export const validateDocumentObservable = cjs.validateDocumentObservable;
|
package/lib/index.esm.js
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
const _excluded = ["value", "type", "path", "parent"];
|
|
2
|
-
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
3
|
-
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
4
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
5
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
6
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
7
1
|
import cloneDeep from 'lodash/cloneDeep.js';
|
|
8
2
|
import get from 'lodash/get.js';
|
|
9
3
|
import { isKeyedObject, isReference, isPortableTextTextBlock, isBlockSchemaType, isSpanSchemaType, isTypedObject } from '@sanity/types';
|
|
@@ -227,16 +221,18 @@ const genericValidators = {
|
|
|
227
221
|
return result;
|
|
228
222
|
}
|
|
229
223
|
};
|
|
230
|
-
const booleanValidators =
|
|
224
|
+
const booleanValidators = {
|
|
225
|
+
...genericValidators,
|
|
231
226
|
presence: (flag, value, message) => {
|
|
232
227
|
if (flag === "required" && typeof value !== "boolean") {
|
|
233
228
|
return message || "Required";
|
|
234
229
|
}
|
|
235
230
|
return true;
|
|
236
231
|
}
|
|
237
|
-
}
|
|
232
|
+
};
|
|
238
233
|
const precisionRx = /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/;
|
|
239
|
-
const numberValidators =
|
|
234
|
+
const numberValidators = {
|
|
235
|
+
...genericValidators,
|
|
240
236
|
integer: (_unused, value, message) => {
|
|
241
237
|
if (!Number.isInteger(value)) {
|
|
242
238
|
return message || "Must be an integer";
|
|
@@ -276,11 +272,12 @@ const numberValidators = _objectSpread(_objectSpread({}, genericValidators), {},
|
|
|
276
272
|
}
|
|
277
273
|
return message || "Must be less than ".concat(maxNum);
|
|
278
274
|
}
|
|
279
|
-
}
|
|
275
|
+
};
|
|
280
276
|
const DUMMY_ORIGIN = "http://sanity";
|
|
281
277
|
const emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
|
282
278
|
const isRelativeUrl = url => /^\.*\//.test(url);
|
|
283
|
-
const stringValidators =
|
|
279
|
+
const stringValidators = {
|
|
280
|
+
...genericValidators,
|
|
284
281
|
min: (minLength, value, message) => {
|
|
285
282
|
if (!value || value.length >= minLength) {
|
|
286
283
|
return true;
|
|
@@ -370,8 +367,9 @@ const stringValidators = _objectSpread(_objectSpread({}, genericValidators), {},
|
|
|
370
367
|
}
|
|
371
368
|
return message || "Must be a valid email address";
|
|
372
369
|
}
|
|
373
|
-
}
|
|
374
|
-
const arrayValidators =
|
|
370
|
+
};
|
|
371
|
+
const arrayValidators = {
|
|
372
|
+
...genericValidators,
|
|
375
373
|
min: (minLength, value, message) => {
|
|
376
374
|
if (!value || value.length >= minLength) {
|
|
377
375
|
return true;
|
|
@@ -447,9 +445,10 @@ const arrayValidators = _objectSpread(_objectSpread({}, genericValidators), {},
|
|
|
447
445
|
paths
|
|
448
446
|
}) : true;
|
|
449
447
|
}
|
|
450
|
-
}
|
|
448
|
+
};
|
|
451
449
|
const metaKeys = ["_key", "_type", "_weak"];
|
|
452
|
-
const objectValidators =
|
|
450
|
+
const objectValidators = {
|
|
451
|
+
...genericValidators,
|
|
453
452
|
presence: (expected, value, message) => {
|
|
454
453
|
if (expected !== "required") {
|
|
455
454
|
return true;
|
|
@@ -495,7 +494,7 @@ const objectValidators = _objectSpread(_objectSpread({}, genericValidators), {},
|
|
|
495
494
|
}
|
|
496
495
|
return true;
|
|
497
496
|
}
|
|
498
|
-
}
|
|
497
|
+
};
|
|
499
498
|
function isRecord$1(obj) {
|
|
500
499
|
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
501
500
|
}
|
|
@@ -529,7 +528,8 @@ function parseDate(date) {
|
|
|
529
528
|
}
|
|
530
529
|
return isInvalid ? null : parsed;
|
|
531
530
|
}
|
|
532
|
-
const dateValidators =
|
|
531
|
+
const dateValidators = {
|
|
532
|
+
...genericValidators,
|
|
533
533
|
type: (_unused, value, message) => {
|
|
534
534
|
const strVal = "".concat(value);
|
|
535
535
|
if (!strVal || isoDate.test(value)) {
|
|
@@ -567,7 +567,7 @@ const dateValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
|
|
|
567
567
|
const date = getFormattedDate(context.type.name, maxDate, dateTimeOptions);
|
|
568
568
|
return message || "Must be at or before ".concat(date);
|
|
569
569
|
}
|
|
570
|
-
}
|
|
570
|
+
};
|
|
571
571
|
var _a;
|
|
572
572
|
const typeValidators = {
|
|
573
573
|
Boolean: booleanValidators,
|
|
@@ -596,6 +596,7 @@ const Rule = (_a = class {
|
|
|
596
596
|
this._message = void 0;
|
|
597
597
|
this._rules = [];
|
|
598
598
|
this._fieldRules = void 0;
|
|
599
|
+
// Alias to static method, since we often have access to an _instance_ of a rule but not the actual Rule class
|
|
599
600
|
this.valueOfField = _a.valueOfField.bind(_a);
|
|
600
601
|
this._typeDef = typeDef;
|
|
601
602
|
this.reset();
|
|
@@ -673,6 +674,7 @@ const Rule = (_a = class {
|
|
|
673
674
|
newRule._level = this._level === "error" ? rule._level : this._level;
|
|
674
675
|
return newRule;
|
|
675
676
|
}
|
|
677
|
+
// Validation flag setters
|
|
676
678
|
type(targetType) {
|
|
677
679
|
const type = "".concat(targetType.slice(0, 1).toUpperCase()).concat(targetType.slice(1));
|
|
678
680
|
if (!ruleConstraintTypes$1.includes(type)) {
|
|
@@ -697,6 +699,7 @@ const Rule = (_a = class {
|
|
|
697
699
|
constraint: children
|
|
698
700
|
}]);
|
|
699
701
|
}
|
|
702
|
+
// Shared rules
|
|
700
703
|
optional() {
|
|
701
704
|
const rule = this.cloneWithRules([{
|
|
702
705
|
flag: "presence",
|
|
@@ -744,6 +747,7 @@ const Rule = (_a = class {
|
|
|
744
747
|
constraint: values
|
|
745
748
|
}]);
|
|
746
749
|
}
|
|
750
|
+
// Numbers only
|
|
747
751
|
integer() {
|
|
748
752
|
return this.cloneWithRules([{
|
|
749
753
|
flag: "integer"
|
|
@@ -779,6 +783,7 @@ const Rule = (_a = class {
|
|
|
779
783
|
constraint: num
|
|
780
784
|
}]);
|
|
781
785
|
}
|
|
786
|
+
// String only
|
|
782
787
|
uppercase() {
|
|
783
788
|
return this.cloneWithRules([{
|
|
784
789
|
flag: "stringCasing",
|
|
@@ -834,11 +839,13 @@ const Rule = (_a = class {
|
|
|
834
839
|
constraint
|
|
835
840
|
}]);
|
|
836
841
|
}
|
|
842
|
+
// Array only
|
|
837
843
|
unique() {
|
|
838
844
|
return this.cloneWithRules([{
|
|
839
845
|
flag: "unique"
|
|
840
846
|
}]);
|
|
841
847
|
}
|
|
848
|
+
// Objects only
|
|
842
849
|
reference() {
|
|
843
850
|
return this.cloneWithRules([{
|
|
844
851
|
flag: "reference"
|
|
@@ -875,7 +882,9 @@ const Rule = (_a = class {
|
|
|
875
882
|
if (valueIsEmpty && this._required === "optional") {
|
|
876
883
|
return EMPTY_ARRAY;
|
|
877
884
|
}
|
|
878
|
-
const rules =
|
|
885
|
+
const rules =
|
|
886
|
+
// Run only the _custom_ functions if the rule is not set to required or optional
|
|
887
|
+
this._required === void 0 && valueIsEmpty ? this._rules.filter(curr => curr.flag === "custom") : this._rules;
|
|
879
888
|
const validators = this._type && typeValidators[this._type] || genericValidators;
|
|
880
889
|
const results = await Promise.all(rules.map(async curr => {
|
|
881
890
|
if (curr.flag === void 0) {
|
|
@@ -992,11 +1001,12 @@ const slugValidator = async (value, context) => {
|
|
|
992
1001
|
}
|
|
993
1002
|
const options = (_a = context == null ? void 0 : context.type) == null ? void 0 : _a.options;
|
|
994
1003
|
const isUnique = (options == null ? void 0 : options.isUnique) || defaultIsUnique;
|
|
995
|
-
const slugContext =
|
|
1004
|
+
const slugContext = {
|
|
1005
|
+
...context,
|
|
996
1006
|
parent: context.parent,
|
|
997
1007
|
type: context.type,
|
|
998
1008
|
defaultIsUnique
|
|
999
|
-
}
|
|
1009
|
+
};
|
|
1000
1010
|
const wasUnique = await isUnique(slugValue, slugContext);
|
|
1001
1011
|
if (wasUnique) {
|
|
1002
1012
|
return true;
|
|
@@ -1024,7 +1034,15 @@ function baseRuleReducer(inputRule, type) {
|
|
|
1024
1034
|
if (isRuleConstraint(type.jsonType)) {
|
|
1025
1035
|
baseRule = baseRule.type(type.jsonType);
|
|
1026
1036
|
}
|
|
1027
|
-
const typeOptionsList =
|
|
1037
|
+
const typeOptionsList =
|
|
1038
|
+
// if type.options is truthy
|
|
1039
|
+
(type == null ? void 0 : type.options) &&
|
|
1040
|
+
// and type.options is an object (non-null from the previous)
|
|
1041
|
+
typeof type.options === "object" &&
|
|
1042
|
+
// and if `list` is in options
|
|
1043
|
+
"list" in type.options &&
|
|
1044
|
+
// then finally access the list
|
|
1045
|
+
type.options.list;
|
|
1028
1046
|
if (Array.isArray(typeOptionsList)) {
|
|
1029
1047
|
baseRule = baseRule.valid(typeOptionsList.map(option => extractValueFromListOption(option, type)));
|
|
1030
1048
|
}
|
|
@@ -1053,23 +1071,27 @@ function normalizeValidationRules(typeDef) {
|
|
|
1053
1071
|
}
|
|
1054
1072
|
const validation = typeDef.validation;
|
|
1055
1073
|
if (Array.isArray(validation)) {
|
|
1056
|
-
return validation.flatMap(i => normalizeValidationRules(
|
|
1074
|
+
return validation.flatMap(i => normalizeValidationRules({
|
|
1075
|
+
...typeDef,
|
|
1057
1076
|
validation: i
|
|
1058
|
-
}))
|
|
1077
|
+
}));
|
|
1059
1078
|
}
|
|
1060
1079
|
if (validation instanceof Rule) {
|
|
1061
1080
|
return [validation];
|
|
1062
1081
|
}
|
|
1063
|
-
const baseRule =
|
|
1082
|
+
const baseRule =
|
|
1083
|
+
// using an object + Object.values to de-dupe the type chain by type name
|
|
1084
|
+
Object.values(getTypeChain(typeDef, /* @__PURE__ */new Set()).reduce((acc, type) => {
|
|
1064
1085
|
acc[type.name] = type;
|
|
1065
1086
|
return acc;
|
|
1066
1087
|
}, {})).reduce(baseRuleReducer, new Rule(typeDef));
|
|
1067
1088
|
if (!validation) {
|
|
1068
1089
|
return [baseRule];
|
|
1069
1090
|
}
|
|
1070
|
-
return normalizeValidationRules(
|
|
1091
|
+
return normalizeValidationRules({
|
|
1092
|
+
...typeDef,
|
|
1071
1093
|
validation: validation(baseRule)
|
|
1072
|
-
})
|
|
1094
|
+
});
|
|
1073
1095
|
}
|
|
1074
1096
|
const isRecord = maybeRecord => typeof maybeRecord === "object" && maybeRecord !== null && !Array.isArray(maybeRecord);
|
|
1075
1097
|
const isNonNullable = value => value !== null && value !== void 0;
|
|
@@ -1131,22 +1153,25 @@ function validateDocumentObservable(getClient, doc, schema, context) {
|
|
|
1131
1153
|
}
|
|
1132
1154
|
function validateItemObservable(_ref) {
|
|
1133
1155
|
let {
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1156
|
+
value,
|
|
1157
|
+
type,
|
|
1158
|
+
path = [],
|
|
1159
|
+
parent,
|
|
1160
|
+
...restOfContext
|
|
1161
|
+
} = _ref;
|
|
1140
1162
|
var _a;
|
|
1141
1163
|
const rules = normalizeValidationRules(type);
|
|
1142
|
-
const selfChecks = rules.map(rule => defer(() => rule.validate(value,
|
|
1164
|
+
const selfChecks = rules.map(rule => defer(() => rule.validate(value, {
|
|
1165
|
+
...restOfContext,
|
|
1143
1166
|
parent,
|
|
1144
1167
|
path,
|
|
1145
1168
|
type
|
|
1146
|
-
})))
|
|
1169
|
+
})));
|
|
1147
1170
|
let nestedChecks = [];
|
|
1148
1171
|
const selfIsRequired = rules.some(rule => rule.isRequired());
|
|
1149
|
-
const shouldRunNestedObjectValidation =
|
|
1172
|
+
const shouldRunNestedObjectValidation =
|
|
1173
|
+
// run nested validation for objects
|
|
1174
|
+
(type == null ? void 0 : type.jsonType) === "object" && (!!value || (value === null || value === void 0) && selfIsRequired);
|
|
1150
1175
|
if (shouldRunNestedObjectValidation) {
|
|
1151
1176
|
const fieldTypes = type.fields.reduce((acc, field) => {
|
|
1152
1177
|
acc[field.name] = field.type;
|
|
@@ -1155,34 +1180,38 @@ function validateItemObservable(_ref) {
|
|
|
1155
1180
|
nestedChecks = nestedChecks.concat(rules.map(rule => rule._fieldRules).filter(isNonNullable).flatMap(fieldResults => Object.entries(fieldResults)).flatMap(_ref2 => {
|
|
1156
1181
|
let [name, validation] = _ref2;
|
|
1157
1182
|
const fieldType = fieldTypes[name];
|
|
1158
|
-
return normalizeValidationRules(
|
|
1183
|
+
return normalizeValidationRules({
|
|
1184
|
+
...fieldType,
|
|
1159
1185
|
validation
|
|
1160
|
-
})
|
|
1186
|
+
}).map(subRule => {
|
|
1161
1187
|
const nestedValue = isRecord(value) ? value[name] : void 0;
|
|
1162
|
-
return defer(() => subRule.validate(nestedValue,
|
|
1188
|
+
return defer(() => subRule.validate(nestedValue, {
|
|
1189
|
+
...restOfContext,
|
|
1163
1190
|
parent: value,
|
|
1164
1191
|
path: path.concat(name),
|
|
1165
1192
|
type: fieldType
|
|
1166
|
-
}))
|
|
1193
|
+
}));
|
|
1167
1194
|
});
|
|
1168
1195
|
}));
|
|
1169
|
-
nestedChecks = nestedChecks.concat(type.fields.map(field => validateItemObservable(
|
|
1196
|
+
nestedChecks = nestedChecks.concat(type.fields.map(field => validateItemObservable({
|
|
1197
|
+
...restOfContext,
|
|
1170
1198
|
parent: value,
|
|
1171
1199
|
value: isRecord(value) ? value[field.name] : void 0,
|
|
1172
1200
|
path: path.concat(field.name),
|
|
1173
1201
|
type: field.type
|
|
1174
|
-
})))
|
|
1202
|
+
})));
|
|
1175
1203
|
}
|
|
1176
1204
|
const shouldRunNestedValidationForArrays = (type == null ? void 0 : type.jsonType) === "array" && Array.isArray(value);
|
|
1177
1205
|
if (shouldRunNestedValidationForArrays) {
|
|
1178
|
-
nestedChecks = nestedChecks.concat(value.map((item, index) => validateItemObservable(
|
|
1206
|
+
nestedChecks = nestedChecks.concat(value.map((item, index) => validateItemObservable({
|
|
1207
|
+
...restOfContext,
|
|
1179
1208
|
parent: value,
|
|
1180
1209
|
value: item,
|
|
1181
1210
|
path: path.concat(isKeyedObject(item) ? {
|
|
1182
1211
|
_key: item._key
|
|
1183
1212
|
} : index),
|
|
1184
1213
|
type: resolveTypeForArrayItem(item, type.of)
|
|
1185
|
-
})))
|
|
1214
|
+
})));
|
|
1186
1215
|
}
|
|
1187
1216
|
const shouldRunNestedValidationForMarkDefs = isPortableTextTextBlock(value) && ((_a = value.markDefs) == null ? void 0 : _a.length) && isBlockSchemaType(type);
|
|
1188
1217
|
if (shouldRunNestedValidationForMarkDefs) {
|
|
@@ -1192,14 +1221,15 @@ function validateItemObservable(_ref) {
|
|
|
1192
1221
|
acc.set(annotationType.name, annotationType);
|
|
1193
1222
|
return acc;
|
|
1194
1223
|
}, /* @__PURE__ */new Map());
|
|
1195
|
-
nestedChecks = nestedChecks.concat((value.markDefs || []).map(markDef => validateItemObservable(
|
|
1224
|
+
nestedChecks = nestedChecks.concat((value.markDefs || []).map(markDef => validateItemObservable({
|
|
1225
|
+
...restOfContext,
|
|
1196
1226
|
parent: value,
|
|
1197
1227
|
value: markDef,
|
|
1198
1228
|
path: path.concat(["markDefs", {
|
|
1199
1229
|
_key: markDef._key
|
|
1200
1230
|
}]),
|
|
1201
1231
|
type: annotations.get(markDef._type)
|
|
1202
|
-
})))
|
|
1232
|
+
})));
|
|
1203
1233
|
}
|
|
1204
1234
|
return defer(() => merge([...selfChecks, ...nestedChecks])).pipe(mergeMap(validateNode => concat(idle(), validateNode), 40), mergeAll(), toArray(), map(flatten), map(results => {
|
|
1205
1235
|
if (rules.some(rule => rule._fieldRules)) {
|