@sanity/validation 3.1.4 → 3.1.5-canary.15

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.js CHANGED
@@ -1,11 +1,5 @@
1
1
  'use strict';
2
2
 
3
- const _excluded = ["value", "type", "path", "parent"];
4
- 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; }
5
- 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; }
6
- 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; }
7
- 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; }
8
- 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; }
9
3
  Object.defineProperty(exports, '__esModule', {
10
4
  value: true
11
5
  });
@@ -18,17 +12,17 @@ var operators = require('rxjs/operators');
18
12
  var flatten = require('lodash/flatten.js');
19
13
  var uniqBy = require('lodash/uniqBy.js');
20
14
  var memoize = require('lodash/memoize.js');
21
- function _interopDefaultLegacy(e) {
15
+ function _interopDefaultCompat(e) {
22
16
  return e && typeof e === 'object' && 'default' in e ? e : {
23
- 'default': e
17
+ default: e
24
18
  };
25
19
  }
26
- var cloneDeep__default = /*#__PURE__*/_interopDefaultLegacy(cloneDeep);
27
- var get__default = /*#__PURE__*/_interopDefaultLegacy(get);
28
- var formatDate__default = /*#__PURE__*/_interopDefaultLegacy(formatDate);
29
- var flatten__default = /*#__PURE__*/_interopDefaultLegacy(flatten);
30
- var uniqBy__default = /*#__PURE__*/_interopDefaultLegacy(uniqBy);
31
- var memoize__default = /*#__PURE__*/_interopDefaultLegacy(memoize);
20
+ var cloneDeep__default = /*#__PURE__*/_interopDefaultCompat(cloneDeep);
21
+ var get__default = /*#__PURE__*/_interopDefaultCompat(get);
22
+ var formatDate__default = /*#__PURE__*/_interopDefaultCompat(formatDate);
23
+ var flatten__default = /*#__PURE__*/_interopDefaultCompat(flatten);
24
+ var uniqBy__default = /*#__PURE__*/_interopDefaultCompat(uniqBy);
25
+ var memoize__default = /*#__PURE__*/_interopDefaultCompat(memoize);
32
26
  const ValidationError = class ValidationError2 {
33
27
  constructor(message) {
34
28
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -243,16 +237,18 @@ const genericValidators = {
243
237
  return result;
244
238
  }
245
239
  };
246
- const booleanValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
240
+ const booleanValidators = {
241
+ ...genericValidators,
247
242
  presence: (flag, value, message) => {
248
243
  if (flag === "required" && typeof value !== "boolean") {
249
244
  return message || "Required";
250
245
  }
251
246
  return true;
252
247
  }
253
- });
248
+ };
254
249
  const precisionRx = /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/;
255
- const numberValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
250
+ const numberValidators = {
251
+ ...genericValidators,
256
252
  integer: (_unused, value, message) => {
257
253
  if (!Number.isInteger(value)) {
258
254
  return message || "Must be an integer";
@@ -292,11 +288,12 @@ const numberValidators = _objectSpread(_objectSpread({}, genericValidators), {},
292
288
  }
293
289
  return message || "Must be less than ".concat(maxNum);
294
290
  }
295
- });
291
+ };
296
292
  const DUMMY_ORIGIN = "http://sanity";
297
293
  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,}))$/;
298
294
  const isRelativeUrl = url => /^\.*\//.test(url);
299
- const stringValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
295
+ const stringValidators = {
296
+ ...genericValidators,
300
297
  min: (minLength, value, message) => {
301
298
  if (!value || value.length >= minLength) {
302
299
  return true;
@@ -386,8 +383,9 @@ const stringValidators = _objectSpread(_objectSpread({}, genericValidators), {},
386
383
  }
387
384
  return message || "Must be a valid email address";
388
385
  }
389
- });
390
- const arrayValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
386
+ };
387
+ const arrayValidators = {
388
+ ...genericValidators,
391
389
  min: (minLength, value, message) => {
392
390
  if (!value || value.length >= minLength) {
393
391
  return true;
@@ -463,9 +461,10 @@ const arrayValidators = _objectSpread(_objectSpread({}, genericValidators), {},
463
461
  paths
464
462
  }) : true;
465
463
  }
466
- });
464
+ };
467
465
  const metaKeys = ["_key", "_type", "_weak"];
