@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.
- package/lib/dts/src/Rule.js +317 -312
- package/lib/dts/src/ValidationError.js +16 -16
- package/lib/dts/src/index.js +7 -7
- package/lib/dts/src/inferFromSchema.js +11 -11
- package/lib/dts/src/inferFromSchemaType.js +24 -24
- package/lib/dts/src/util/convertToValidationMarker.js +44 -53
- package/lib/dts/src/util/deepEquals.js +50 -49
- package/lib/dts/src/util/escapeRegex.js +4 -4
- package/lib/dts/src/util/normalizeValidationRules.js +87 -78
- package/lib/dts/src/util/normalizeValidationRules.test.d.ts +2 -2
- package/lib/dts/src/util/normalizeValidationRules.test.js +149 -149
- package/lib/dts/src/util/pathToString.js +16 -16
- package/lib/dts/src/util/typeString.js +17 -14
- package/lib/dts/src/util/typeString.test.d.ts +2 -2
- package/lib/dts/src/util/typeString.test.js +23 -24
- package/lib/dts/src/validateDocument.js +132 -157
- package/lib/dts/src/validateDocument.test.d.ts +2 -2
- package/lib/dts/src/validateDocument.test.js +664 -678
- package/lib/dts/src/validators/arrayValidator.js +75 -75
- package/lib/dts/src/validators/booleanValidator.js +11 -11
- package/lib/dts/src/validators/dateValidator.js +74 -68
- package/lib/dts/src/validators/genericValidator.js +89 -87
- package/lib/dts/src/validators/numberValidator.js +46 -48
- package/lib/dts/src/validators/objectValidator.js +47 -47
- package/lib/dts/src/validators/slugValidator.js +68 -74
- package/lib/dts/src/validators/stringValidator.js +93 -93
- package/lib/dts/test/array.test.d.ts +2 -2
- package/lib/dts/test/array.test.js +54 -78
- package/lib/dts/test/children.test.d.ts +2 -2
- package/lib/dts/test/children.test.js +69 -87
- package/lib/dts/test/createSchema.d.ts +6 -3
- package/lib/dts/test/createSchema.js +17 -17
- package/lib/dts/test/generics.test.d.ts +2 -2
- package/lib/dts/test/generics.test.js +59 -59
- package/lib/dts/test/infer.test.d.ts +2 -2
- package/lib/dts/test/infer.test.js +236 -285
- package/lib/dts/test/mocks/mockSanityClient.d.ts +4 -5
- package/lib/dts/test/mocks/mockSanityClient.d.ts.map +1 -1
- package/lib/dts/test/mocks/mockSanityClient.js +6 -6
- package/lib/dts/test/nullExport.d.ts +3 -3
- package/lib/dts/test/nullExport.js +2 -2
- package/lib/dts/test/numbers.test.d.ts +2 -2
- package/lib/dts/test/numbers.test.js +56 -62
- package/lib/dts/test/strings.test.d.ts +2 -2
- package/lib/dts/test/strings.test.js +99 -150
- package/lib/dts/tsconfig.lib.tsbuildinfo +1 -1
- package/lib/dts/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
import {isReference} from '@sanity/types'
|
|
2
|
-
import genericValidator from './genericValidator'
|
|
3
|
-
const metaKeys = ['_key', '_type', '_weak']
|
|
1
|
+
import { isReference } from '@sanity/types';
|
|
2
|
+
import genericValidator from './genericValidator';
|
|
3
|
+
const metaKeys = ['_key', '_type', '_weak'];
|
|
4
4
|
const objectValidators = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
export default objectValidators
|
|
48
|
-
//# sourceMappingURL=objectValidator.js.map
|
|
5
|
+
...genericValidator,
|
|
6
|
+
presence: (expected, value, message) => {
|
|
7
|
+
if (expected !== 'required') {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
const keys = value && Object.keys(value).filter((key) => !metaKeys.includes(key));
|
|
11
|
+
if (value === undefined || (keys && keys.length === 0)) {
|
|
12
|
+
return message || 'Required';
|
|
13
|
+
}
|
|
14
|
+
return true;
|
|
15
|
+
},
|
|
16
|
+
reference: async (_unused, value, message, context) => {
|
|
17
|
+
if (!value) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
if (!isReference(value)) {
|
|
21
|
+
return message || true;
|
|
22
|
+
}
|
|
23
|
+
const { type, getDocumentExists } = context;
|
|
24
|
+
if (!type) {
|
|
25
|
+
throw new Error(`\`type\` was not provided in validation context`);
|
|
26
|
+
}
|
|
27
|
+
if ('weak' in type && type.weak) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
if (!getDocumentExists) {
|
|
31
|
+
throw new Error(`\`getDocumentExists\` was not provided in validation context`);
|
|
32
|
+
}
|
|
33
|
+
const exists = await getDocumentExists({ id: value._ref });
|
|
34
|
+
if (!exists) {
|
|
35
|
+
return 'This reference must be published';
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
},
|
|
39
|
+
assetRequired: (flag, value, message) => {
|
|
40
|
+
if (!value || !value.asset || !value.asset._ref) {
|
|
41
|
+
const assetType = flag.assetType || 'Asset';
|
|
42
|
+
return message || `${assetType} required`;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
export default objectValidators;
|
|
48
|
+
//# sourceMappingURL=objectValidator.js.map
|
|
@@ -1,65 +1,59 @@
|
|
|
1
|
-
import {isKeyedObject} from '@sanity/types'
|
|
2
|
-
import {memoize} from 'lodash'
|
|
1
|
+
import { isKeyedObject } from '@sanity/types';
|
|
2
|
+
import { memoize } from 'lodash';
|
|
3
3
|
// import getClient from '../getClient'
|
|
4
|
-
const memoizedWarnOnArraySlug = memoize(warnOnArraySlug)
|
|
4
|
+
const memoizedWarnOnArraySlug = memoize(warnOnArraySlug);
|
|
5
5
|
function getDocumentIds(id) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
const isDraft = id.indexOf('drafts.') === 0;
|
|
7
|
+
return {
|
|
8
|
+
published: isDraft ? id.slice('drafts.'.length) : id,
|
|
9
|
+
draft: isDraft ? id : `drafts.${id}`,
|
|
10
|
+
};
|
|
11
11
|
}
|
|
12
12
|
function serializePath(path) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
return path.reduce((target, part, i) => {
|
|
14
|
+
const isIndex = typeof part === 'number';
|
|
15
|
+
const isKey = isKeyedObject(part);
|
|
16
|
+
const separator = i === 0 ? '' : '.';
|
|
17
|
+
const add = isIndex || isKey ? '[]' : `${separator}${part}`;
|
|
18
|
+
return `${target}${add}`;
|
|
19
|
+
}, '');
|
|
20
20
|
}
|
|
21
21
|
const defaultIsUnique = (slug, context) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
},
|
|
50
|
-
{tag: 'validation.slug-is-unique'}
|
|
51
|
-
)
|
|
52
|
-
}
|
|
22
|
+
const { client, document, path, type } = context;
|
|
23
|
+
const schemaOptions = type?.options;
|
|
24
|
+
if (!document) {
|
|
25
|
+
throw new Error(`\`document\` was not provided in validation context.`);
|
|
26
|
+
}
|
|
27
|
+
if (!path) {
|
|
28
|
+
throw new Error(`\`path\` was not provided in validation context.`);
|
|
29
|
+
}
|
|
30
|
+
const disableArrayWarning = schemaOptions?.disableArrayWarning || false;
|
|
31
|
+
const { published, draft } = getDocumentIds(document._id);
|
|
32
|
+
const docType = document._type;
|
|
33
|
+
const atPath = serializePath(path.concat('current'));
|
|
34
|
+
if (!disableArrayWarning && atPath.includes('[]')) {
|
|
35
|
+
memoizedWarnOnArraySlug(serializePath(path));
|
|
36
|
+
}
|
|
37
|
+
const constraints = [
|
|
38
|
+
'_type == $docType',
|
|
39
|
+
`!(_id in [$draft, $published])`,
|
|
40
|
+
`${atPath} == $slug`,
|
|
41
|
+
].join(' && ');
|
|
42
|
+
return client.fetch(`!defined(*[${constraints}][0]._id)`, {
|
|
43
|
+
docType,
|
|
44
|
+
draft,
|
|
45
|
+
published,
|
|
46
|
+
slug,
|
|
47
|
+
}, { tag: 'validation.slug-is-unique' });
|
|
48
|
+
};
|
|
53
49
|
function warnOnArraySlug(serializedPath) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
)
|
|
62
|
-
/* eslint-enable no-console */
|
|
50
|
+
/* eslint-disable no-console */
|
|
51
|
+
console.warn([
|
|
52
|
+
`Slug field at path ${serializedPath} is within an array and cannot be automatically checked for uniqueness`,
|
|
53
|
+
`If you need to check for uniqueness, provide your own "isUnique" method`,
|
|
54
|
+
`To disable this message, set \`disableArrayWarning: true\` on the slug \`options\` field`,
|
|
55
|
+
].join('\n'));
|
|
56
|
+
/* eslint-enable no-console */
|
|
63
57
|
}
|
|
64
58
|
/**
|
|
65
59
|
* Validates slugs values by querying for uniqueness from the client.
|
|
@@ -68,22 +62,22 @@ function warnOnArraySlug(serializedPath) {
|
|
|
68
62
|
* that's populated in `inferFromSchemaType` when the type name is `slug`
|
|
69
63
|
*/
|
|
70
64
|
export const slugValidator = async (value, context) => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
//# sourceMappingURL=slugValidator.js.map
|
|
65
|
+
if (!value) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
if (typeof value !== 'object') {
|
|
69
|
+
return 'Slug must be an object';
|
|
70
|
+
}
|
|
71
|
+
const slugValue = value.current;
|
|
72
|
+
if (!slugValue) {
|
|
73
|
+
return 'Slug must have a value';
|
|
74
|
+
}
|
|
75
|
+
const options = context?.type?.options;
|
|
76
|
+
const isUnique = options?.isUnique || defaultIsUnique;
|
|
77
|
+
const wasUnique = await isUnique(slugValue, { ...context, defaultIsUnique });
|
|
78
|
+
if (wasUnique) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
return 'Slug is already in use';
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=slugValidator.js.map
|
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
import genericValidator from './genericValidator'
|
|
2
|
-
const DUMMY_ORIGIN = 'http://sanity'
|
|
3
|
-
const emailRegex =
|
|
4
|
-
|
|
5
|
-
const isRelativeUrl = (url) => /^\.*\//.test(url)
|
|
1
|
+
import genericValidator from './genericValidator';
|
|
2
|
+
const DUMMY_ORIGIN = 'http://sanity';
|
|
3
|
+
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,}))$/;
|
|
4
|
+
const isRelativeUrl = (url) => /^\.*\//.test(url);
|
|
6
5
|
const stringValidators = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
6
|
+
...genericValidator,
|
|
7
|
+
min: (minLength, value, message) => {
|
|
8
|
+
if (!value || value.length >= minLength) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
return message || `Must be at least ${minLength} characters long`;
|
|
12
|
+
},
|
|
13
|
+
max: (maxLength, value, message) => {
|
|
14
|
+
if (!value || value.length <= maxLength) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return message || `Must be at most ${maxLength} characters long`;
|
|
18
|
+
},
|
|
19
|
+
length: (wantedLength, value, message) => {
|
|
20
|
+
const strValue = value || '';
|
|
21
|
+
if (strValue.length === wantedLength) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return message || `Must be exactly ${wantedLength} characters long`;
|
|
25
|
+
},
|
|
26
|
+
uri: (constraints, value, message) => {
|
|
27
|
+
const strValue = value || '';
|
|
28
|
+
const { options } = constraints;
|
|
29
|
+
const { allowCredentials, relativeOnly } = options;
|
|
30
|
+
const allowRelative = options.allowRelative || relativeOnly;
|
|
31
|
+
let url;
|
|
32
|
+
try {
|
|
33
|
+
// WARNING: Safari checks for a given `base` param by looking at the length of arguments passed
|
|
34
|
+
// to new URL(str, base), and will fail if invoked with new URL(strValue, undefined)
|
|
35
|
+
url = allowRelative ? new URL(strValue, DUMMY_ORIGIN) : new URL(strValue);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
return message || 'Not a valid URL';
|
|
39
|
+
}
|
|
40
|
+
if (relativeOnly && url.origin !== DUMMY_ORIGIN) {
|
|
41
|
+
return message || 'Only relative URLs are allowed';
|
|
42
|
+
}
|
|
43
|
+
if (!allowRelative && url.origin === DUMMY_ORIGIN && isRelativeUrl(strValue)) {
|
|
44
|
+
return message || 'Relative URLs are not allowed';
|
|
45
|
+
}
|
|
46
|
+
if (!allowCredentials && (url.username || url.password)) {
|
|
47
|
+
return message || `Username/password not allowed`;
|
|
48
|
+
}
|
|
49
|
+
const urlScheme = url.protocol.replace(/:$/, '');
|
|
50
|
+
const matchesAllowedScheme = options.scheme.some((scheme) => scheme.test(urlScheme));
|
|
51
|
+
if (!matchesAllowedScheme) {
|
|
52
|
+
return message || 'Does not match allowed protocols/schemes';
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
},
|
|
56
|
+
stringCasing: (casing, value, message) => {
|
|
57
|
+
const strValue = value || '';
|
|
58
|
+
if (casing === 'uppercase' && strValue !== strValue.toLocaleUpperCase()) {
|
|
59
|
+
return message || `Must be all uppercase letters`;
|
|
60
|
+
}
|
|
61
|
+
if (casing === 'lowercase' && strValue !== strValue.toLocaleLowerCase()) {
|
|
62
|
+
return message || `Must be all lowercase letters`;
|
|
63
|
+
}
|
|
64
|
+
return true;
|
|
65
|
+
},
|
|
66
|
+
presence: (flag, value, message) => {
|
|
67
|
+
if (flag === 'required' && !value) {
|
|
68
|
+
return message || 'Required';
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
},
|
|
72
|
+
regex: (options, value, message) => {
|
|
73
|
+
const { pattern, name, invert } = options;
|
|
74
|
+
const regName = name || `"${pattern.toString()}"`;
|
|
75
|
+
const strValue = value || '';
|
|
76
|
+
const matches = pattern.test(strValue);
|
|
77
|
+
if ((!invert && !matches) || (invert && matches)) {
|
|
78
|
+
const defaultMessage = invert
|
|
79
|
+
? `Should not match ${regName}-pattern`
|
|
80
|
+
: `Does not match ${regName}-pattern`;
|
|
81
|
+
return message || defaultMessage;
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
},
|
|
85
|
+
email: (_unused, value, message) => {
|
|
86
|
+
const strValue = `${value || ''}`.trim();
|
|
87
|
+
if (!strValue || emailRegex.test(strValue)) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
return message || 'Must be a valid email address';
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
export default stringValidators;
|
|
94
|
+
//# sourceMappingURL=stringValidator.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {}
|
|
2
|
-
//# sourceMappingURL=array.test.d.ts.map
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=array.test.d.ts.map
|
|
@@ -1,79 +1,55 @@
|
|
|
1
|
-
import {Rule} from '../src'
|
|
2
|
-
const context = {client: {}}
|
|
1
|
+
import { Rule } from '../src';
|
|
2
|
+
const context = { client: {} };
|
|
3
3
|
describe('array', () => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
'array unique: valid'
|
|
57
|
-
)
|
|
58
|
-
await expect(rule.validate(['a', 'a', 'c', 'd'].map(refArr), context)).resolves.toMatchSnapshot(
|
|
59
|
-
'array unique: duplicates'
|
|
60
|
-
)
|
|
61
|
-
})
|
|
62
|
-
test('unique constraint (default, bool values)', async () => {
|
|
63
|
-
const rule = Rule.array().unique()
|
|
64
|
-
await expect(rule.validate([true, false], context)).resolves.toMatchSnapshot(
|
|
65
|
-
'boolean unique: valid'
|
|
66
|
-
)
|
|
67
|
-
await expect(rule.validate([false, true, false], context)).resolves.toMatchSnapshot(
|
|
68
|
-
'boolean unique: duplicates'
|
|
69
|
-
)
|
|
70
|
-
})
|
|
71
|
-
test('unique constraint (default, numeric values)', async () => {
|
|
72
|
-
const rule = Rule.array().unique()
|
|
73
|
-
await expect(rule.validate([1, 3], context)).resolves.toMatchSnapshot('numeric unique: valid')
|
|
74
|
-
await expect(rule.validate([3, 1, 3], context)).resolves.toMatchSnapshot(
|
|
75
|
-
'numeric unique: duplicates'
|
|
76
|
-
)
|
|
77
|
-
})
|
|
78
|
-
})
|
|
79
|
-
//# sourceMappingURL=array.test.js.map
|
|
4
|
+
test('required constraint', async () => {
|
|
5
|
+
const rule = Rule.array().required();
|
|
6
|
+
await expect(rule.validate(null, context)).resolves.toMatchSnapshot('required: null');
|
|
7
|
+
await expect(rule.validate(undefined, context)).resolves.toMatchSnapshot('required: undefined');
|
|
8
|
+
await expect(rule.validate([], context)).resolves.toMatchSnapshot('required: empty array');
|
|
9
|
+
await expect(rule.validate(['hei'], context)).resolves.toMatchSnapshot('required: valid');
|
|
10
|
+
});
|
|
11
|
+
test('min length constraint', async () => {
|
|
12
|
+
const rule = Rule.array().min(2);
|
|
13
|
+
await expect(rule.validate(['a'], context)).resolves.toMatchSnapshot('min length: too short');
|
|
14
|
+
await expect(rule.validate(['a', 'b', 'c'], context)).resolves.toMatchSnapshot('min length: valid');
|
|
15
|
+
});
|
|
16
|
+
test('max length constraint', async () => {
|
|
17
|
+
const rule = Rule.array().max(2);
|
|
18
|
+
await expect(rule.validate(['a', 'b', 'c', 'd'], context)).resolves.toMatchSnapshot('max length: too long');
|
|
19
|
+
await expect(rule.validate(['a'], context)).resolves.toMatchSnapshot('max length: valid');
|
|
20
|
+
});
|
|
21
|
+
test('exact length constraint', async () => {
|
|
22
|
+
const rule = Rule.array().length(2);
|
|
23
|
+
await expect(rule.validate(['a', 'b', 'c'], context)).resolves.toMatchSnapshot('exact length: too long');
|
|
24
|
+
await expect(rule.validate(['a'], context)).resolves.toMatchSnapshot('exact length: too short');
|
|
25
|
+
await expect(rule.validate(['a', 'b'], context)).resolves.toMatchSnapshot('exact length: valid');
|
|
26
|
+
});
|
|
27
|
+
test('unique constraint (default, simple values)', async () => {
|
|
28
|
+
const rule = Rule.array().unique();
|
|
29
|
+
await expect(rule.validate(['a', 'b', 'c', 'd'], context)).resolves.toMatchSnapshot('simple unique: valid');
|
|
30
|
+
await expect(rule.validate(['a', 'b', 'c', 'a'], context)).resolves.toMatchSnapshot('simple unique: duplicates');
|
|
31
|
+
});
|
|
32
|
+
test('unique constraint (default, object values)', async () => {
|
|
33
|
+
const rule = Rule.array().unique();
|
|
34
|
+
const ref = (id) => ({ _ref: id, _type: 'reference' });
|
|
35
|
+
await expect(rule.validate(['a', 'b', 'c', 'd'].map(ref), context)).resolves.toMatchSnapshot('object unique: valid');
|
|
36
|
+
await expect(rule.validate(['a', 'b', 'c', 'a'].map(ref), context)).resolves.toMatchSnapshot('object unique: duplicates');
|
|
37
|
+
});
|
|
38
|
+
test('unique constraint (default, array values)', async () => {
|
|
39
|
+
const rule = Rule.array().unique();
|
|
40
|
+
const refArr = (id) => [{ _ref: id, _type: 'reference' }];
|
|
41
|
+
await expect(rule.validate(['a', 'b', 'c', 'd'].map(refArr), context)).resolves.toMatchSnapshot('array unique: valid');
|
|
42
|
+
await expect(rule.validate(['a', 'a', 'c', 'd'].map(refArr), context)).resolves.toMatchSnapshot('array unique: duplicates');
|
|
43
|
+
});
|
|
44
|
+
test('unique constraint (default, bool values)', async () => {
|
|
45
|
+
const rule = Rule.array().unique();
|
|
46
|
+
await expect(rule.validate([true, false], context)).resolves.toMatchSnapshot('boolean unique: valid');
|
|
47
|
+
await expect(rule.validate([false, true, false], context)).resolves.toMatchSnapshot('boolean unique: duplicates');
|
|
48
|
+
});
|
|
49
|
+
test('unique constraint (default, numeric values)', async () => {
|
|
50
|
+
const rule = Rule.array().unique();
|
|
51
|
+
await expect(rule.validate([1, 3], context)).resolves.toMatchSnapshot('numeric unique: valid');
|
|
52
|
+
await expect(rule.validate([3, 1, 3], context)).resolves.toMatchSnapshot('numeric unique: duplicates');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=array.test.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {}
|
|
2
|
-
//# sourceMappingURL=children.test.d.ts.map
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=children.test.d.ts.map
|