@sanity/validation 3.14.4 → 6.12.0-next.46

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 (40) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +29 -0
  3. package/lib/_internal.d.ts +93 -0
  4. package/lib/_internal.js +39 -0
  5. package/lib/_internal.js.map +1 -0
  6. package/lib/index.d.ts +2 -0
  7. package/lib/index.js +2 -1306
  8. package/lib/validateDocument-C77_Oewa.js +843 -0
  9. package/lib/validateDocument-C77_Oewa.js.map +1 -0
  10. package/lib/validateDocument-CBOsd748.d.ts +199 -0
  11. package/package.json +53 -45
  12. package/lib/dts/src/index.d.ts +0 -50
  13. package/lib/index.cjs.mjs +0 -9
  14. package/lib/index.esm.js +0 -1286
  15. package/lib/index.esm.js.map +0 -1
  16. package/lib/index.js.map +0 -1
  17. package/src/Rule.ts +0 -424
  18. package/src/ValidationError.ts +0 -32
  19. package/src/index.ts +0 -9
  20. package/src/inferFromSchema.ts +0 -19
  21. package/src/inferFromSchemaType.ts +0 -50
  22. package/src/util/convertToValidationMarker.ts +0 -84
  23. package/src/util/deepEquals.ts +0 -77
  24. package/src/util/escapeRegex.ts +0 -5
  25. package/src/util/normalizeValidationRules.test.ts +0 -170
  26. package/src/util/normalizeValidationRules.ts +0 -118
  27. package/src/util/pathToString.ts +0 -21
  28. package/src/util/requestIdleCallback.ts +0 -31
  29. package/src/util/typeString.test.ts +0 -27
  30. package/src/util/typeString.ts +0 -23
  31. package/src/validateDocument.test.ts +0 -703
  32. package/src/validateDocument.ts +0 -240
  33. package/src/validators/arrayValidator.ts +0 -100
  34. package/src/validators/booleanValidator.ts +0 -16
  35. package/src/validators/dateValidator.ts +0 -113
  36. package/src/validators/genericValidator.ts +0 -117
  37. package/src/validators/numberValidator.ts +0 -66
  38. package/src/validators/objectValidator.ts +0 -64
  39. package/src/validators/slugValidator.ts +0 -117
  40. package/src/validators/stringValidator.ts +0 -120
