@sanity/validation 2.30.1-purple-unicorn.964 → 3.0.0-dev-preview.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.
Files changed (48) hide show
  1. package/lib/dts/src/Rule.js +317 -312
  2. package/lib/dts/src/ValidationError.js +16 -16
  3. package/lib/dts/src/index.js +7 -7
  4. package/lib/dts/src/inferFromSchema.js +11 -11
  5. package/lib/dts/src/inferFromSchemaType.js +24 -24
  6. package/lib/dts/src/util/convertToValidationMarker.js +44 -53
  7. package/lib/dts/src/util/deepEquals.js +50 -49
  8. package/lib/dts/src/util/escapeRegex.js +4 -4
  9. package/lib/dts/src/util/normalizeValidationRules.js +87 -78
  10. package/lib/dts/src/util/normalizeValidationRules.test.d.ts +2 -2
  11. package/lib/dts/src/util/normalizeValidationRules.test.js +149 -149
  12. package/lib/dts/src/util/pathToString.js +16 -16
  13. package/lib/dts/src/util/typeString.js +17 -14
  14. package/lib/dts/src/util/typeString.test.d.ts +2 -2
  15. package/lib/dts/src/util/typeString.test.js +23 -24
  16. package/lib/dts/src/validateDocument.js +132 -157
  17. package/lib/dts/src/validateDocument.test.d.ts +2 -2
  18. package/lib/dts/src/validateDocument.test.js +664 -678
  19. package/lib/dts/src/validators/arrayValidator.js +75 -75
  20. package/lib/dts/src/validators/booleanValidator.js +11 -11
  21. package/lib/dts/src/validators/dateValidator.js +74 -68
  22. package/lib/dts/src/validators/genericValidator.js +89 -87
  23. package/lib/dts/src/validators/numberValidator.js +46 -48
  24. package/lib/dts/src/validators/objectValidator.js +47 -47
  25. package/lib/dts/src/validators/slugValidator.js +68 -74
  26. package/lib/dts/src/validators/stringValidator.js +93 -93
  27. package/lib/dts/test/array.test.d.ts +2 -2
  28. package/lib/dts/test/array.test.js +54 -78
  29. package/lib/dts/test/children.test.d.ts +2 -2
  30. package/lib/dts/test/children.test.js +69 -87
  31. package/lib/dts/test/createSchema.d.ts +6 -3
  32. package/lib/dts/test/createSchema.js +17 -17
  33. package/lib/dts/test/generics.test.d.ts +2 -2
  34. package/lib/dts/test/generics.test.js +59 -59
  35. package/lib/dts/test/infer.test.d.ts +2 -2
  36. package/lib/dts/test/infer.test.js +236 -285
  37. package/lib/dts/test/mocks/mockSanityClient.d.ts +4 -5
  38. package/lib/dts/test/mocks/mockSanityClient.d.ts.map +1 -1
  39. package/lib/dts/test/mocks/mockSanityClient.js +6 -6
  40. package/lib/dts/test/nullExport.d.ts +3 -3
  41. package/lib/dts/test/nullExport.js +2 -2
  42. package/lib/dts/test/numbers.test.d.ts +2 -2
  43. package/lib/dts/test/numbers.test.js +56 -62
  44. package/lib/dts/test/strings.test.d.ts +2 -2
  45. package/lib/dts/test/strings.test.js +99 -150
  46. package/lib/dts/tsconfig.lib.tsbuildinfo +1 -1
  47. package/lib/dts/tsconfig.tsbuildinfo +1 -1
  48. package/package.json +4 -4
@@ -1,18 +1,18 @@
1
1
  // Follows the same pattern as Rule and RuleClass. @see Rule