468
- const objectValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
466
+ const objectValidators = {
467
+ ...genericValidators,
469
468
  presence: (expected, value, message) => {
470
469
  if (expected !== "required") {
471
470
  return true;
@@ -511,7 +510,7 @@ const objectValidators = _objectSpread(_objectSpread({}, genericValidators), {},
511
510
  }
512
511
  return true;
513
512
  }
514
- });
513
+ };
515
514
  function isRecord$1(obj) {
516
515
  return typeof obj === "object" && obj !== null && !Array.isArray(obj);
517
516
  }
@@ -525,14 +524,14 @@ const getFormattedDate = function () {
525
524
  format = options.dateFormat;
526
525
  }
527
526
  if (type === "date") {
528
- return formatDate__default["default"](new Date(value), format);
527
+ return formatDate__default.default(new Date(value), format);
529
528
  }
530
529
  if (options && options.timeFormat) {
531
530
  format += " ".concat(options.timeFormat);
532
531
  } else {
533
532
  format += " HH:mm";
534
533
  }
535
- return formatDate__default["default"](new Date(value), format);
534
+ return formatDate__default.default(new Date(value), format);
536
535
  };
537
536
  function parseDate(date) {
538
537
  let throwOnError = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@@ -545,7 +544,8 @@ function parseDate(date) {
545
544
  }
546
545
  return isInvalid ? null : parsed;
547
546
  }
