@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.
@@ -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 = _objectSpread(_objectSpread({}, genericValidators), {}, {
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 = _objectSpread(_objectSpread({}, genericValidators), {}, {
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 = _objectSpread(_objectSpread({}, genericValidators), {}, {
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 = _objectSpread(_objectSpread({}, genericValidators), {}, {
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 = _objectSpread(_objectSpread({}, genericValidators), {}, {
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 = _objectSpread(_objectSpread({}, genericValidators), {}, {
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 = this._required === void 0 && valueIsEmpty ? this._rules.filter(curr => curr.flag === "custom") : this._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 = _objectSpread(_objectSpread({}, context), {}, {
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 = (type == null ? void 0 : type.options) && typeof type.options === "object" && "list" in type.options && type.options.list;
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(_objectSpread(_objectSpread({}, typeDef), {}, {
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 = Object.values(getTypeChain(typeDef, /* @__PURE__ */new Set()).reduce((acc, type) => {
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(_objectSpread(_objectSpread({}, typeDef), {}, {
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
- value,
1137
- type,
1138
- path = [],
1139
- parent
1140
- } = _ref,
1141
- restOfContext = _objectWithoutProperties(_ref, _excluded);
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, _objectSpread(_objectSpread({}, restOfContext), {}, {
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 = (type == null ? void 0 : type.jsonType) === "object" && (!!value || (value === null || value === void 0) && selfIsRequired);
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(_objectSpread(_objectSpread({}, fieldType), {}, {
1183
+ return normalizeValidationRules({
1184
+ ...fieldType,
1161
1185
  validation
1162
- })).map(subRule => {
1186
+ }).map(subRule => {
1163
1187
  const nestedValue = isRecord(value) ? value[name] : void 0;
1164
- return defer(() => subRule.validate(nestedValue, _objectSpread(_objectSpread({}, restOfContext), {}, {
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(_objectSpread(_objectSpread({}, restOfContext), {}, {
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(_objectSpread(_objectSpread({}, restOfContext), {}, {
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(_objectSpread(_objectSpread({}, restOfContext), {}, {
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)) {