2
2
  const ValidationError = class ValidationError {
3
- constructor(message, options = {}) {
4
- this.message = message
5
- this.paths = options.paths || []
6
- this.children = options.children
7
- this.operation = options.operation
8
- }
9
- cloneWithMessage(msg) {
10
- return new ValidationError(msg, {
11
- paths: this.paths,
12
- children: this.children,
13
- operation: this.operation,
14
- })
15
- }
16
- }
17
- export default ValidationError
18
- //# sourceMappingURL=ValidationError.js.map
3
+ constructor(message, options = {}) {
4
+ this.message = message;
5
+ this.paths = options.paths || [];
6
+ this.children = options.children;
7
+ this.operation = options.operation;
8
+ }
9
+ cloneWithMessage(msg) {
10
+ return new ValidationError(msg, {
11
+ paths: this.paths,
12
+ children: this.children,
13
+ operation: this.operation,
14
+ });
15
+ }
16
+ };
17
+ export default ValidationError;
18
+ //# sourceMappingURL=ValidationError.js.map
@@ -1,7 +1,7 @@
1
- import RuleClass from './Rule'
2
- import validateDocument from './validateDocument'
3
- import inferFromSchema from './inferFromSchema'
4
- import inferFromSchemaType from './inferFromSchemaType'
5
- export default {Rule: RuleClass, validateDocument, inferFromSchema, inferFromSchemaType}
6
- export {RuleClass as Rule, validateDocument, inferFromSchema, inferFromSchemaType}
7
- //# sourceMappingURL=index.js.map
1
+ import RuleClass from './Rule';
2
+ import validateDocument from './validateDocument';
3
+ import inferFromSchema from './inferFromSchema';
4
+ import inferFromSchemaType from './inferFromSchemaType';
5
+ export default { Rule: RuleClass, validateDocument, inferFromSchema, inferFromSchemaType };
6
+ export { RuleClass as Rule, validateDocument, inferFromSchema, inferFromSchemaType };
7
+ //# sourceMappingURL=index.js.map
@@ -1,14 +1,14 @@
1
- import inferFromSchemaType from './inferFromSchemaType'
1
+ import inferFromSchemaType from './inferFromSchemaType';
2
2
  // Note: Mutates schema. Refactor when @sanity/schema supports middlewares
3
3
  function inferFromSchema(schema) {
4
- const typeNames = schema.getTypeNames()
5
- typeNames.forEach((typeName) => {
6
- const schemaType = schema.get(typeName)
7
- if (schemaType) {
8
- inferFromSchemaType(schemaType)
9
- }
10
- })
11
- return schema
4
+ const typeNames = schema.getTypeNames();
5
+ typeNames.forEach((typeName) => {
6
+ const schemaType = schema.get(typeName);
7
+ if (schemaType) {
8
+ inferFromSchemaType(schemaType);
9
+ }
10
+ });
11
+ return schema;
12
12
  }
