sanity-advanced-validators 0.2.0 → 0.2.1
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/README.md +63 -66
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ Note that every validator can accept an optional custom error message as its las
|
|
|
18
18
|
|
|
19
19
|
## Mega-example
|
|
20
20
|
|
|
21
|
-
Imagine that you’ve got a document that has an optional video file — but it's required on the `/about` page. If the video exists, it must either MP4 or MOV, and have a poster image that's between 1250x800 and 2500x1600 in size.
|
|
21
|
+
Imagine that you’ve got a document that has an optional video file — but it's required on the `/about` page. If the video exists, it must be either MP4 or MOV, and have a poster image that's between 1250x800 and 2500x1600 pixels in size.
|
|
22
22
|
|
|
23
23
|
```typescript
|
|
24
24
|
const Page = defineType({
|
|
@@ -84,17 +84,14 @@ Enforces that an uploaded image asset is at minimum certain dimensions.
|
|
|
84
84
|
import { minDimensions } from "sanity-advanced-validation"
|
|
85
85
|
|
|
86
86
|
const ImageWithCaption = defineType({
|
|
87
|
-
name: "
|
|
87
|
+
name: "article",
|
|
88
88
|
type: "object",
|
|
89
89
|
fields: [
|
|
90
|
+
// …
|
|
90
91
|
defineField({
|
|
91
|
-
name: "
|
|
92
|
-
type: "string",
|
|
93
|
-
}),
|
|
94
|
-
defineField({
|
|
95
|
-
name: "image",
|
|
92
|
+
name: "heroImage",
|
|
96
93
|
type: "image",
|
|
97
|
-
validation: (rule) => rule.custom(minDimensions({ x:
|
|
94
|
+
validation: (rule) => rule.custom(minDimensions({ x: 1200, y: 800 })),
|
|
98
95
|
}),
|
|
99
96
|
],
|
|
100
97
|
})
|
|
@@ -104,12 +101,12 @@ You can also enforce on only one dimension, or feed a custom error message:
|
|
|
104
101
|
|
|
105
102
|
```typescript
|
|
106
103
|
defineField({
|
|
107
|
-
name: "
|
|
104
|
+
name: "heroImage",
|
|
108
105
|
type: "image",
|
|
109
|
-
description: "At least
|
|
106
|
+
description: "At least 1200px wide; as tall as you like.",
|
|
110
107
|
validation: (rule) => rule.custom(
|
|
111
108
|
minDimensions(
|
|
112
|
-
{ x:
|
|
109
|
+
{ x: 1200 },
|
|
113
110
|
"Uh oh, your image is {width} pixels wide. That’s less than {x}!"
|
|
114
111
|
)
|
|
115
112
|
),
|
|
@@ -121,37 +118,25 @@ defineField({
|
|
|
121
118
|
Enforces that an uploaded image asset is at most certain dimensions.
|
|
122
119
|
|
|
123
120
|
```typescript
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
fields: [
|
|
130
|
-
defineField({
|
|
131
|
-
name: "caption",
|
|
132
|
-
type: "string",
|
|
133
|
-
}),
|
|
134
|
-
defineField({
|
|
135
|
-
name: "image",
|
|
136
|
-
type: "image",
|
|
137
|
-
validation: (rule) => rule.custom(maxDimensions({ x: 2000, y: 2000 })),
|
|
138
|
-
}),
|
|
139
|
-
],
|
|
140
|
-
})
|
|
121
|
+
defineField({
|
|
122
|
+
name: "heroImage",
|
|
123
|
+
type: "image",
|
|
124
|
+
validation: (rule) => rule.custom(maxDimensions({ x: 2400, y: 1600 })),
|
|
125
|
+
}),
|
|
141
126
|
```
|
|
142
127
|
|
|
143
128
|
Chain for min and max dimensions:
|
|
144
129
|
|
|
145
130
|
```typescript
|
|
146
131
|
defineField({
|
|
147
|
-
name: "
|
|
132
|
+
name: "heroImage",
|
|
148
133
|
type: "image",
|
|
149
|
-
description: "Min:
|
|
134
|
+
description: "Min: 1200x800, max: 2400x1600.",
|
|
150
135
|
validation: (rule) =>
|
|
151
136
|
rule
|
|
152
137
|
.required()
|
|
153
|
-
.custom(minDimensions({ x:
|
|
154
|
-
.custom(maxDimensions({ x:
|
|
138
|
+
.custom(minDimensions({ x: 1200, y: 800 }))
|
|
139
|
+
.custom(maxDimensions({ x: 2400, y: 1600 })),
|
|
155
140
|
})
|
|
156
141
|
```
|
|
157
142
|
|
|
@@ -159,6 +144,8 @@ defineField({
|
|
|
159
144
|
|
|
160
145
|
For a given object that has multiple fields, mark a field as `required` if a sibling has a particular value.
|
|
161
146
|
|
|
147
|
+
This is really handy if you have a field that is hidden circumstances, but need to make it `required()` when it’s visible! This is probably the validator I use most.
|
|
148
|
+
|
|
162
149
|
_note:_ This does not work for slugs, because they have to match a nested `.current` value. Use the [requiredIfSlugEq validator](#requiredIfSlugEq) instead.
|
|
163
150
|
|
|
164
151
|
```typescript
|
|
@@ -186,9 +173,9 @@ defineType({
|
|
|
186
173
|
list: [
|
|
187
174
|
'javascript', 'rust', 'python', 'swift'
|
|
188
175
|
]
|
|
189
|
-
}
|
|
176
|
+
},
|
|
177
|
+
validation: rule => rule.custom(requiredIfSiblingEq('occupation', 'software engineer')),
|
|
190
178
|
hidden: ({parent}) => parent.occuption !== 'software engineer',
|
|
191
|
-
validation: rule => rule.custom(requiredIfSiblingEq('occupation', 'software engineer'))
|
|
192
179
|
}),
|
|
193
180
|
],
|
|
194
181
|
})
|
|
@@ -215,7 +202,7 @@ defineType({
|
|
|
215
202
|
validation: rule => rule.custom(requiredIfSiblingEq(
|
|
216
203
|
'email',
|
|
217
204
|
null,
|
|
218
|
-
"If you don’t have an email address,
|
|
205
|
+
"If you don’t have an email address, a phone number is required."
|
|
219
206
|
))
|
|
220
207
|
})
|
|
221
208
|
],
|
|
@@ -233,29 +220,23 @@ defineType({
|
|
|
233
220
|
name: 'name',
|
|
234
221
|
type: 'string'
|
|
235
222
|
}),
|
|
236
|
-
|
|
237
|
-
name: '
|
|
238
|
-
type: '
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
description: 'Why are you wasting your life this way?',
|
|
254
|
-
type: 'text',
|
|
255
|
-
hidden: ({parent}) => parent.occuption === 'software engineer',
|
|
256
|
-
validation: rule => rule.custom(requiredIfSiblingEq('occupation', ['doctor', 'lawyer']))
|
|
257
|
-
})
|
|
258
|
-
],
|
|
223
|
+
defineField({
|
|
224
|
+
name: 'name',
|
|
225
|
+
type: 'string'
|
|
226
|
+
}),
|
|
227
|
+
defineField({
|
|
228
|
+
name: 'occupation',
|
|
229
|
+
type: 'string',
|
|
230
|
+
options: {
|
|
231
|
+
list: ['doctor', 'lawyer', 'software engineer']
|
|
232
|
+
}
|
|
233
|
+
}),
|
|
234
|
+
defineField({
|
|
235
|
+
name: 'explanation',
|
|
236
|
+
description: 'Why are you wasting your life this way?',
|
|
237
|
+
type: 'text',
|
|
238
|
+
validation: rule => rule.custom(requiredIfSiblingEq('occupation', ['doctor', 'lawyer'])),
|
|
239
|
+
hidden: ({parent}) => parent.occuption === 'software engineer',
|
|
259
240
|
})
|
|
260
241
|
],
|
|
261
242
|
})
|
|
@@ -287,9 +268,8 @@ defineType({
|
|
|
287
268
|
})
|
|
288
269
|
defineField({
|
|
289
270
|
name: 'why',
|
|
290
|
-
description: '
|
|
291
|
-
type: '
|
|
292
|
-
hidden: ({parent}) => parent.occuption === 'software engineer',
|
|
271
|
+
description: 'How many years will you spend paying off your degree?',
|
|
272
|
+
type: 'number',
|
|
293
273
|
validation: rule => rule.custom(requiredIfSiblingNeq('occupation', 'software engineer'))
|
|
294
274
|
}),
|
|
295
275
|
],
|
|
@@ -317,7 +297,7 @@ defineType({
|
|
|
317
297
|
of: [
|
|
318
298
|
{type: 'qaItem'}
|
|
319
299
|
],
|
|
320
|
-
validation: rule => rule.custom(requiredIfSlugEq('faq'))
|
|
300
|
+
validation: rule => rule.custom(requiredIfSlugEq('faq')),
|
|
321
301
|
hidden: ({parent}) => parent.slug.current !== 'faq'
|
|
322
302
|
})
|
|
323
303
|
]
|
|
@@ -350,12 +330,12 @@ defineType({
|
|
|
350
330
|
}),
|
|
351
331
|
defineField({
|
|
352
332
|
name: 'subnav',
|
|
353
|
-
description:
|
|
333
|
+
description: `Subnav is required on documents that aren’t '/home'`,
|
|
354
334
|
type: 'array',
|
|
355
335
|
of: [
|
|
356
336
|
{type: 'navLink'}
|
|
357
337
|
],
|
|
358
|
-
validation: rule => rule.custom(requiredIfSlugNeq('home'))
|
|
338
|
+
validation: rule => rule.custom(requiredIfSlugNeq('home')),
|
|
359
339
|
hidden: ({parent}) => parent.slug.current !== 'home'
|
|
360
340
|
})
|
|
361
341
|
]
|
|
@@ -364,7 +344,7 @@ defineType({
|
|
|
364
344
|
|
|
365
345
|
### referencedDocumentRequires
|
|
366
346
|
|
|
367
|
-
You might want to enforce some validation on a
|
|
347
|
+
You might want to enforce some validation on a referenced document. This validator enforces that a given value is not null in the referenced document.
|
|
368
348
|
|
|
369
349
|
```typescript
|
|
370
350
|
defineField({
|
|
@@ -448,7 +428,7 @@ const navLink = defineType({
|
|
|
448
428
|
|
|
449
429
|
This will enforce that a subnav list can embed in a subnav, which can also be embedded in a subnav — but no further.
|
|
450
430
|
|
|
451
|
-
_Note to any Sanity dev who looks at this_: I’d love to include similar logic on my `hidden:` attribute, but I don’t think that’t possible without a `path` array in
|
|
431
|
+
_Note to any Sanity dev who looks at this_: I’d love to include similar logic on my `hidden:` attribute, but I don’t think that’t possible without a `path` array in `hidden`’s `ConditionalPropertyCallbackContext` that’s similar to the one fed to the `ValidationContext` (todo: type this correctly). Wouldn’t this be cool?
|
|
452
432
|
|
|
453
433
|
```typescript
|
|
454
434
|
defineField({
|
|
@@ -469,12 +449,29 @@ Most of these validators rely on a function called `getSibling()`. If you’re t
|
|
|
469
449
|
|
|
470
450
|
## Upcoming
|
|
471
451
|
|
|
452
|
+
### Nested pathfinders
|
|
453
|
+
|
|
472
454
|
Since building these validator, I took to putting my slugs in a metadata object. I need to update `requiredIfSlugEq` to accept a path, like `requiredIfSlugEq('metadata.slug', 'some-values')`.
|
|
473
455
|
|
|
474
456
|
This pathfinding should be added to any validator that takes a sibling, like `requiredIfSiblingEq`. It can probably be snapped into `getSibling`.
|
|
475
457
|
|
|
476
458
|
While I’m at it, there’s a possibility that `getSibling` could detect the target type. If that type is `slug`, then it could add `current` to the path, and then I can deprecate `requiredIfSlugEq` altogether.
|
|
477
459
|
|
|
460
|
+
### Image and File checks
|
|
461
|
+
|
|
462
|
+
`minDimensions`, `maxDimensions`, and `fileExtension` should check to see if the field is of type `image` or `file`.
|
|
463
|
+
|
|
464
|
+
Some of the other checks should probably make sure the field is _not_ `image` or `file`.
|
|
465
|
+
|
|
466
|
+
### new referencedDocumentFieldEq validator
|
|
467
|
+
|
|
468
|
+
```
|
|
469
|
+
// only articles by Jimmy Olsen
|
|
470
|
+
rule => rule.custom(referencedDocumentFieldEq('article', 'author', 'Jimmy Olsen'))
|
|
471
|
+
// only articles whose authors are not null. replaces `referencedDocumentRequires`.
|
|
472
|
+
rule => rule.custom(referencedDocumentFieldNeq('article', 'author', null))
|
|
473
|
+
```
|
|
474
|
+
|
|
478
475
|
## MOAR
|
|
479
476
|
|
|
480
477
|
Do you have any ideas or edge cases that these validators don’t cover? Leave an issue, maybe I can hack it out.
|