@sanity/validation 3.1.3 → 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 -48
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +76 -48
- 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,11 +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) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
7
|
-
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
8
|
-
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
9
1
|
import cloneDeep from 'lodash/cloneDeep.js';
|
|
10
2
|
import get from 'lodash/get.js';
|
|
11
3
|
import { isKeyedObject, isReference, isPortableTextTextBlock, isBlockSchemaType, isSpanSchemaType, isTypedObject } from '@sanity/types';
|
|
@@ -229,16 +221,18 @@ const genericValidators = {
|
|
|
229
221
|
return result;
|
|
230
222
|
}
|
|
231
223
|
};
|
|
232
|
-
const booleanValidators =
|
|
224
|
+
const booleanValidators = {
|
|
225
|
+
...genericValidators,
|
|
233
226
|
presence: (flag, value, message) => {
|
|
234
227
|
if (flag === "required" && typeof value !== "boolean") {
|
|
235
228
|
return message || "Required";
|
|
236
229
|
}
|
|
237
230
|
return true;
|
|
238
231
|
}
|
|
239
|
-
}
|
|
232
|
+
};
|
|
240
233
|
const precisionRx = /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/;
|
|
241
|
-
const numberValidators =
|
|
234
|
+
const numberValidators = {
|
|
235
|
+
...genericValidators,
|
|
242
236
|
integer: (_unused, value, message) => {
|
|
243
237
|
if (!Number.isInteger(value)) {
|
|
244
238
|
return message || "Must be an integer";
|
|
@@ -278,11 +272,12 @@ const numberValidators = _objectSpread(_objectSpread({}, genericValidators), {},
|
|
|
278
272
|
}
|
|
279
273
|
return message || "Must be less than ".concat(maxNum);
|
|
280
274
|
}
|
|
281
|
-
}
|
|
275
|
+
};
|
|
282
276
|
const DUMMY_ORIGIN = "http://sanity";
|
|
283
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,}))$/;
|
|
284
278
|
const isRelativeUrl = url => /^\.*\//.test(url);
|
|
285
|
-
const stringValidators =
|
|
279
|
+
const stringValidators = {
|
|
280
|
+
...genericValidators,
|
|
286
281
|
min: (minLength, value, message) => {
|
|
287
282
|
if (!value || value.length >= minLength) {
|
|
288
283
|
return true;
|
|
@@ -372,8 +367,9 @@ const stringValidators = _objectSpread(_objectSpread({}, genericValidators), {},
|
|
|
372
367
|
}
|
|
373
368
|
return message || "Must be a valid email address";
|
|
374
369
|
}
|
|
375
|
-
}
|
|
376
|
-
const arrayValidators =
|
|
370
|
+
};
|
|
371
|
+
const arrayValidators = {
|
|
372
|
+
...genericValidators,
|
|
377
373
|
min: (minLength, value, message) => {
|
|
378
374
|
if (!value || value.length >= minLength) {
|
|
379
375
|
return true;
|
|
@@ -449,9 +445,10 @@ const arrayValidators = _objectSpread(_objectSpread({}, genericValidators), {},
|
|
|
449
445
|
paths
|
|
450
446
|
}) : true;
|
|
451
447
|
}
|
|
452
|
-
}
|
|
448
|
+
};
|
|
453
449
|
const metaKeys = ["_key", "_type", "_weak"];
|
|
454
|
-
const objectValidators =
|
|
450
|
+
const objectValidators = {
|
|
451
|
+
...genericValidators,
|
|
455
452
|
presence: (expected, value, message) => {
|
|
456
453
|
if (expected !== "required") {
|
|
457
454
|
return true;
|
|
@@ -497,7 +494,7 @@ const objectValidators = _objectSpread(_objectSpread({}, genericValidators), {},
|
|
|
497
494
|
}
|
|
498
495
|
return true;
|
|
499
496
|
}
|
|
500
|
-
}
|
|
497
|
+
};
|
|
501
498
|
function isRecord$1(obj) {
|
|
502
499
|
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
503
500
|
}
|
|
@@ -531,7 +528,8 @@ function parseDate(date) {
|
|
|
531
528
|
}
|
|
532
529
|
return isInvalid ? null : parsed;
|
|
533
530
|
}
|
|
534
|
-
const dateValidators =
|
|
531
|
+
const dateValidators = {
|
|
532
|
+
...genericValidators,
|
|
535
533
|
type: (_unused, value, message) => {
|
|
536
534
|
const strVal = "".concat(value);
|
|
537
535
|
if (!strVal || isoDate.test(value)) {
|
|
@@ -569,7 +567,7 @@ const dateValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
|
|
|
569
567
|
const date = getFormattedDate(context.type.name, maxDate, dateTimeOptions);
|
|
570
568
|
return message || "Must be at or before ".concat(date);
|
|
571
569
|
}
|
|
572
|
-
}
|
|
570
|
+
};
|
|
573
571
|
var _a;
|
|
574
572
|
const typeValidators = {
|
|
575
573
|
Boolean: booleanValidators,
|
|
@@ -598,6 +596,7 @@ const Rule = (_a = class {
|
|
|
598
596
|
this._message = void 0;
|
|
599
597
|
this._rules = [];
|
|
600
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
|
|
601
600
|
this.valueOfField = _a.valueOfField.bind(_a);
|
|
602
601
|
this._typeDef = typeDef;
|
|
603
602
|
this.reset();
|
|
@@ -675,6 +674,7 @@ const Rule = (_a = class {
|
|
|
675
674
|
newRule._level = this._level === "error" ? rule._level : this._level;
|
|
676
675
|
return newRule;
|
|
677
676
|
}
|
|
677
|
+
// Validation flag setters
|
|
678
678
|
type(targetType) {
|
|
679
679
|
const type = "".concat(targetType.slice(0, 1).toUpperCase()).concat(targetType.slice(1));
|
|
680
680
|
if (!ruleConstraintTypes$1.includes(type)) {
|
|
@@ -699,6 +699,7 @@ const Rule = (_a = class {
|
|
|
699
699
|
constraint: children
|
|
700
700
|
}]);
|
|
701
701
|
}
|
|
702
|
+
// Shared rules
|
|
702
703
|
optional() {
|
|
703
704
|
const rule = this.cloneWithRules([{
|
|
704
705
|
flag: "presence",
|
|
@@ -746,6 +747,7 @@ const Rule = (_a = class {
|
|
|
746
747
|
constraint: values
|
|
747
748
|
}]);
|
|
748
749
|
}
|
|
750
|
+
// Numbers only
|
|
749
751
|
integer() {
|
|
750
752
|
return this.cloneWithRules([{
|
|
751
753
|
flag: "integer"
|
|
@@ -781,6 +783,7 @@ const Rule = (_a = class {
|
|
|
781
783
|
constraint: num
|
|
782
784
|
}]);
|
|
783
785
|
}
|
|
786
|
+
// String only
|
|
784
787
|
uppercase() {
|
|
785
788
|
return this.cloneWithRules([{
|
|
786
789
|
flag: "stringCasing",
|
|
@@ -836,11 +839,13 @@ const Rule = (_a = class {
|
|
|
836
839
|
constraint
|
|
837
840
|
}]);
|
|
838
841
|
}
|
|
842
|
+
// Array only
|
|
839
843
|
unique() {
|
|
840
844
|
return this.cloneWithRules([{
|
|
841
845
|
flag: "unique"
|
|
842
846
|
}]);
|
|
843
847
|
}
|
|
848
|
+
// Objects only
|
|
844
849
|
reference() {
|
|
845
850
|
return this.cloneWithRules([{
|
|
846
851
|
flag: "reference"
|
|
@@ -877,7 +882,9 @@ const Rule = (_a = class {
|
|
|
877
882
|
if (valueIsEmpty && this._required === "optional") {
|
|
878
883
|
return EMPTY_ARRAY;
|
|
879
884
|
}
|
|
880
|
-
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;
|
|
881
888
|
const validators = this._type && typeValidators[this._type] || genericValidators;
|
|
882
889
|
const results = await Promise.all(rules.map(async curr => {
|
|
883
890
|
if (curr.flag === void 0) {
|
|
@@ -994,11 +1001,12 @@ const slugValidator = async (value, context) => {
|
|
|
994
1001
|
}
|
|
995
1002
|
const options = (_a = context == null ? void 0 : context.type) == null ? void 0 : _a.options;
|
|
996
1003
|
const isUnique = (options == null ? void 0 : options.isUnique) || defaultIsUnique;
|
|
997
|
-
const slugContext =
|
|
1004
|
+
const slugContext = {
|
|
1005
|
+
...context,
|
|
998
1006
|
parent: context.parent,
|
|
999
1007
|
type: context.type,
|
|
1000
1008
|
defaultIsUnique
|
|
1001
|
-
}
|
|
1009
|
+
};
|
|
1002
1010
|
const wasUnique = await isUnique(slugValue, slugContext);
|
|
1003
1011
|
if (wasUnique) {
|
|
1004
1012
|
return true;
|
|
@@ -1026,7 +1034,15 @@ function baseRuleReducer(inputRule, type) {
|
|
|
1026
1034
|
if (isRuleConstraint(type.jsonType)) {
|
|
1027
1035
|
baseRule = baseRule.type(type.jsonType);
|
|
1028
1036
|
}
|
|
1029
|
-
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;
|
|
1030
1046
|
if (Array.isArray(typeOptionsList)) {
|
|
1031
1047
|
baseRule = baseRule.valid(typeOptionsList.map(option => extractValueFromListOption(option, type)));
|
|
1032
1048
|
}
|
|
@@ -1055,23 +1071,27 @@ function normalizeValidationRules(typeDef) {
|
|
|
1055
1071
|
}
|
|
1056
1072
|
const validation = typeDef.validation;
|
|
1057
1073
|
if (Array.isArray(validation)) {
|
|
1058
|
-
return validation.flatMap(i => normalizeValidationRules(
|
|
1074
|
+
return validation.flatMap(i => normalizeValidationRules({
|
|
1075
|
+
...typeDef,
|
|
1059
1076
|
validation: i
|
|
1060
|
-
}))
|
|
1077
|
+
}));
|
|
1061
1078
|
}
|
|
1062
1079
|
if (validation instanceof Rule) {
|
|
1063
1080
|
return [validation];
|
|
1064
1081
|
}
|
|
1065
|
-
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) => {
|
|
1066
1085
|
acc[type.name] = type;
|
|
1067
1086
|
return acc;
|
|
1068
1087
|
}, {})).reduce(baseRuleReducer, new Rule(typeDef));
|
|
1069
1088
|
if (!validation) {
|
|
1070
1089
|
return [baseRule];
|
|
1071
1090
|
}
|
|
1072
|
-
return normalizeValidationRules(
|
|
1091
|
+
return normalizeValidationRules({
|
|
1092
|
+
...typeDef,
|
|
1073
1093
|
validation: validation(baseRule)
|
|
1074
|
-
})
|
|
1094
|
+
});
|
|
1075
1095
|
}
|
|
1076
1096
|
const isRecord = maybeRecord => typeof maybeRecord === "object" && maybeRecord !== null && !Array.isArray(maybeRecord);
|
|
1077
1097
|
const isNonNullable = value => value !== null && value !== void 0;
|
|
@@ -1133,22 +1153,25 @@ function validateDocumentObservable(getClient, doc, schema, context) {
|
|
|
1133
1153
|
}
|
|
1134
1154
|
function validateItemObservable(_ref) {
|
|
1135
1155
|
let {
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1156
|
+
value,
|
|
1157
|
+
type,
|
|
1158
|
+
path = [],
|
|
1159
|
+
parent,
|
|
1160
|
+
...restOfContext
|
|
1161
|
+
} = _ref;
|
|
1142
1162
|
var _a;
|
|
1143
1163
|
const rules = normalizeValidationRules(type);
|
|
1144
|
-
const selfChecks = rules.map(rule => defer(() => rule.validate(value,
|
|
1164
|
+
const selfChecks = rules.map(rule => defer(() => rule.validate(value, {
|
|
1165
|
+
...restOfContext,
|
|
1145
1166
|
parent,
|
|
1146
1167
|
path,
|
|
1147
1168
|
type
|
|
1148
|
-
})))
|
|
1169
|
+
})));
|
|
1149
1170
|
let nestedChecks = [];
|
|
1150
1171
|
const selfIsRequired = rules.some(rule => rule.isRequired());
|
|
1151
|
-
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);
|
|
1152
1175
|
if (shouldRunNestedObjectValidation) {
|
|
1153
1176
|
const fieldTypes = type.fields.reduce((acc, field) => {
|
|
1154
1177
|
acc[field.name] = field.type;
|
|
@@ -1157,34 +1180,38 @@ function validateItemObservable(_ref) {
|
|
|
1157
1180
|
nestedChecks = nestedChecks.concat(rules.map(rule => rule._fieldRules).filter(isNonNullable).flatMap(fieldResults => Object.entries(fieldResults)).flatMap(_ref2 => {
|
|
1158
1181
|
let [name, validation] = _ref2;
|
|
1159
1182
|
const fieldType = fieldTypes[name];
|
|
1160
|
-
return normalizeValidationRules(
|
|
1183
|
+
return normalizeValidationRules({
|
|
1184
|
+
...fieldType,
|
|
1161
1185
|
validation
|
|
1162
|
-
})
|
|
1186
|
+
}).map(subRule => {
|
|
1163
1187
|
const nestedValue = isRecord(value) ? value[name] : void 0;
|
|
1164
|
-
return defer(() => subRule.validate(nestedValue,
|
|
1188
|
+
return defer(() => subRule.validate(nestedValue, {
|
|
1189
|
+
...restOfContext,
|
|
1165
1190
|
parent: value,
|
|
1166
1191
|
path: path.concat(name),
|
|
1167
1192
|
type: fieldType
|
|
1168
|
-
}))
|
|
1193
|
+
}));
|
|
1169
1194
|
});
|
|
1170
1195
|
}));
|
|
1171
|
-
nestedChecks = nestedChecks.concat(type.fields.map(field => validateItemObservable(
|
|
1196
|
+
nestedChecks = nestedChecks.concat(type.fields.map(field => validateItemObservable({
|
|
1197
|
+
...restOfContext,
|
|
1172
1198
|
parent: value,
|
|
1173
1199
|
value: isRecord(value) ? value[field.name] : void 0,
|
|
1174
1200
|
path: path.concat(field.name),
|
|
1175
1201
|
type: field.type
|
|
1176
|
-
})))
|
|
1202
|
+
})));
|
|
1177
1203
|
}
|
|
1178
1204
|
const shouldRunNestedValidationForArrays = (type == null ? void 0 : type.jsonType) === "array" && Array.isArray(value);
|
|
1179
1205
|
if (shouldRunNestedValidationForArrays) {
|
|
1180
|
-
nestedChecks = nestedChecks.concat(value.map((item, index) => validateItemObservable(
|
|
1206
|
+
nestedChecks = nestedChecks.concat(value.map((item, index) => validateItemObservable({
|
|
1207
|
+
...restOfContext,
|
|
1181
1208
|
parent: value,
|
|
1182
1209
|
value: item,
|
|
1183
1210
|
path: path.concat(isKeyedObject(item) ? {
|
|
1184
1211
|
_key: item._key
|
|
1185
1212
|
} : index),
|
|
1186
1213
|
type: resolveTypeForArrayItem(item, type.of)
|
|
1187
|
-
})))
|
|
1214
|
+
})));
|
|
1188
1215
|
}
|
|
1189
1216
|
const shouldRunNestedValidationForMarkDefs = isPortableTextTextBlock(value) && ((_a = value.markDefs) == null ? void 0 : _a.length) && isBlockSchemaType(type);
|
|
1190
1217
|
if (shouldRunNestedValidationForMarkDefs) {
|
|
@@ -1194,14 +1221,15 @@ function validateItemObservable(_ref) {
|
|
|
1194
1221
|
acc.set(annotationType.name, annotationType);
|
|
1195
1222
|
return acc;
|
|
1196
1223
|
}, /* @__PURE__ */new Map());
|
|
1197
|
-
nestedChecks = nestedChecks.concat((value.markDefs || []).map(markDef => validateItemObservable(
|
|
1224
|
+
nestedChecks = nestedChecks.concat((value.markDefs || []).map(markDef => validateItemObservable({
|
|
1225
|
+
...restOfContext,
|
|
1198
1226
|
parent: value,
|
|
1199
1227
|
value: markDef,
|
|
1200
1228
|
path: path.concat(["markDefs", {
|
|
1201
1229
|
_key: markDef._key
|
|
1202
1230
|
}]),
|
|
1203
1231
|
type: annotations.get(markDef._type)
|
|
1204
|
-
})))
|
|
1232
|
+
})));
|
|
1205
1233
|
}
|
|
1206
1234
|
return defer(() => merge([...selfChecks, ...nestedChecks])).pipe(mergeMap(validateNode => concat(idle(), validateNode), 40), mergeAll(), toArray(), map(flatten), map(results => {
|
|
1207
1235
|
if (rules.some(rule => rule._fieldRules)) {
|