13
- export default inferFromSchema
14
- //# sourceMappingURL=inferFromSchema.js.map
13
+ export default inferFromSchema;
14
+ //# sourceMappingURL=inferFromSchema.js.map
@@ -1,33 +1,33 @@
1
- import normalizeValidationRules from './util/normalizeValidationRules'
1
+ import normalizeValidationRules from './util/normalizeValidationRules';
2
2
  function traverse(typeDef, visited) {
3
- if (visited.has(typeDef)) {
4
- return
5
- }
6
- visited.add(typeDef)
7
- typeDef.validation = normalizeValidationRules(typeDef)
8
- if ('fields' in typeDef) {
9
- for (const field of typeDef.fields) {
10
- traverse(field.type, visited)
3
+ if (visited.has(typeDef)) {
4
+ return;
11
5
  }
12
- }
13
- if ('of' in typeDef) {
14
- for (const candidate of typeDef.of) {
15
- traverse(candidate, visited)
6
+ visited.add(typeDef);
7
+ typeDef.validation = normalizeValidationRules(typeDef);
8
+ if ('fields' in typeDef) {
9
+ for (const field of typeDef.fields) {
10
+ traverse(field.type, visited);
11
+ }
12
+ }
13
+ if ('of' in typeDef) {
14
+ for (const candidate of typeDef.of) {
15
+ traverse(candidate, visited);
16
+ }
16
17
  }
17
- }
18
- // eslint-disable-next-line no-warning-comments
19
- // @ts-expect-error TODO (eventually): `annotations` does not exist on the SchemaType yet
20
- if (typeDef.annotations) {
21
18
  // eslint-disable-next-line no-warning-comments
22
19
  // @ts-expect-error TODO (eventually): `annotations` does not exist on the SchemaType yet
23
- for (const annotation of typeDef.annotations) {
24
- traverse(annotation, visited)
20
+ if (typeDef.annotations) {
21
+ // eslint-disable-next-line no-warning-comments
22
+ // @ts-expect-error TODO (eventually): `annotations` does not exist on the SchemaType yet
23
+ for (const annotation of typeDef.annotations) {
24
+ traverse(annotation, visited);
25
+ }
25
26
  }
26
- }
27
27
  }
28
28
  function inferFromSchemaType(typeDef) {
29
- traverse(typeDef, new Set())
30
- return typeDef
29
+ traverse(typeDef, new Set());
30
+ return typeDef;
31
31
  }
32
- export default inferFromSchemaType
33
- //# sourceMappingURL=inferFromSchemaType.js.map
32
+ export default inferFromSchemaType;
33
+ //# sourceMappingURL=inferFromSchemaType.js.map
@@ -1,60 +1,51 @@
1
- import ValidationErrorClass from '../ValidationError'
2
- import pathToString from '../util/pathToString'
1
+ import ValidationErrorClass from '../ValidationError';
2
+ import pathToString from '../util/pathToString';
3
3
  export function isNonNullable(t) {
4
- return t !== null || t !== undefined
4
+ return t !== null || t !== undefined;
5
5
  }
6
6
  export function convertToValidationMarker(validatorResult, level, context) {
7
- if (!context) {
8
- throw new Error('missing context')
9
- }
10
- if (validatorResult === true) return []
11
- if (Array.isArray(validatorResult)) {
12
- return validatorResult
13
- .flatMap((child) => convertToValidationMarker(child, level, context))
14
- .filter(isNonNullable)
15
- }
16
- if (typeof validatorResult === 'string') {
17
- return convertToValidationMarker(new ValidationErrorClass(validatorResult), level, context)
18
- }
19
- if (!(validatorResult instanceof ValidationErrorClass)) {
20
- // in order to accept the `ValidationErrorLike`, it at least needs to have
21
- // a `message` in the object
22
- if (typeof validatorResult?.message !== 'string') {
23
- throw new Error(
24
- `${pathToString(
25
- context.path
26
- )}: Validator must return 'true' if valid or an error message as a string on errors`
27
- )
7
+ if (!context) {
8
+ throw new Error('missing context');
28
9
  }
29
- // this is the occurs when an object is returned that wasn't created with the
30
- // `ValidationErrorClass`. in this case, we want to convert it to a class
31
- return convertToValidationMarker(
32
- new ValidationErrorClass(validatorResult.message, validatorResult),
33
- level,
34
- context
35
- )
36
- }
37
- const results = []
38
- // the validator result does not include any item-level relative paths,
39
- // then just return the top-level path with the validation result
40
- if (!validatorResult.paths?.length) {
41
- return [
42
- {
10
+ if (validatorResult === true)
11
+ return [];
12
+ if (Array.isArray(validatorResult)) {
13
+ return validatorResult
14
+ .flatMap((child) => convertToValidationMarker(child, level, context))
15
+ .filter(isNonNullable);
16
+ }
17
+ if (typeof validatorResult === 'string') {
18
+ return convertToValidationMarker(new ValidationErrorClass(validatorResult), level, context);
19
+ }
20
+ if (!(validatorResult instanceof ValidationErrorClass)) {
21
+ // in order to accept the `ValidationErrorLike`, it at least needs to have
22
+ // a `message` in the object
23
+ if (typeof validatorResult?.message !== 'string') {
24
+ throw new Error(`${pathToString(context.path)}: Validator must return 'true' if valid or an error message as a string on errors`);
25
+ }
26
+ // this is the occurs when an object is returned that wasn't created with the
27
+ // `ValidationErrorClass`. in this case, we want to convert it to a class
28
+ return convertToValidationMarker(new ValidationErrorClass(validatorResult.message, validatorResult), level, context);
29
+ }
30
+ const results = [];
31
+ // the validator result does not include any item-level relative paths,
32
+ // then just return the top-level path with the validation result
33
+ if (!validatorResult.paths?.length) {
34
+ return [
35
+ {
36
+ level: level || 'error',
37
+ item: validatorResult,
38
+ path: context.path || [],
39
+ },
40
+ ];
41
+ }
42
+ // if the validator result did include item-level relative paths, then for
43
+ // each item-level relative path, create a validation marker that concatenates
44
+ // the relative path with the path from the validation context
45
+ return results.concat(validatorResult.paths.map((path) => ({
46
+ path: (context.path || []).concat(path),
43
47
  level: level || 'error',
44
48
  item: validatorResult,
45
- path: context.path || [],
46
- },
47
- ]
48
- }
49
- // if the validator result did include item-level relative paths, then for
50
- // each item-level relative path, create a validation marker that concatenates
51
- // the relative path with the path from the validation context
52
- return results.concat(
53
- validatorResult.paths.map((path) => ({
54
- path: (context.path || []).concat(path),
55
- level: level || 'error',
56
- item: validatorResult,
57
- }))
58
- )
49
+ })));
59
50
  }
60
- //# sourceMappingURL=convertToValidationMarker.js.map
51
+ //# sourceMappingURL=convertToValidationMarker.js.map
@@ -8,57 +8,58 @@
8
8
  // control flow branch.
9
9
  // see here: https://www.typescriptlang.org/docs/handbook/2/narrowing.html
10
10
  export default function deepEquals(a, b) {
11
- if (a === b) {
12
- return true
13
- }
14
- if (Array.isArray(a) && Array.isArray(b)) {
15
- if (a.length != b.length) return false
16
- for (let i = 0; i < a.length; i++) {
17
- if (!deepEquals(a[i], b[i])) {
18
- return false
19
- }
11
+ if (a === b) {
12
+ return true;
20
13
  }
21
- return true
22
- }
23
- if (Array.isArray(a) != Array.isArray(b)) {
24
- return false
25
- }
26
- if (a && b && typeof a === 'object' && typeof b === 'object') {
27
- const keys = Object.keys(a)
28
- if (keys.length !== Object.keys(b).length) {
29
- return false
14
+ if (Array.isArray(a) && Array.isArray(b)) {
15
+ if (a.length != b.length)
16
+ return false;
17
+ for (let i = 0; i < a.length; i++) {
18
+ if (!deepEquals(a[i], b[i])) {
19
+ return false;
20
+ }
21
+ }
22
+ return true;
30
23
  }
31
- if (a instanceof Date && b instanceof Date) {
32
- return a.getTime() === b.getTime()
24
+ if (Array.isArray(a) != Array.isArray(b)) {
25
+ return false;
33
26
  }
34
- if (a instanceof Date != b instanceof Date) {
35
- return false
27
+ if (a && b && typeof a === 'object' && typeof b === 'object') {
28
+ const keys = Object.keys(a);
29
+ if (keys.length !== Object.keys(b).length) {
30
+ return false;
31
+ }
32
+ if (a instanceof Date && b instanceof Date) {
33
+ return a.getTime() === b.getTime();
34
+ }
35
+ if (a instanceof Date != b instanceof Date) {
36
+ return false;
37
+ }
38
+ if (a instanceof RegExp && b instanceof RegExp) {
39
+ return a.toString() == b.toString();
40
+ }
41
+ if (a instanceof RegExp != b instanceof RegExp) {
42
+ return false;
43
+ }
44
+ for (let i = 0; i < keys.length; i++) {
45
+ if (keys[i] === '_key') {
46
+ continue;
47
+ }
48
+ if (!Object.prototype.hasOwnProperty.call(b, keys[i])) {
49
+ return false;
50
+ }
51
+ }
52
+ for (let i = 0; i < keys.length; i++) {
53
+ const key = keys[i];
54
+ if (key === '_key') {
55
+ continue;
56
+ }
57
+ if (!deepEquals(a[key], b[key])) {
58
+ return false;
59
+ }
60
+ }
61
+ return true;
36
62
  }
37
- if (a instanceof RegExp && b instanceof RegExp) {
38
- return a.toString() == b.toString()
39
- }
40
- if (a instanceof RegExp != b instanceof RegExp) {
41
- return false
42
- }
43
- for (let i = 0; i < keys.length; i++) {
44
- if (keys[i] === '_key') {
45
- continue
46
- }
47
- if (!Object.prototype.hasOwnProperty.call(b, keys[i])) {
48
- return false
49
- }
50
- }
51
- for (let i = 0; i < keys.length; i++) {
52
- const key = keys[i]
53
- if (key === '_key') {
54
- continue
55
- }
56
- if (!deepEquals(a[key], b[key])) {
57
- return false
58
- }
59
- }
60
- return true
61
- }
62
- return false
63
+ return false;
63
64
  }
64
- //# sourceMappingURL=deepEquals.js.map
65
+ //# sourceMappingURL=deepEquals.js.map
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-useless-escape */
2
2
  export default (string) => {
3
- // Escape ^$.*+-?=!:|\/()[]{},
4
- return string.replace(/[\^\$\.\*\+\-\?\=\!\:\|\\\/\(\)\[\]\{\}\,]/g, '\\$&')
5
- }
6
- //# sourceMappingURL=escapeRegex.js.map
3
+ // Escape ^$.*+-?=!:|\/()[]{},
4
+ return string.replace(/[\^\$\.\*\+\-\?\=\!\:\|\\\/\(\)\[\]\{\}\,]/g, '\\$&');
5
+ };
6
+ //# sourceMappingURL=escapeRegex.js.map
@@ -1,95 +1,104 @@
1
- import RuleClass from '../Rule'
2
- import {slugValidator} from '../validators/slugValidator'
1
+ import RuleClass from '../Rule';
2
+ import { slugValidator } from '../validators/slugValidator';
3
3
  const ruleConstraintTypes = {
4
- array: true,
5
- boolean: true,
6
- date: true,
7
- number: true,
8
- object: true,
9
- string: true,
10
- }
11
- const isRuleConstraint = (typeString) => typeString in ruleConstraintTypes
4
+ array: true,
5
+ boolean: true,
6
+ date: true,
7
+ number: true,
8
+ object: true,
9
+ string: true,
10
+ };
11
+ const isRuleConstraint = (typeString) => typeString in ruleConstraintTypes;
12
12
  function getTypeChain(type, visited) {
13
- if (!type) return []
14
- if (visited.has(type)) return []
15
- visited.add(type)
16
- const next = type.type ? getTypeChain(type.type, visited) : []
17
- return [...next, type]
13
+ if (!type)
14
+ return [];
15
+ if (visited.has(type))
16
+ return [];
17
+ visited.add(type);
18
+ const next = type.type ? getTypeChain(type.type, visited) : [];
19
+ return [...next, type];
18
20
  }
19
21
  function baseRuleReducer(inputRule, type) {
20
- let baseRule = inputRule
21
- if (isRuleConstraint(type.jsonType)) {
22
- baseRule = baseRule.type(type.jsonType)
23
- }
24
- const typeOptionsList =
22
+ let baseRule = inputRule;
23
+ if (isRuleConstraint(type.jsonType)) {
24
+ baseRule = baseRule.type(type.jsonType);
25
+ }
26
+ const typeOptionsList =
25
27
  // if type.options is truthy
26
28
  type?.options &&
27
- // and type.options is an object (non-null from the previous)
28
- typeof type.options === 'object' &&
29
- // and if `list` is in options
30
- 'list' in type.options &&
31
- // then finally access the list
32
- type.options.list
33
- if (Array.isArray(typeOptionsList)) {
34
- baseRule = baseRule.valid(
35
- typeOptionsList.map((option) => extractValueFromListOption(option, type))
36
- )
37
- }
38
- if (type.name === 'datetime') return baseRule.type('Date')
39
- if (type.name === 'date') return baseRule.type('Date')
40
- if (type.name === 'url') return baseRule.uri()
41
- if (type.name === 'slug') return baseRule.custom(slugValidator)
42
- if (type.name === 'reference') return baseRule.reference()
43
- if (type.name === 'email') return baseRule.email()
44
- return baseRule
29
+ // and type.options is an object (non-null from the previous)
30
+ typeof type.options === 'object' &&
31
+ // and if `list` is in options
32
+ 'list' in type.options &&
33
+ // then finally access the list
34
+ type.options.list;
35
+ if (Array.isArray(typeOptionsList)) {
36
+ baseRule = baseRule.valid(typeOptionsList.map((option) => extractValueFromListOption(option, type)));
37
+ }
38
+ if (type.name === 'datetime')
39
+ return baseRule.type('Date');
40
+ if (type.name === 'date')
41
+ return baseRule.type('Date');
42
+ if (type.name === 'url')
43
+ return baseRule.uri();
44
+ if (type.name === 'slug')
45
+ return baseRule.custom(slugValidator);
46
+ if (type.name === 'reference')
47
+ return baseRule.reference();
48
+ if (type.name === 'email')
49
+ return baseRule.email();
50
+ return baseRule;
45
51
  }
46
52
  function hasValueField(typeDef) {
47
- if (!typeDef) return false
48
- if (!('fields' in typeDef) && typeDef.type) return hasValueField(typeDef.type)
49
- if (!('fields' in typeDef)) return false
50
- if (!Array.isArray(typeDef.fields)) return false
51
- return typeDef.fields.some((field) => field.name === 'value')
53
+ if (!typeDef)
54
+ return false;
55
+ if (!('fields' in typeDef) && typeDef.type)
56
+ return hasValueField(typeDef.type);
57
+ if (!('fields' in typeDef))
58
+ return false;
59
+ if (!Array.isArray(typeDef.fields))
60
+ return false;
61
+ return typeDef.fields.some((field) => field.name === 'value');
52
62
  }
53
63
  function extractValueFromListOption(option, typeDef) {
54
- // If you define a `list` option with object items, where the item has a `value` field,
55
- // we don't want to treat that as the value but rather the surrounding object
56
- // This differs from the case where you have a title/value pair setup for a string/number, for instance
57
- if (typeDef.jsonType === 'object' && hasValueField(typeDef)) return option
58
- return option.value === undefined ? option : option.value
64
+ // If you define a `list` option with object items, where the item has a `value` field,
65
+ // we don't want to treat that as the value but rather the surrounding object
66
+ // This differs from the case where you have a title/value pair setup for a string/number, for instance
67
+ if (typeDef.jsonType === 'object' && hasValueField(typeDef))
68
+ return option;
69
+ return option.value === undefined
70
+ ? option
71
+ : option.value;
59
72
  }
60
73
  /**
61
74
  * Takes in `SchemaValidationValue` and returns an array of `Rule` instances.
62
75
  */
63
76
  export default function normalizeValidationRules(typeDef) {
64
- if (!typeDef) {
65
- return []
66
- }
67
- const validation = typeDef.validation
68
- if (Array.isArray(validation)) {
69
- return validation.flatMap((i) =>
70
- normalizeValidationRules({
71
- ...typeDef,
72
- validation: i,
73
- })
74
- )
75
- }
76
- if (validation instanceof RuleClass) {
77
- return [validation]
78
- }
79
- const baseRule =
77
+ if (!typeDef) {
78
+ return [];
79
+ }
80
+ const validation = typeDef.validation;
81
+ if (Array.isArray(validation)) {
82
+ return validation.flatMap((i) => normalizeValidationRules({
83
+ ...typeDef,
84
+ validation: i,
85
+ }));
86
+ }
87
+ if (validation instanceof RuleClass) {
88
+ return [validation];
89
+ }
90
+ const baseRule =
80
91
  // using an object + Object.values to de-dupe the type chain by type name
81
- Object.values(
82
- getTypeChain(typeDef, new Set()).reduce((acc, type) => {
83
- acc[type.name] = type
84
- return acc
85
- }, {})
86
- ).reduce(baseRuleReducer, new RuleClass(typeDef))
87
- if (!validation) {
88
- return [baseRule]
89
- }
90
- return normalizeValidationRules({
91
- ...typeDef,
92
- validation: validation(baseRule),
93
- })
92
+ Object.values(getTypeChain(typeDef, new Set()).reduce((acc, type) => {
93
+ acc[type.name] = type;
94
+ return acc;
95
+ }, {})).reduce(baseRuleReducer, new RuleClass(typeDef));
96
+ if (!validation) {
97
+ return [baseRule];
98
+ }
99
+ return normalizeValidationRules({
100
+ ...typeDef,
101
+ validation: validation(baseRule),
102
+ });
94
103
  }
95
- //# sourceMappingURL=normalizeValidationRules.js.map
104
+ //# sourceMappingURL=normalizeValidationRules.js.map
@@ -1,2 +1,2 @@
1
- export {}
2
- //# sourceMappingURL=normalizeValidationRules.test.d.ts.map
1
+ export {};
2
+ //# sourceMappingURL=normalizeValidationRules.test.d.ts.map