@@ -1,64 +0,0 @@
1
- import {Validators, isReference} from '@sanity/types'
2
- import genericValidator from './genericValidator'
3
-
4
- const metaKeys = ['_key', '_type', '_weak']
5
-
6
- const objectValidators: Validators = {
7
- ...genericValidator,
8
-
9
- presence: (expected, value, message) => {
10
- if (expected !== 'required') {
11
- return true
12
- }
13
-
14
- const keys = value && Object.keys(value).filter((key) => !metaKeys.includes(key))
15
-
16
- if (value === undefined || (keys && keys.length === 0)) {
17
- return message || 'Required'
18
- }
19
-
20
- return true
21
- },
22
-
23
- reference: async (_unused, value: unknown, message, context) => {
24
- if (!value) {
25
- return true
26
- }
27
-
28
- if (!isReference(value)) {
29
- return message || 'Must be a reference to a document'
30
- }
31
-
32
- const {type, getDocumentExists} = context
33
-
34
- if (!type) {
35
- throw new Error(`\`type\` was not provided in validation context`)
36
- }
37
-
38
- if ('weak' in type && type.weak) {
39
- return true
40
- }
41
-
42
- if (!getDocumentExists) {
43
- throw new Error(`\`getDocumentExists\` was not provided in validation context`)
44
- }
45
-
46
- const exists = await getDocumentExists({id: value._ref})
47
- if (!exists) {
48
- return 'This reference must be published'
49
- }
50
-
51
- return true
52
- },
53
-
54
- assetRequired: (flag, value, message) => {
55
- if (!value || !value.asset || !value.asset._ref) {
56
- const assetType = flag.assetType || 'Asset'
57
- return message || `${assetType} required`
58
- }
59
-
60
- return true
61
- },
62
- }
63
-
64
- export default objectValidators
@@ -1,117 +0,0 @@
1
- import {
2
- SlugIsUniqueValidator,
3
- Path,
4
- CustomValidator,
5
- isKeyedObject,
6
- SlugValidationContext,
7
- SlugParent,
8
- SlugSchemaType,
9
- } from '@sanity/types'
10
- import {memoize} from 'lodash'
11
- // import getClient from '../getClient'
12
-
13
- const memoizedWarnOnArraySlug = memoize(warnOnArraySlug)
14
-
15
- function getDocumentIds(id: string) {
16
- const isDraft = id.indexOf('drafts.') === 0
17
- return {
18
- published: isDraft ? id.slice('drafts.'.length) : id,
19
- draft: isDraft ? id : `drafts.${id}`,
20
- }
21
- }
22
-
23
- function serializePath(path: Path): string {
24
- return path.reduce<string>((target, part, i) => {
25
- const isIndex = typeof part === 'number'
26
- const isKey = isKeyedObject(part)
27
- const separator = i === 0 ? '' : '.'
28
- const add = isIndex || isKey ? '[]' : `${separator}${part}`
29
- return `${target}${add}`
30
- }, '')
31
- }
32
-
33
- const defaultIsUnique: SlugIsUniqueValidator = (slug, context) => {
34
- const {getClient, document, path, type} = context
35
- const schemaOptions = type?.options as {disableArrayWarning?: boolean} | undefined
36
-
37
- if (!document) {
38
- throw new Error(`\`document\` was not provided in validation context.`)
39
- }
40
- if (!path) {
41
- throw new Error(`\`path\` was not provided in validation context.`)
42
- }
43
-
44
- const disableArrayWarning = schemaOptions?.disableArrayWarning || false
45
- const {published, draft} = getDocumentIds(document._id)
46
- const docType = document._type
47
- const atPath = serializePath(path.concat('current'))
48
-
49
- if (!disableArrayWarning && atPath.includes('[]')) {
50
- memoizedWarnOnArraySlug(serializePath(path))
51
- }
52
-
53
- const constraints = [
54
- '_type == $docType',
55
- `!(_id in [$draft, $published])`,
56
- `${atPath} == $slug`,
57
- ].join(' && ')
58
-
59
- return getClient({apiVersion: '2022-09-09'}).fetch<boolean>(
60
- `!defined(*[${constraints}][0]._id)`,
61
- {
62
- docType,
63
- draft,
64
- published,
65
- slug,
66
- },
67
- {tag: 'validation.slug-is-unique'}
68
- )
69
- }
70
-
71
- function warnOnArraySlug(serializedPath: string) {
72
- /* eslint-disable no-console */
73
- console.warn(
74
- [
75
- `Slug field at path ${serializedPath} is within an array and cannot be automatically checked for uniqueness`,
76
- `If you need to check for uniqueness, provide your own "isUnique" method`,
77
- `To disable this message, set \`disableArrayWarning: true\` on the slug \`options\` field`,
78
- ].join('\n')
79
- )
80
- /* eslint-enable no-console */
81
- }
82
-
83
- /**
84
- * Validates slugs values by querying for uniqueness from the client.
85
- *
86
- * This is a custom rule implementation (e.g. `Rule.custom(slugValidator)`)
87
- * that's populated in `inferFromSchemaType` when the type name is `slug`
88
- */
89
- export const slugValidator: CustomValidator = async (value, context) => {
90
- if (!value) {
91
- return true
92
- }
93
- if (typeof value !== 'object') {
94
- return 'Slug must be an object'
95
- }
96
-
97
- const slugValue = (value as {current?: string}).current
98
- if (!slugValue) {
99
- return 'Slug must have a value'
100
- }
101
-
102
- const options = context?.type?.options as {isUnique?: SlugIsUniqueValidator} | undefined
103
- const isUnique = options?.isUnique || defaultIsUnique
104
-
105
- const slugContext: SlugValidationContext = {
106
- ...context,
107
- parent: context.parent as SlugParent,
108
- type: context.type as SlugSchemaType,
109
- defaultIsUnique,
110
- }
111
- const wasUnique = await isUnique(slugValue, slugContext)
112
- if (wasUnique) {
113
- return true
114
- }
115
-
116
- return 'Slug is already in use'
117
- }
@@ -1,120 +0,0 @@
1
- import {Validators} from '@sanity/types'
2
- import genericValidator from './genericValidator'
3
-
4
- const DUMMY_ORIGIN = 'http://sanity'
5
- const emailRegex =
6
- /^(([^<>()[\]\\.,;:\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,}))$/
7
- const isRelativeUrl = (url: string) => /^\.*\//.test(url)
8
-
9
- const stringValidators: Validators = {
10
- ...genericValidator,
11
-
12
- min: (minLength, value, message) => {
13
- if (!value || value.length >= minLength) {
14
- return true
15
- }
16
-
17
- return message || `Must be at least ${minLength} characters long`
18
- },
19
-
20
- max: (maxLength, value, message) => {
21
- if (!value || value.length <= maxLength) {
22
- return true
23
- }
24
-
25
- return message || `Must be at most ${maxLength} characters long`
26
- },
27
-
28
- length: (wantedLength, value, message) => {
29
- const strValue = value || ''
30
- if (strValue.length === wantedLength) {
31
- return true
32
- }
33
-
34
- return message || `Must be exactly ${wantedLength} characters long`
35
- },
36
-
37
- uri: (constraints, value, message) => {
38
- const strValue = value || ''
39
- const {options} = constraints
40
- const {allowCredentials, relativeOnly} = options
41
- const allowRelative = options.allowRelative || relativeOnly
42
-
43
- let url
44
- try {
45
- // WARNING: Safari checks for a given `base` param by looking at the length of arguments passed
46
- // to new URL(str, base), and will fail if invoked with new URL(strValue, undefined)
47
- url = allowRelative ? new URL(strValue, DUMMY_ORIGIN) : new URL(strValue)
48
- } catch (err) {
49
- return message || 'Not a valid URL'
50
- }
51
-
52
- if (relativeOnly && url.origin !== DUMMY_ORIGIN) {
53
- return message || 'Only relative URLs are allowed'
54
- }
55
-
56
- if (!allowRelative && url.origin === DUMMY_ORIGIN && isRelativeUrl(strValue)) {
57
- return message || 'Relative URLs are not allowed'
58
- }
59
-
60
- if (!allowCredentials && (url.username || url.password)) {
61
- return message || `Username/password not allowed`
62
- }
63
-
64
- const urlScheme = url.protocol.replace(/:$/, '')
65
- const matchesAllowedScheme = options.scheme.some((scheme) => scheme.test(urlScheme))
66
- if (!matchesAllowedScheme) {
67
- return message || 'Does not match allowed protocols/schemes'
68
- }
69
-
70
- return true
71
- },
72
-
73
- stringCasing: (casing, value, message) => {
74
- const strValue = value || ''
75
- if (casing === 'uppercase' && strValue !== strValue.toLocaleUpperCase()) {
76
- return message || `Must be all uppercase letters`
77
- }
78
-
79
- if (casing === 'lowercase' && strValue !== strValue.toLocaleLowerCase()) {
80
- return message || `Must be all lowercase letters`
81
- }
82
-
83
- return true
84
- },
85
-
86
- presence: (flag, value, message) => {
87
- if (flag === 'required' && !value) {
88
- return message || 'Required'
89
- }
90
-
91
- return true
92
- },
93
-
94
- regex: (options, value, message) => {
95
- const {pattern, name, invert} = options
96
- const regName = name || `"${pattern.toString()}"`
97
- const strValue = value || ''
98
- const matches = pattern.test(strValue)
99
- if ((!invert && !matches) || (invert && matches)) {
100
- const defaultMessage = invert
101
- ? `Should not match ${regName}-pattern`
102
- : `Does not match ${regName}-pattern`
103
-
104
- return message || defaultMessage
105
- }
106
-
107
- return true
108
- },
109
-
110
- email: (_unused, value, message) => {
111
- const strValue = `${value || ''}`.trim()
112
- if (!strValue || emailRegex.test(strValue)) {
113
- return true
114
- }
115
-
116
- return message || 'Must be a valid email address'
117
- },
118
- }
119
-
120
- export default stringValidators