548
- const dateValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
547
+ const dateValidators = {
548
+ ...genericValidators,
549
549
  type: (_unused, value, message) => {
550
550
  const strVal = "".concat(value);
551
551
  if (!strVal || isoDate.test(value)) {
@@ -583,7 +583,7 @@ const dateValidators = _objectSpread(_objectSpread({}, genericValidators), {}, {
583
583
  const date = getFormattedDate(context.type.name, maxDate, dateTimeOptions);
584
584
  return message || "Must be at or before ".concat(date);
585
585
  }
586
- });
586
+ };
587
587
  var _a;
588
588
  const typeValidators = {
589
589
  Boolean: booleanValidators,
@@ -612,6 +612,7 @@ const Rule = (_a = class {
612
612
  this._message = void 0;
613
613
  this._rules = [];
614
614
  this._fieldRules = void 0;
615
+ // Alias to static method, since we often have access to an _instance_ of a rule but not the actual Rule class
615
616
  this.valueOfField = _a.valueOfField.bind(_a);
616
617
  this._typeDef = typeDef;
617
618
  this.reset();
@@ -656,7 +657,7 @@ const Rule = (_a = class {
656
657
  rule._type = this._type;
657
658
  rule._message = this._message;
658
659
  rule._required = this._required;
659
- rule._rules = cloneDeep__default["default"](this._rules);
660
+ rule._rules = cloneDeep__default.default(this._rules);
660
661
  rule._level = this._level;
661
662
  rule._fieldRules = this._fieldRules;
662
663
  rule._typeDef = this._typeDef;
@@ -689,6 +690,7 @@ const Rule = (_a = class {
689
690
  newRule._level = this._level === "error" ? rule._level : this._level;
690
691
  return newRule;
691
692
  }
693
+ // Validation flag setters
692
694
  type(targetType) {
693
695
  const type = "".concat(targetType.slice(0, 1).toUpperCase()).concat(targetType.slice(1));
694
696
  if (!ruleConstraintTypes$1.includes(type)) {
@@ -713,6 +715,7 @@ const Rule = (_a = class {
713
715
  constraint: children
714
716
  }]);
715
717
  }
718
+ // Shared rules
716
719
  optional() {
717
720
  const rule = this.cloneWithRules([{
718
721
  flag: "presence",
@@ -760,6 +763,7 @@ const Rule = (_a = class {
760
763
  constraint: values
761
764
  }]);
762
765
  }
766
+ // Numbers only
763
767
  integer() {
764
768
  return this.cloneWithRules([{
765
769
  flag: "integer"
@@ -795,6 +799,7 @@ const Rule = (_a = class {
795
799
  constraint: num
796
800
  }]);
797
801
  }
802
+ // String only
798
803
  uppercase() {
799
804
  return this.cloneWithRules([{
800
805
  flag: "stringCasing",
@@ -850,11 +855,13 @@ const Rule = (_a = class {
850
855
  constraint
851
856
  }]);
852
857
  }
858
+ // Array only
853
859
  unique() {
854
860
  return this.cloneWithRules([{
855
861
  flag: "unique"
856
862
  }]);
857
863
  }
864
+ // Objects only
858
865
  reference() {
859
866
  return this.cloneWithRules([{
860
867
  flag: "reference"
@@ -891,7 +898,9 @@ const Rule = (_a = class {
891
898
  if (valueIsEmpty && this._required === "optional") {
892
899
  return EMPTY_ARRAY;
893
900
  }
894
- const rules = this._required === void 0 && valueIsEmpty ? this._rules.filter(curr => curr.flag === "custom") : this._rules;
901
+ const rules =
902
+ // Run only the _custom_ functions if the rule is not set to required or optional
903
+ this._required === void 0 && valueIsEmpty ? this._rules.filter(curr => curr.flag === "custom") : this._rules;
895
904
  const validators = this._type && typeValidators[this._type] || genericValidators;
896
905
  const results = await Promise.all(rules.map(async curr => {
897
906
  if (curr.flag === void 0) {
@@ -904,7 +913,7 @@ const Rule = (_a = class {
904
913
  }
905
914
  let specConstraint = "constraint" in curr ? curr.constraint : null;
906
915
  if (isFieldRef(specConstraint)) {
907
- specConstraint = get__default["default"](context.parent, specConstraint.path);
916
+ specConstraint = get__default.default(context.parent, specConstraint.path);
908
917
  }
909
918
  let result;
910
919
  try {
@@ -938,7 +947,7 @@ const cancelIdleCallbackShim = function cancelIdleCallbackShim2(handle) {
938
947
  const win = typeof window === "undefined" ? void 0 : window;
939
948
  const requestIdleCallback = (win == null ? void 0 : win.requestIdleCallback) || requestIdleCallbackShim;
940
949
  const cancelIdleCallback = (win == null ? void 0 : win.cancelIdleCallback) || cancelIdleCallbackShim;
941
- const memoizedWarnOnArraySlug = memoize__default["default"](warnOnArraySlug);
950
+ const memoizedWarnOnArraySlug = memoize__default.default(warnOnArraySlug);
942
951
  function getDocumentIds(id) {
943
952
  const isDraft = id.indexOf("drafts.") === 0;
944
953
  return {
@@ -1008,11 +1017,12 @@ const slugValidator = async (value, context) => {
1008
1017
  }
1009
1018
  const options = (_a = context == null ? void 0 : context.type) == null ? void 0 : _a.options;
1010
1019
  const isUnique = (options == null ? void 0 : options.isUnique) || defaultIsUnique;
1011
- const slugContext = _objectSpread(_objectSpread({}, context), {}, {
1020
+ const slugContext = {
1021
+ ...context,
1012
1022
  parent: context.parent,
1013
1023
  type: context.type,
1014
1024
  defaultIsUnique
1015
- });
1025
+ };
1016
1026
  const wasUnique = await isUnique(slugValue, slugContext);
1017
1027
  if (wasUnique) {
1018
1028
  return true;
@@ -1040,7 +1050,15 @@ function baseRuleReducer(inputRule, type) {
1040
1050
  if (isRuleConstraint(type.jsonType)) {
1041
1051
  baseRule = baseRule.type(type.jsonType);
1042
1052
  }
1043
- const typeOptionsList = (type == null ? void 0 : type.options) && typeof type.options === "object" && "list" in type.options && type.options.list;
1053
+ const typeOptionsList =
1054
+ // if type.options is truthy
1055
+ (type == null ? void 0 : type.options) &&
1056
+ // and type.options is an object (non-null from the previous)
1057
+ typeof type.options === "object" &&
1058
+ // and if `list` is in options
1059
+ "list" in type.options &&
1060
+ // then finally access the list
1061
+ type.options.list;
1044
1062
  if (Array.isArray(typeOptionsList)) {
1045
1063
  baseRule = baseRule.valid(typeOptionsList.map(option => extractValueFromListOption(option, type)));
1046
1064
  }
@@ -1069,23 +1087,27 @@ function normalizeValidationRules(typeDef) {
1069
1087
  }
1070
1088
  const validation = typeDef.validation;
1071
1089
  if (Array.isArray(validation)) {
1072
- return validation.flatMap(i => normalizeValidationRules(_objectSpread(_objectSpread({}, typeDef), {}, {
1090
+ return validation.flatMap(i => normalizeValidationRules({
1091
+ ...typeDef,
1073
1092
  validation: i
1074
- })));
1093
+ }));
1075
1094
  }
1076
1095
  if (validation instanceof Rule) {
1077
1096
  return [validation];
1078
1097
  }
1079
- const baseRule = Object.values(getTypeChain(typeDef, /* @__PURE__ */new Set()).reduce((acc, type) => {
1098
+ const baseRule =
1099
+ // using an object + Object.values to de-dupe the type chain by type name
1100
+ Object.values(getTypeChain(typeDef, /* @__PURE__ */new Set()).reduce((acc, type) => {
1080
1101
  acc[type.name] = type;
1081
1102
  return acc;
1082
1103
  }, {})).reduce(baseRuleReducer, new Rule(typeDef));
1083
1104
  if (!validation) {
1084
1105
  return [baseRule];
1085
1106
  }
1086
- return normalizeValidationRules(_objectSpread(_objectSpread({}, typeDef), {}, {
1107
+ return normalizeValidationRules({
1108
+ ...typeDef,
1087
1109
  validation: validation(baseRule)
1088
- }));
1110
+ });
1089
1111
  }
1090
1112
  const isRecord = maybeRecord => typeof maybeRecord === "object" && maybeRecord !== null && !Array.isArray(maybeRecord);
1091
1113
  const isNonNullable = value => value !== null && value !== void 0;
@@ -1147,22 +1169,25 @@ function validateDocumentObservable(getClient, doc, schema, context) {
1147
1169
  }
1148
1170
  function validateItemObservable(_ref) {
1149
1171
  let {
1150
- value,
1151
- type,
1152
- path = [],
1153
- parent
1154
- } = _ref,
1155
- restOfContext = _objectWithoutProperties(_ref, _excluded);
1172
+ value,
1173
+ type,
1174
+ path = [],
1175
+ parent,
1176
+ ...restOfContext
1177
+ } = _ref;
1156
1178
  var _a;
1157
1179
  const rules = normalizeValidationRules(type);
1158
- const selfChecks = rules.map(rule => rxjs.defer(() => rule.validate(value, _objectSpread(_objectSpread({}, restOfContext), {}, {
1180
+ const selfChecks = rules.map(rule => rxjs.defer(() => rule.validate(value, {
1181
+ ...restOfContext,
1159
1182
  parent,
1160
1183
  path,
1161
1184
  type
1162
- }))));
1185
+ })));
1163
1186
  let nestedChecks = [];
1164
1187
  const selfIsRequired = rules.some(rule => rule.isRequired());
1165
- const shouldRunNestedObjectValidation = (type == null ? void 0 : type.jsonType) === "object" && (!!value || (value === null || value === void 0) && selfIsRequired);
1188
+ const shouldRunNestedObjectValidation =
1189
+ // run nested validation for objects
1190
+ (type == null ? void 0 : type.jsonType) === "object" && (!!value || (value === null || value === void 0) && selfIsRequired);
1166
1191
  if (shouldRunNestedObjectValidation) {
1167
1192
  const fieldTypes = type.fields.reduce((acc, field) => {
1168
1193
  acc[field.name] = field.type;
@@ -1171,34 +1196,38 @@ function validateItemObservable(_ref) {
1171
1196
  nestedChecks = nestedChecks.concat(rules.map(rule => rule._fieldRules).filter(isNonNullable).flatMap(fieldResults => Object.entries(fieldResults)).flatMap(_ref2 => {
1172
1197
  let [name, validation] = _ref2;
1173
1198
  const fieldType = fieldTypes[name];
1174
- return normalizeValidationRules(_objectSpread(_objectSpread({}, fieldType), {}, {
1199
+ return normalizeValidationRules({
1200
+ ...fieldType,
1175
1201
  validation
1176
- })).map(subRule => {
1202
+ }).map(subRule => {
1177
1203
  const nestedValue = isRecord(value) ? value[name] : void 0;
1178
- return rxjs.defer(() => subRule.validate(nestedValue, _objectSpread(_objectSpread({}, restOfContext), {}, {
1204
+ return rxjs.defer(() => subRule.validate(nestedValue, {
1205
+ ...restOfContext,
1179
1206
  parent: value,
1180
1207
  path: path.concat(name),
1181
1208
  type: fieldType
1182
- })));
1209
+ }));
1183
1210
  });
1184
1211
  }));
1185
- nestedChecks = nestedChecks.concat(type.fields.map(field => validateItemObservable(_objectSpread(_objectSpread({}, restOfContext), {}, {
1212
+ nestedChecks = nestedChecks.concat(type.fields.map(field => validateItemObservable({
1213
+ ...restOfContext,
1186
1214
  parent: value,
1187
1215
  value: isRecord(value) ? value[field.name] : void 0,
1188
1216
  path: path.concat(field.name),
1189
1217
  type: field.type
1190
- }))));
1218
+ })));
1191
1219
  }
1192
1220
  const shouldRunNestedValidationForArrays = (type == null ? void 0 : type.jsonType) === "array" && Array.isArray(value);
1193
1221
  if (shouldRunNestedValidationForArrays) {
1194
- nestedChecks = nestedChecks.concat(value.map((item, index) => validateItemObservable(_objectSpread(_objectSpread({}, restOfContext), {}, {
1222
+ nestedChecks = nestedChecks.concat(value.map((item, index) => validateItemObservable({
1223
+ ...restOfContext,
1195
1224
  parent: value,
1196
1225
  value: item,
1197
1226
  path: path.concat(types.isKeyedObject(item) ? {
1198
1227
  _key: item._key
1199
1228
  } : index),
1200
1229
  type: resolveTypeForArrayItem(item, type.of)
1201
- }))));
1230
+ })));
1202
1231
  }
1203
1232
  const shouldRunNestedValidationForMarkDefs = types.isPortableTextTextBlock(value) && ((_a = value.markDefs) == null ? void 0 : _a.length) && types.isBlockSchemaType(type);
1204
1233
  if (shouldRunNestedValidationForMarkDefs) {
@@ -1208,18 +1237,19 @@ function validateItemObservable(_ref) {
1208
1237
  acc.set(annotationType.name, annotationType);
1209
1238
  return acc;
1210
1239
  }, /* @__PURE__ */new Map());
1211
- nestedChecks = nestedChecks.concat((value.markDefs || []).map(markDef => validateItemObservable(_objectSpread(_objectSpread({}, restOfContext), {}, {
1240
+ nestedChecks = nestedChecks.concat((value.markDefs || []).map(markDef => validateItemObservable({
1241
+ ...restOfContext,
1212
1242
  parent: value,
1213
1243
  value: markDef,
1214
1244
  path: path.concat(["markDefs", {
1215
1245
  _key: markDef._key
1216
1246
  }]),
1217
1247
  type: annotations.get(markDef._type)
1218
- }))));
1248
+ })));
1219
1249
  }
1220
- return rxjs.defer(() => rxjs.merge([...selfChecks, ...nestedChecks])).pipe(operators.mergeMap(validateNode => rxjs.concat(idle(), validateNode), 40), operators.mergeAll(), operators.toArray(), operators.map(flatten__default["default"]), operators.map(results => {
1250
+ return rxjs.defer(() => rxjs.merge([...selfChecks, ...nestedChecks])).pipe(operators.mergeMap(validateNode => rxjs.concat(idle(), validateNode), 40), operators.mergeAll(), operators.toArray(), operators.map(flatten__default.default), operators.map(results => {
1221
1251
  if (rules.some(rule => rule._fieldRules)) {
1222
- return uniqBy__default["default"](results, rule => JSON.stringify(rule));
1252
+ return uniqBy__default.default(results, rule => JSON.stringify(rule));
1223
1253
  }
1224
1254
  return results;
1225
1255
  }));