@sanity/validation 3.0.0-dev-preview.20 → 3.0.0-dev-preview.21
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/index.d.ts +36 -13
- package/lib/index.js +1525 -1291
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +1542 -0
- package/lib/index.mjs.map +1 -0
- package/package.json +24 -18
- package/src/index.ts +3 -1
- package/src/util/requestIdleCallback.ts +31 -0
- package/src/validateDocument.test.ts +0 -80
- package/src/validateDocument.ts +82 -43
- package/src/validators/slugValidator.ts +16 -2
- package/lib/dts/src/Rule.d.ts +0 -4
- package/lib/dts/src/Rule.d.ts.map +0 -1
- package/lib/dts/src/Rule.js +0 -336
- package/lib/dts/src/Rule.js.map +0 -1
- package/lib/dts/src/ValidationError.d.ts +0 -4
- package/lib/dts/src/ValidationError.d.ts.map +0 -1
- package/lib/dts/src/ValidationError.js +0 -18
- package/lib/dts/src/ValidationError.js.map +0 -1
- package/lib/dts/src/index.d.ts.map +0 -1
- package/lib/dts/src/index.js +0 -7
- package/lib/dts/src/index.js.map +0 -1
- package/lib/dts/src/inferFromSchema.d.ts +0 -4
- package/lib/dts/src/inferFromSchema.d.ts.map +0 -1
- package/lib/dts/src/inferFromSchema.js +0 -14
- package/lib/dts/src/inferFromSchema.js.map +0 -1
- package/lib/dts/src/inferFromSchemaType.d.ts +0 -5
- package/lib/dts/src/inferFromSchemaType.d.ts.map +0 -1
- package/lib/dts/src/inferFromSchemaType.js +0 -33
- package/lib/dts/src/inferFromSchemaType.js.map +0 -1
- package/lib/dts/src/util/convertToValidationMarker.d.ts +0 -6
- package/lib/dts/src/util/convertToValidationMarker.d.ts.map +0 -1
- package/lib/dts/src/util/convertToValidationMarker.js +0 -51
- package/lib/dts/src/util/convertToValidationMarker.js.map +0 -1
- package/lib/dts/src/util/deepEquals.d.ts +0 -6
- package/lib/dts/src/util/deepEquals.d.ts.map +0 -1
- package/lib/dts/src/util/deepEquals.js +0 -65
- package/lib/dts/src/util/deepEquals.js.map +0 -1
- package/lib/dts/src/util/escapeRegex.d.ts +0 -3
- package/lib/dts/src/util/escapeRegex.d.ts.map +0 -1
- package/lib/dts/src/util/escapeRegex.js +0 -6
- package/lib/dts/src/util/escapeRegex.js.map +0 -1
- package/lib/dts/src/util/normalizeValidationRules.d.ts +0 -6
- package/lib/dts/src/util/normalizeValidationRules.d.ts.map +0 -1
- package/lib/dts/src/util/normalizeValidationRules.js +0 -104
- package/lib/dts/src/util/normalizeValidationRules.js.map +0 -1
- package/lib/dts/src/util/normalizeValidationRules.test.d.ts +0 -2
- package/lib/dts/src/util/normalizeValidationRules.test.d.ts.map +0 -1
- package/lib/dts/src/util/normalizeValidationRules.test.js +0 -150
- package/lib/dts/src/util/normalizeValidationRules.test.js.map +0 -1
- package/lib/dts/src/util/pathToString.d.ts +0 -3
- package/lib/dts/src/util/pathToString.d.ts.map +0 -1
- package/lib/dts/src/util/pathToString.js +0 -18
- package/lib/dts/src/util/pathToString.js.map +0 -1
- package/lib/dts/src/util/typeString.d.ts +0 -2
- package/lib/dts/src/util/typeString.d.ts.map +0 -1
- package/lib/dts/src/util/typeString.js +0 -23
- package/lib/dts/src/util/typeString.js.map +0 -1
- package/lib/dts/src/util/typeString.test.d.ts +0 -2
- package/lib/dts/src/util/typeString.test.d.ts.map +0 -1
- package/lib/dts/src/util/typeString.test.js +0 -24
- package/lib/dts/src/util/typeString.test.js.map +0 -1
- package/lib/dts/src/validateDocument.d.ts +0 -25
- package/lib/dts/src/validateDocument.d.ts.map +0 -1
- package/lib/dts/src/validateDocument.js +0 -165
- package/lib/dts/src/validateDocument.js.map +0 -1
- package/lib/dts/src/validateDocument.test.d.ts +0 -2
- package/lib/dts/src/validateDocument.test.d.ts.map +0 -1
- package/lib/dts/src/validateDocument.test.js +0 -717
- package/lib/dts/src/validateDocument.test.js.map +0 -1
- package/lib/dts/src/validators/arrayValidator.d.ts +0 -4
- package/lib/dts/src/validators/arrayValidator.d.ts.map +0 -1
- package/lib/dts/src/validators/arrayValidator.js +0 -79
- package/lib/dts/src/validators/arrayValidator.js.map +0 -1
- package/lib/dts/src/validators/booleanValidator.d.ts +0 -4
- package/lib/dts/src/validators/booleanValidator.d.ts.map +0 -1
- package/lib/dts/src/validators/booleanValidator.js +0 -12
- package/lib/dts/src/validators/booleanValidator.js.map +0 -1
- package/lib/dts/src/validators/dateValidator.d.ts +0 -5
- package/lib/dts/src/validators/dateValidator.d.ts.map +0 -1
- package/lib/dts/src/validators/dateValidator.js +0 -83
- package/lib/dts/src/validators/dateValidator.js.map +0 -1
- package/lib/dts/src/validators/genericValidator.d.ts +0 -4
- package/lib/dts/src/validators/genericValidator.d.ts.map +0 -1
- package/lib/dts/src/validators/genericValidator.js +0 -93
- package/lib/dts/src/validators/genericValidator.js.map +0 -1
- package/lib/dts/src/validators/numberValidator.d.ts +0 -4
- package/lib/dts/src/validators/numberValidator.d.ts.map +0 -1
- package/lib/dts/src/validators/numberValidator.js +0 -47
- package/lib/dts/src/validators/numberValidator.js.map +0 -1
- package/lib/dts/src/validators/objectValidator.d.ts +0 -4
- package/lib/dts/src/validators/objectValidator.d.ts.map +0 -1
- package/lib/dts/src/validators/objectValidator.js +0 -48
- package/lib/dts/src/validators/objectValidator.js.map +0 -1
- package/lib/dts/src/validators/slugValidator.d.ts +0 -9
- package/lib/dts/src/validators/slugValidator.d.ts.map +0 -1
- package/lib/dts/src/validators/slugValidator.js +0 -83
- package/lib/dts/src/validators/slugValidator.js.map +0 -1
- package/lib/dts/src/validators/stringValidator.d.ts +0 -4
- package/lib/dts/src/validators/stringValidator.d.ts.map +0 -1
- package/lib/dts/src/validators/stringValidator.js +0 -94
- package/lib/dts/src/validators/stringValidator.js.map +0 -1
- package/lib/dts/test/array.test.d.ts +0 -2
- package/lib/dts/test/array.test.d.ts.map +0 -1
- package/lib/dts/test/array.test.js +0 -55
- package/lib/dts/test/array.test.js.map +0 -1
- package/lib/dts/test/children.test.d.ts +0 -2
- package/lib/dts/test/children.test.d.ts.map +0 -1
- package/lib/dts/test/children.test.js +0 -70
- package/lib/dts/test/children.test.js.map +0 -1
- package/lib/dts/test/createSchema.d.ts +0 -6
- package/lib/dts/test/createSchema.d.ts.map +0 -1
- package/lib/dts/test/createSchema.js +0 -19
- package/lib/dts/test/createSchema.js.map +0 -1
- package/lib/dts/test/generics.test.d.ts +0 -2
- package/lib/dts/test/generics.test.d.ts.map +0 -1
- package/lib/dts/test/generics.test.js +0 -60
- package/lib/dts/test/generics.test.js.map +0 -1
- package/lib/dts/test/infer.test.d.ts +0 -2
- package/lib/dts/test/infer.test.d.ts.map +0 -1
- package/lib/dts/test/infer.test.js +0 -244
- package/lib/dts/test/infer.test.js.map +0 -1
- package/lib/dts/test/mocks/mockSanityClient.d.ts +0 -6
- package/lib/dts/test/mocks/mockSanityClient.d.ts.map +0 -1
- package/lib/dts/test/mocks/mockSanityClient.js +0 -8
- package/lib/dts/test/mocks/mockSanityClient.js.map +0 -1
- package/lib/dts/test/nullExport.d.ts +0 -3
- package/lib/dts/test/nullExport.d.ts.map +0 -1
- package/lib/dts/test/nullExport.js +0 -4
- package/lib/dts/test/nullExport.js.map +0 -1
- package/lib/dts/test/numbers.test.d.ts +0 -2
- package/lib/dts/test/numbers.test.d.ts.map +0 -1
- package/lib/dts/test/numbers.test.js +0 -57
- package/lib/dts/test/numbers.test.js.map +0 -1
- package/lib/dts/test/strings.test.d.ts +0 -2
- package/lib/dts/test/strings.test.d.ts.map +0 -1
- package/lib/dts/test/strings.test.js +0 -100
- package/lib/dts/test/strings.test.js.map +0 -1
- package/lib/dts/tsconfig.lib.tsbuildinfo +0 -1
- package/lib/dts/tsconfig.tsbuildinfo +0 -1
- package/lib/index.cjs +0 -1341
- package/lib/index.cjs.map +0 -1
|
@@ -1,94 +0,0 @@
|
|
|
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);
|
|
5
|
-
const stringValidators = {
|
|
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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stringValidator.js","sourceRoot":"","sources":["../../../../src/validators/stringValidator.ts"],"names":[],"mappings":"AACA,OAAO,gBAAgB,MAAM,oBAAoB,CAAA;AAEjD,MAAM,YAAY,GAAG,eAAe,CAAA;AACpC,MAAM,UAAU,GACd,sJAAsJ,CAAA;AACxJ,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAEzD,MAAM,gBAAgB,GAAe;IACnC,GAAG,gBAAgB;IAEnB,GAAG,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACjC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,SAAS,EAAE;YACvC,OAAO,IAAI,CAAA;SACZ;QAED,OAAO,OAAO,IAAI,oBAAoB,SAAS,kBAAkB,CAAA;IACnE,CAAC;IAED,GAAG,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACjC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,SAAS,EAAE;YACvC,OAAO,IAAI,CAAA;SACZ;QAED,OAAO,OAAO,IAAI,mBAAmB,SAAS,kBAAkB,CAAA;IAClE,CAAC;IAED,MAAM,EAAE,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACvC,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE,CAAA;QAC5B,IAAI,QAAQ,CAAC,MAAM,KAAK,YAAY,EAAE;YACpC,OAAO,IAAI,CAAA;SACZ;QAED,OAAO,OAAO,IAAI,mBAAmB,YAAY,kBAAkB,CAAA;IACrE,CAAC;IAED,GAAG,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACnC,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE,CAAA;QAC5B,MAAM,EAAC,OAAO,EAAC,GAAG,WAAW,CAAA;QAC7B,MAAM,EAAC,gBAAgB,EAAE,YAAY,EAAC,GAAG,OAAO,CAAA;QAChD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,YAAY,CAAA;QAE3D,IAAI,GAAG,CAAA;QACP,IAAI;YACF,+FAA+F;YAC/F,oFAAoF;YACpF,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAA;SAC1E;QAAC,OAAO,GAAG,EAAE;YACZ,OAAO,OAAO,IAAI,iBAAiB,CAAA;SACpC;QAED,IAAI,YAAY,IAAI,GAAG,CAAC,MAAM,KAAK,YAAY,EAAE;YAC/C,OAAO,OAAO,IAAI,gCAAgC,CAAA;SACnD;QAED,IAAI,CAAC,aAAa,IAAI,GAAG,CAAC,MAAM,KAAK,YAAY,IAAI,aAAa,CAAC,QAAQ,CAAC,EAAE;YAC5E,OAAO,OAAO,IAAI,+BAA+B,CAAA;SAClD;QAED,IAAI,CAAC,gBAAgB,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,EAAE;YACvD,OAAO,OAAO,IAAI,+BAA+B,CAAA;SAClD;QAED,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAChD,MAAM,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;QACpF,IAAI,CAAC,oBAAoB,EAAE;YACzB,OAAO,OAAO,IAAI,0CAA0C,CAAA;SAC7D;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAED,YAAY,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACvC,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE,CAAA;QAC5B,IAAI,MAAM,KAAK,WAAW,IAAI,QAAQ,KAAK,QAAQ,CAAC,iBAAiB,EAAE,EAAE;YACvE,OAAO,OAAO,IAAI,+BAA+B,CAAA;SAClD;QAED,IAAI,MAAM,KAAK,WAAW,IAAI,QAAQ,KAAK,QAAQ,CAAC,iBAAiB,EAAE,EAAE;YACvE,OAAO,OAAO,IAAI,+BAA+B,CAAA;SAClD;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAED,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACjC,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC,KAAK,EAAE;YACjC,OAAO,OAAO,IAAI,UAAU,CAAA;SAC7B;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACjC,MAAM,EAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAC,GAAG,OAAO,CAAA;QACvC,MAAM,OAAO,GAAG,IAAI,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAA;QACjD,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE,CAAA;QAC5B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACtC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,EAAE;YAChD,MAAM,cAAc,GAAG,MAAM;gBAC3B,CAAC,CAAC,oBAAoB,OAAO,UAAU;gBACvC,CAAC,CAAC,kBAAkB,OAAO,UAAU,CAAA;YAEvC,OAAO,OAAO,IAAI,cAAc,CAAA;SACjC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACjC,MAAM,QAAQ,GAAG,GAAG,KAAK,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;QACxC,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;YAC1C,OAAO,IAAI,CAAA;SACZ;QAED,OAAO,OAAO,IAAI,+BAA+B,CAAA;IACnD,CAAC;CACF,CAAA;AAED,eAAe,gBAAgB,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"array.test.d.ts","sourceRoot":"","sources":["../../../test/array.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { Rule } from '../src';
|
|
2
|
-
const context = { client: {} };
|
|
3
|
-
describe('array', () => {
|
|
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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"array.test.js","sourceRoot":"","sources":["../../../test/array.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,QAAQ,CAAA;AAE3B,MAAM,OAAO,GAAQ,EAAC,MAAM,EAAE,EAAE,EAAC,CAAA;AAEjC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,IAAI,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAA;QACpC,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAA;QACrF,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAA;QAC/F,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAA;QAC1F,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAA;IAC3F,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QAChC,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAA;QAC7F,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAC5E,mBAAmB,CACpB,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QAChC,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CACjF,sBAAsB,CACvB,CAAA;QACD,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAA;IAC3F,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAC5E,wBAAwB,CACzB,CAAA;QACD,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,yBAAyB,CAAC,CAAA;QAC/F,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAA;IAClG,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,CAAA;QAClC,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CACjF,sBAAsB,CACvB,CAAA;QACD,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CACjF,2BAA2B,CAC5B,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,CAAA;QAClC,MAAM,GAAG,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,CAAC,EAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAC,CAAC,CAAA;QAC5D,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAC1F,sBAAsB,CACvB,CAAA;QACD,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAC1F,2BAA2B,CAC5B,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,CAAA;QAClC,MAAM,MAAM,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,CAAC,EAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAC,CAAC,CAAA;QAC/D,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAC7F,qBAAqB,CACtB,CAAA;QACD,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAC7F,0BAA0B,CAC3B,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,CAAA;QAClC,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAC1E,uBAAuB,CACxB,CAAA;QACD,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CACjF,4BAA4B,CAC7B,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,CAAA;QAClC,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAA;QAC9F,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CACtE,4BAA4B,CAC7B,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"children.test.d.ts","sourceRoot":"","sources":["../../../test/children.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { Rule } from '../src';
|
|
2
|
-
const context = { client: {} };
|
|
3
|
-
describe('child rules', () => {
|
|
4
|
-
// --- ALL ---
|
|
5
|
-
test('all() rules - single failure', async () => {
|
|
6
|
-
const rule = Rule.string().all([
|
|
7
|
-
Rule.string()
|
|
8
|
-
.regex(/^[A-Z]/)
|
|
9
|
-
.error('Must start with an uppercase character'),
|
|
10
|
-
Rule.string()
|
|
11
|
-
.regex(/[a-z]+/)
|
|
12
|
-
.error('Must follow with lowercase characters'),
|
|
13
|
-
]);
|
|
14
|
-
await expect(rule.validate('Sanity', context)).resolves.toMatchSnapshot('all() rules - match');
|
|
15
|
-
await expect(rule.validate('moop', context)).resolves.toMatchSnapshot('all() rules - single failure, custom message');
|
|
16
|
-
});
|
|
17
|
-
test('all() rules - multiple failures', async () => {
|
|
18
|
-
const rule = Rule.string().all([
|
|
19
|
-
Rule.string()
|
|
20
|
-
.regex(/^[A-Z]/)
|
|
21
|
-
.error('Must start with an uppercase character'),
|
|
22
|
-
Rule.string().min(5).error('5 chars or more'),
|
|
23
|
-
Rule.string()
|
|
24
|
-
.regex(/[a-z]+/)
|
|
25
|
-
.error('Must follow with lowercase characters'),
|
|
26
|
-
]);
|
|
27
|
-
await expect(rule.validate('Sanity', context)).resolves.toMatchSnapshot('all() rules - match');
|
|
28
|
-
await expect(rule.validate('moop', context)).resolves.toMatchSnapshot('all() rules - multiple failures, custom messages');
|
|
29
|
-
});
|
|
30
|
-
test('all() rules - single failure, custom, common error', async () => {
|
|
31
|
-
const rule = Rule.string()
|
|
32
|
-
.all([Rule.string().regex(/^[A-Z]/), Rule.string().regex(/[a-z]+/)])
|
|
33
|
-
.error('Needs to start with a capital letter and then follow with lowercase characters');
|
|
34
|
-
await expect(rule.validate('moop', context)).resolves.toMatchSnapshot('all() rules - single failure, common error');
|
|
35
|
-
});
|
|
36
|
-
test('all() rules - single failure, custom, common error', async () => {
|
|
37
|
-
const rule = Rule.string()
|
|
38
|
-
.all([Rule.string().regex(/^[A-Z]/), Rule.string().min(5), Rule.string().regex(/[a-z]+/)])
|
|
39
|
-
.error('Needs to be a capital letter followed by at least 4 lowercase characters');
|
|
40
|
-
await expect(rule.validate('moop', context)).resolves.toMatchSnapshot('all() rules - multiple failures, common error');
|
|
41
|
-
});
|
|
42
|
-
// --- EITHER ---
|
|
43
|
-
test('either() rules - single failure', async () => {
|
|
44
|
-
const rule = Rule.string().either([
|
|
45
|
-
Rule.string()
|
|
46
|
-
.regex(/^rgb(\d+,\s*\d+,\s*\d+)$/)
|
|
47
|
-
.error('Must be rgb(num, num, num) format'),
|
|
48
|
-
Rule.string()
|
|
49
|
-
.regex(/^#([a-f0-9]{3}|[a-f0-9]{6})$/)
|
|
50
|
-
.error('Must be hex color with #-prefix'),
|
|
51
|
-
]);
|
|
52
|
-
await expect(rule.validate('rgb(16, 22, 133)', context)).resolves.toMatchSnapshot('either() rules - match');
|
|
53
|
-
await expect(rule.validate('#bf', context)).resolves.toMatchSnapshot('either() rules - single failure, custom message');
|
|
54
|
-
});
|
|
55
|
-
test('either() rules - all matches', async () => {
|
|
56
|
-
const rule = Rule.string().either([
|
|
57
|
-
Rule.string().regex(/^R/).error('Must start with a capital R'),
|
|
58
|
-
Rule.string().regex(/ed$/).error('Must end with "ed"'),
|
|
59
|
-
]);
|
|
60
|
-
await expect(rule.validate('Red', context)).resolves.toMatchSnapshot('either() rules - all match');
|
|
61
|
-
await expect(rule.validate('nope', context)).resolves.toMatchSnapshot('either() rules - no matches');
|
|
62
|
-
});
|
|
63
|
-
test('either() rules - all fail, custom, common error', async () => {
|
|
64
|
-
const rule = Rule.string()
|
|
65
|
-
.either([Rule.string().regex(/^[A-Z]/), Rule.string().regex(/^i[A-Z]/)])
|
|
66
|
-
.error("Needs to start with a capital letter, unless it's an iProduct");
|
|
67
|
-
await expect(rule.validate('mopatis!', context)).resolves.toMatchSnapshot('either() rules - all fail, common error');
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
//# sourceMappingURL=children.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"children.test.js","sourceRoot":"","sources":["../../../test/children.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createSchema.d.ts","sourceRoot":"","sources":["../../../test/createSchema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,MAAM,EAAC,MAAM,eAAe,CAAA;AAEpC,wBAAgB,YAAY,CAAC,SAAS,EAAE;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,GAAG,EAAE,CAAA;CAAC,GAAG,MAAM,CAsB7E"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import SchemaBuilder from '@sanity/schema';
|
|
2
|
-
import { validateSchema, groupProblems } from '@sanity/schema/_internal';
|
|
3
|
-
export function createSchema(schemaDef) {
|
|
4
|
-
const validated = validateSchema(schemaDef.types).getTypes();
|
|
5
|
-
const validation = groupProblems(validated);
|
|
6
|
-
const types = [...schemaDef.types];
|
|
7
|
-
// Add builtin types
|
|
8
|
-
types.push({ type: 'object', name: 'slug' });
|
|
9
|
-
// if (!types.find((t) => t.name === 'slug')) {
|
|
10
|
-
// types.push()
|
|
11
|
-
// }
|
|
12
|
-
const schema = SchemaBuilder.compile({
|
|
13
|
-
name: schemaDef.name || 'default',
|
|
14
|
-
types,
|
|
15
|
-
});
|
|
16
|
-
schema._validation = validation;
|
|
17
|
-
return schema;
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=createSchema.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createSchema.js","sourceRoot":"","sources":["../../../test/createSchema.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,0BAA0B,CAAA;AAGtE,MAAM,UAAU,YAAY,CAAC,SAAwC;IACnE,MAAM,SAAS,GAAG,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAA;IAC5D,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,CAAA;IAE3C,MAAM,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;IAElC,oBAAoB;IACpB,KAAK,CAAC,IAAI,CAAC,EAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAC,CAAC,CAAA;IAE1C,+CAA+C;IAC/C,iBAAiB;IACjB,IAAI;IAEJ,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC;QACnC,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,SAAS;QACjC,KAAK;KACN,CAAC,CAGD;IAAC,MAAc,CAAC,WAAW,GAAG,UAAU,CAAA;IAEzC,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generics.test.d.ts","sourceRoot":"","sources":["../../../test/generics.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { Rule } from '../src';
|
|
2
|
-
const context = { client: {} };
|
|
3
|
-
describe('generics', () => {
|
|
4
|
-
test('should be able to construct an empty rule', () => {
|
|
5
|
-
expect(() => new Rule()).not.toThrow(Error);
|
|
6
|
-
expect(new Rule()).toBeInstanceOf(Rule);
|
|
7
|
-
});
|
|
8
|
-
test('should be able to construct a new typed rule', () => {
|
|
9
|
-
expect(Rule.string()).toBeInstanceOf(Rule);
|
|
10
|
-
});
|
|
11
|
-
test('clones rule when changing generics', () => {
|
|
12
|
-
const baseRule = new Rule();
|
|
13
|
-
const typed = baseRule.type('string');
|
|
14
|
-
expect(baseRule).not.toBe(typed);
|
|
15
|
-
});
|
|
16
|
-
test('clones rule when changing type-specific rules', () => {
|
|
17
|
-
const baseRule = Rule.string();
|
|
18
|
-
const specific = baseRule.min(5);
|
|
19
|
-
expect(baseRule).not.toBe(specific);
|
|
20
|
-
});
|
|
21
|
-
test('returns arrays of errors/warnings by default', async () => {
|
|
22
|
-
await expect(Rule.string().validate(123, context)).resolves.toMatchSnapshot();
|
|
23
|
-
});
|
|
24
|
-
test('can demote errors to warnings', async () => {
|
|
25
|
-
const result = await Rule.string().warning().validate(123, context);
|
|
26
|
-
expect(result).toMatchSnapshot();
|
|
27
|
-
});
|
|
28
|
-
test('can customize error messages', async () => {
|
|
29
|
-
const result = await Rule.string().error('Dude it needs to be a string').validate(123, context);
|
|
30
|
-
expect(result).toMatchSnapshot();
|
|
31
|
-
});
|
|
32
|
-
test('can customize warning messages', async () => {
|
|
33
|
-
const result = await Rule.string()
|
|
34
|
-
.warning('Dude it should probably be a string')
|
|
35
|
-
.validate(123, context);
|
|
36
|
-
expect(result).toMatchSnapshot();
|
|
37
|
-
});
|
|
38
|
-
test('can customize info messages', async () => {
|
|
39
|
-
const result = await Rule.string()
|
|
40
|
-
.info('Dude it should probably be a string')
|
|
41
|
-
.validate(123, context);
|
|
42
|
-
expect(result).toMatchSnapshot();
|
|
43
|
-
});
|
|
44
|
-
test('can merge rules', async () => {
|
|
45
|
-
const rule = new Rule().required();
|
|
46
|
-
const stringRule = Rule.string().min(5);
|
|
47
|
-
const newRule = rule.merge(stringRule);
|
|
48
|
-
expect(rule).not.toBe(stringRule);
|
|
49
|
-
expect(newRule).not.toBe(stringRule);
|
|
50
|
-
expect(rule).not.toBe(newRule);
|
|
51
|
-
const result = await newRule.validate('Hei', context);
|
|
52
|
-
expect(result).toMatchSnapshot();
|
|
53
|
-
});
|
|
54
|
-
test('can merge rules', () => {
|
|
55
|
-
expect(new Rule().required().isRequired()).toBe(true);
|
|
56
|
-
expect(new Rule().isRequired()).toBe(false);
|
|
57
|
-
expect(new Rule().optional().isRequired()).toBe(false);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
//# sourceMappingURL=generics.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generics.test.js","sourceRoot":"","sources":["../../../test/generics.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"infer.test.d.ts","sourceRoot":"","sources":["../../../test/infer.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
import SchemaBuilder from '@sanity/schema';
|
|
2
|
-
import inferFromSchema from '../src/inferFromSchema';
|
|
3
|
-
import validateDocument from '../src/validateDocument';
|
|
4
|
-
import { createSchema } from './createSchema';
|
|
5
|
-
import { createMockSanityClient } from './mocks/mockSanityClient';
|
|
6
|
-
const client = createMockSanityClient();
|
|
7
|
-
const getClient = (options) => client;
|
|
8
|
-
describe('schema validation inference', () => {
|
|
9
|
-
describe('object with `options.list` and `value` field', () => {
|
|
10
|
-
const listOptions = [
|
|
11
|
-
{ value: '#f00', title: 'Red' },
|
|
12
|
-
{ value: '#0f0', title: 'Green' },
|
|
13
|
-
{ value: '#00f', title: 'Blue' },
|
|
14
|
-
];
|
|
15
|
-
const schema = SchemaBuilder.compile({
|
|
16
|
-
types: [
|
|
17
|
-
{
|
|
18
|
-
name: 'colorList',
|
|
19
|
-
type: 'object',
|
|
20
|
-
fields: [
|
|
21
|
-
{ name: 'value', type: 'string' },
|
|
22
|
-
{ name: 'title', type: 'string' },
|
|
23
|
-
],
|
|
24
|
-
options: {
|
|
25
|
-
list: listOptions,
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
});
|
|
30
|
-
test('allowed value', async () => {
|
|
31
|
-
const type = inferFromSchema(schema).get('colorList');
|
|
32
|
-
await expectNoError(type.validation, listOptions[0]);
|
|
33
|
-
});
|
|
34
|
-
test('disallowed value', async () => {
|
|
35
|
-
const type = inferFromSchema(schema).get('colorList');
|
|
36
|
-
await expectError(type.validation, { value: '#ccc', title: 'Gray' }, 'Value did not match any allowed value');
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
describe('field validations', () => {
|
|
40
|
-
const fieldValidationInferReproDoc = {
|
|
41
|
-
name: 'fieldValidationInferReproDoc',
|
|
42
|
-
type: 'document',
|
|
43
|
-
title: 'FieldValidationRepro',
|
|
44
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
45
|
-
validation: (Rule) => Rule.fields({
|
|
46
|
-
stringField: (fieldRule) => fieldRule.required(),
|
|
47
|
-
}),
|
|
48
|
-
fields: [
|
|
49
|
-
{
|
|
50
|
-
name: 'stringField',
|
|
51
|
-
type: 'string',
|
|
52
|
-
title: 'Field of someObjectType with validation',
|
|
53
|
-
description: 'First field should be required',
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
};
|
|
57
|
-
const schema = SchemaBuilder.compile({
|
|
58
|
-
types: [fieldValidationInferReproDoc],
|
|
59
|
-
});
|
|
60
|
-
test('field validations defined on an object type does not affect the field type validation', () => {
|
|
61
|
-
const documentType = inferFromSchema(schema).get('fieldValidationInferReproDoc');
|
|
62
|
-
const fieldWithoutValidation = documentType.fields.find((field) => field.name === 'stringField');
|
|
63
|
-
// The first field should only have the validation rules that comes with its type
|
|
64
|
-
expect((fieldWithoutValidation?.type.validation).flatMap(
|
|
65
|
-
// eslint-disable-next-line dot-notation
|
|
66
|
-
(validation) => validation['_rules'])).toEqual([{ flag: 'type', constraint: 'String' }]);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
describe('slug validation', () => {
|
|
70
|
-
const slugField = {
|
|
71
|
-
type: 'document',
|
|
72
|
-
name: 'documentWithSlug',
|
|
73
|
-
title: 'Document with Slug',
|
|
74
|
-
fields: [
|
|
75
|
-
{
|
|
76
|
-
name: 'slugField',
|
|
77
|
-
type: 'slug',
|
|
78
|
-
},
|
|
79
|
-
],
|
|
80
|
-
};
|
|
81
|
-
const schema = createSchema({
|
|
82
|
-
types: [slugField],
|
|
83
|
-
});
|
|
84
|
-
const mockDocument = {
|
|
85
|
-
_id: 'mockDocument',
|
|
86
|
-
_type: 'documentWithSlug',
|
|
87
|
-
slugField: { current: 'example-value' },
|
|
88
|
-
_createdAt: '2021-08-26T18:47:55.497Z',
|
|
89
|
-
_updatedAt: '2021-08-26T18:47:55.497Z',
|
|
90
|
-
_rev: 'example-rev',
|
|
91
|
-
};
|
|
92
|
-
afterEach(() => {
|
|
93
|
-
client.fetch.mockReset();
|
|
94
|
-
});
|
|
95
|
-
test('slug is valid if uniqueness queries returns true', async () => {
|
|
96
|
-
client.fetch.mockImplementation(() => Promise.resolve(
|
|
97
|
-
// return true to mock a unique result (valid)
|
|
98
|
-
true));
|
|
99
|
-
await expect(validateDocument(getClient, mockDocument, schema)).resolves.toEqual([]);
|
|
100
|
-
expect(client.fetch).toHaveBeenCalledTimes(1);
|
|
101
|
-
expect(client.fetch.mock.calls[0]).toEqual([
|
|
102
|
-
'!defined(*[_type == $docType && !(_id in [$draft, $published]) && slugField.current == $slug][0]._id)',
|
|
103
|
-
{
|
|
104
|
-
docType: 'documentWithSlug',
|
|
105
|
-
draft: 'drafts.mockDocument',
|
|
106
|
-
published: 'mockDocument',
|
|
107
|
-
slug: 'example-value',
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
tag: 'validation.slug-is-unique',
|
|
111
|
-
},
|
|
112
|
-
]);
|
|
113
|
-
});
|
|
114
|
-
test('slug is invalid if uniqueness queries returns false', async () => {
|
|
115
|
-
client.fetch.mockReset();
|
|
116
|
-
client.fetch.mockImplementation(() => Promise.resolve(
|
|
117
|
-
// return false to mock a non-unique result (invalid)
|
|
118
|
-
false));
|
|
119
|
-
await expect(validateDocument(getClient, mockDocument, schema)).resolves.toMatchObject([
|
|
120
|
-
{
|
|
121
|
-
path: ['slugField'],
|
|
122
|
-
level: 'error',
|
|
123
|
-
item: { message: 'Slug is already in use', paths: [] },
|
|
124
|
-
},
|
|
125
|
-
]);
|
|
126
|
-
expect(client.fetch).toHaveBeenCalledTimes(1);
|
|
127
|
-
expect(client.fetch.mock.calls[0]).toEqual([
|
|
128
|
-
'!defined(*[_type == $docType && !(_id in [$draft, $published]) && slugField.current == $slug][0]._id)',
|
|
129
|
-
{
|
|
130
|
-
docType: 'documentWithSlug',
|
|
131
|
-
draft: 'drafts.mockDocument',
|
|
132
|
-
published: 'mockDocument',
|
|
133
|
-
slug: 'example-value',
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
tag: 'validation.slug-is-unique',
|
|
137
|
-
},
|
|
138
|
-
]);
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
describe('reference validation', () => {
|
|
142
|
-
const documentWithReference = {
|
|
143
|
-
type: 'document',
|
|
144
|
-
name: 'documentWithReference',
|
|
145
|
-
title: 'Document with Reference',
|
|
146
|
-
fields: [
|
|
147
|
-
{
|
|
148
|
-
name: 'referenceField',
|
|
149
|
-
type: 'reference',
|
|
150
|
-
to: [{ type: 'documentWithReference' }],
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
name: 'referenceFieldWeak',
|
|
154
|
-
type: 'reference',
|
|
155
|
-
weak: true,
|
|
156
|
-
to: [{ type: 'documentWithReference' }],
|
|
157
|
-
},
|
|
158
|
-
],
|
|
159
|
-
};
|
|
160
|
-
const schema = createSchema({
|
|
161
|
-
types: [documentWithReference],
|
|
162
|
-
});
|
|
163
|
-
const mockDocument = {
|
|
164
|
-
_id: 'mockDocument',
|
|
165
|
-
_type: 'documentWithReference',
|
|
166
|
-
_createdAt: '2021-08-26T18:47:55.497Z',
|
|
167
|
-
_updatedAt: '2021-08-26T18:47:55.497Z',
|
|
168
|
-
_rev: 'example-rev',
|
|
169
|
-
};
|
|
170
|
-
afterEach(() => {
|
|
171
|
-
client.fetch.mockReset();
|
|
172
|
-
});
|
|
173
|
-
test('referenced document must exist (unless weak)', async () => {
|
|
174
|
-
const mockGetDocumentExists = jest.fn(() => Promise.resolve(false));
|
|
175
|
-
await expect(validateDocument(getClient, {
|
|
176
|
-
...mockDocument,
|
|
177
|
-
referenceField: {
|
|
178
|
-
_ref: 'example-id',
|
|
179
|
-
},
|
|
180
|
-
}, schema, { getDocumentExists: mockGetDocumentExists })).resolves.toMatchObject([
|
|
181
|
-
{
|
|
182
|
-
item: { message: /.+/ },
|
|
183
|
-
level: 'error',
|
|
184
|
-
path: ['referenceField'],
|
|
185
|
-
},
|
|
186
|
-
]);
|
|
187
|
-
expect(mockGetDocumentExists.mock.calls).toMatchObject([[{ id: 'example-id' }]]);
|
|
188
|
-
});
|
|
189
|
-
test('reference is valid if schema type is marked as weak', async () => {
|
|
190
|
-
await expect(validateDocument(getClient, {
|
|
191
|
-
...mockDocument,
|
|
192
|
-
referenceFieldWeak: { _ref: 'example-id' },
|
|
193
|
-
}, schema)).resolves.toEqual([]);
|
|
194
|
-
});
|
|
195
|
-
test('throws if `getDocumentExists` is not present', async () => {
|
|
196
|
-
const result = await validateDocument(getClient, {
|
|
197
|
-
...mockDocument,
|
|
198
|
-
referenceField: {
|
|
199
|
-
_ref: 'example-id',
|
|
200
|
-
},
|
|
201
|
-
}, schema, { getDocumentExists: undefined });
|
|
202
|
-
expect(result).toHaveLength(1);
|
|
203
|
-
expect(result[0].item.message.includes('`getDocumentExists` was not provided in validation context')).toBe(true);
|
|
204
|
-
});
|
|
205
|
-
test('reference is valid if schema type is strong and document does exists', async () => {
|
|
206
|
-
const mockGetDocumentExists = jest.fn(() => Promise.resolve(true));
|
|
207
|
-
await expect(validateDocument(getClient, {
|
|
208
|
-
...mockDocument,
|
|
209
|
-
referenceField: {
|
|
210
|
-
_ref: 'example-id',
|
|
211
|
-
},
|
|
212
|
-
}, schema, { getDocumentExists: mockGetDocumentExists })).resolves.toEqual([]);
|
|
213
|
-
expect(mockGetDocumentExists.mock.calls).toMatchObject([[{ id: 'example-id' }]]);
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
async function expectNoError(validations, value) {
|
|
218
|
-
const errors = (await Promise.all(validations.map((rule) => rule.validate(value, { client: client, getClient, schema: {} })))).flat();
|
|
219
|
-
if (errors.length === 0) {
|
|
220
|
-
// This shouldn't actually be needed, but counts against an assertion in jest-terms
|
|
221
|
-
expect(errors).toHaveLength(0);
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
const messages = errors.map((err) => err.item && err.item.message).join('\n\n- ');
|
|
225
|
-
throw new Error(`Expected no errors, but found ${errors.length}:\n- ${messages}`);
|
|
226
|
-
}
|
|
227
|
-
async function expectError(validations, value, message, level = 'error') {
|
|
228
|
-
const errors = (await Promise.all(validations.map((rule) => rule.validate(value, { client: client, getClient, schema: {} })))).flat();
|
|
229
|
-
if (!errors.length) {
|
|
230
|
-
throw new Error(`Expected error matching "${message}", but no errors were returned.`);
|
|
231
|
-
}
|
|
232
|
-
const matches = errors.filter((err) => err.item && err.item.message.includes(message));
|
|
233
|
-
if (matches.length === 0) {
|
|
234
|
-
const messages = errors.map((err) => err.item && err.item.message).join('\n\n- ');
|
|
235
|
-
throw new Error(`Expected error matching "${message}" not found. Errors found:\n- ${messages}`);
|
|
236
|
-
}
|
|
237
|
-
const levelMatch = matches.find((err) => err.level === level);
|
|
238
|
-
if (!levelMatch) {
|
|
239
|
-
throw new Error(`Expected error to have level "${level}", got ${matches[0].level}`);
|
|
240
|
-
}
|
|
241
|
-
// This shouldn't actually be needed, but counts against an assertion in jest-terms
|
|
242
|
-
expect(levelMatch.item.message).toMatch(message);
|
|
243
|
-
}
|
|
244
|
-
//# sourceMappingURL=infer.test.js.map
|