sanity-advanced-validators 0.4.0 → 0.4.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 +44 -48
- package/dist/index.cjs +26 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +25 -15
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -160,7 +160,7 @@ _note:_ This does not work for slugs, because they have to match a nested `.curr
|
|
|
160
160
|
|
|
161
161
|
```typescript
|
|
162
162
|
key: string, // name of sibling
|
|
163
|
-
operand: string | number | null | Array<string, number
|
|
163
|
+
operand: string | number | boolean | null | Array<string, number> // value that you’re testing for (i.e. if 'name' === operand)
|
|
164
164
|
message?: string // optional custom error message; replaces {key} and {operand} with your input, and {siblingValue} with the value of the sibling you’re testing against.
|
|
165
165
|
```
|
|
166
166
|
|
|
@@ -187,7 +187,7 @@ defineType({
|
|
|
187
187
|
type: 'string',
|
|
188
188
|
options: {
|
|
189
189
|
list: [
|
|
190
|
-
'
|
|
190
|
+
'typescript', 'rust', 'python', 'swift'
|
|
191
191
|
]
|
|
192
192
|
},
|
|
193
193
|
validation: rule => rule.custom(requiredIfSiblingEq('occupation', 'software engineer')),
|
|
@@ -197,7 +197,35 @@ defineType({
|
|
|
197
197
|
})
|
|
198
198
|
```
|
|
199
199
|
|
|
200
|
-
|
|
200
|
+
And it also works for arrays.
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
defineType({
|
|
204
|
+
name: "person",
|
|
205
|
+
type: "object",
|
|
206
|
+
fields: [
|
|
207
|
+
// ...
|
|
208
|
+
defineField({
|
|
209
|
+
name: "occupation",
|
|
210
|
+
type: "string",
|
|
211
|
+
options: {
|
|
212
|
+
list: ["doctor", "lawyer", "software engineer", "linguist"],
|
|
213
|
+
},
|
|
214
|
+
}),
|
|
215
|
+
defineField({
|
|
216
|
+
name: "favoriteLanguage",
|
|
217
|
+
type: "string",
|
|
218
|
+
options: {
|
|
219
|
+
list: ["typescript", "rust", "python", "swift", "latin", "urdu", "klingon"],
|
|
220
|
+
},
|
|
221
|
+
validation: (rule) => rule.custom(requiredIfSiblingEq("occupation", ["software engineer", "linguist"])),
|
|
222
|
+
hidden: ({ parent }) => !["software engineer", "linguist"].includes(parent.occupation),
|
|
223
|
+
}),
|
|
224
|
+
],
|
|
225
|
+
})
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
“If not that, then this.” It even works for null.
|
|
201
229
|
|
|
202
230
|
```typescript
|
|
203
231
|
defineType({
|
|
@@ -225,50 +253,17 @@ defineType({
|
|
|
225
253
|
})
|
|
226
254
|
```
|
|
227
255
|
|
|
228
|
-
And it even works for arrays.
|
|
229
|
-
|
|
230
|
-
```typescript
|
|
231
|
-
defineType({
|
|
232
|
-
name: "person",
|
|
233
|
-
type: "object",
|
|
234
|
-
fields: [
|
|
235
|
-
defineField({
|
|
236
|
-
name: "name",
|
|
237
|
-
type: "string",
|
|
238
|
-
}),
|
|
239
|
-
defineField({
|
|
240
|
-
name: "name",
|
|
241
|
-
type: "string",
|
|
242
|
-
}),
|
|
243
|
-
defineField({
|
|
244
|
-
name: "occupation",
|
|
245
|
-
type: "string",
|
|
246
|
-
options: {
|
|
247
|
-
list: ["doctor", "lawyer", "software engineer"],
|
|
248
|
-
},
|
|
249
|
-
}),
|
|
250
|
-
defineField({
|
|
251
|
-
name: "explanation",
|
|
252
|
-
description: "Why are you wasting your life this way?",
|
|
253
|
-
type: "text",
|
|
254
|
-
validation: (rule) => rule.custom(requiredIfSiblingEq("occupation", ["doctor", "lawyer"])),
|
|
255
|
-
hidden: ({ parent }) => parent.occuption === "software engineer",
|
|
256
|
-
}),
|
|
257
|
-
],
|
|
258
|
-
})
|
|
259
|
-
```
|
|
260
|
-
|
|
261
256
|
---
|
|
262
257
|
|
|
263
258
|
### requiredIfSiblingNeq
|
|
264
259
|
|
|
265
|
-
For a given object that has multiple fields, mark a field as `required` if a sibling does _not_ have a particular value.
|
|
260
|
+
For a given object that has multiple fields, mark a field as `required` if a sibling does _not_ have a particular value (or member of an array of values).
|
|
266
261
|
|
|
267
262
|
_note:_ This does not work for slugs, because they have to match a nested `.current` value. Use the [requiredIfSlugNeq validator](#requiredIfSlugNeq) instead.
|
|
268
263
|
|
|
269
264
|
```typescript
|
|
270
265
|
key: string, // name of sibling
|
|
271
|
-
operand: string | number | null | Array<string, number
|
|
266
|
+
operand: string | number | boolean | null | Array<string, number> // value that you’re testing for (i.e. if 'name' === operand)
|
|
272
267
|
message?: string // optional custom error message; replaces {key} and {operand} with your input, and {siblingValue} with the value of the sibling you’re testing against.
|
|
273
268
|
```
|
|
274
269
|
|
|
@@ -291,12 +286,12 @@ defineType({
|
|
|
291
286
|
}
|
|
292
287
|
})
|
|
293
288
|
defineField({
|
|
294
|
-
name:
|
|
295
|
-
description:
|
|
296
|
-
type:
|
|
297
|
-
validation: rule => rule.custom(requiredIfSiblingNeq(
|
|
298
|
-
|
|
299
|
-
],
|
|
289
|
+
name: "explanation",
|
|
290
|
+
description: "Why are you wasting your life this way?",
|
|
291
|
+
type: "text",
|
|
292
|
+
validation: (rule) => rule.custom(requiredIfSiblingNeq("occupation", "software engineer")),
|
|
293
|
+
hidden: ({ parent }) => parent.occuption === "software engineer",
|
|
294
|
+
}), ],
|
|
300
295
|
})
|
|
301
296
|
```
|
|
302
297
|
|
|
@@ -307,7 +302,7 @@ defineType({
|
|
|
307
302
|
Mark a field as `required` for documents with matching slugs.
|
|
308
303
|
|
|
309
304
|
```typescript
|
|
310
|
-
operand: string | number | null | Array<string, number
|
|
305
|
+
operand: string | number | null | Array<string, number> // possible slug or slugs you’re testing
|
|
311
306
|
key?: string, // name of sibling if not "slug"
|
|
312
307
|
message?: string // optional custom error message; replaces {slugKey} and {operand} with your input, and {siblingSlugValue} with the value of the sibling you’re testing against.
|
|
313
308
|
```
|
|
@@ -350,7 +345,7 @@ defineField({
|
|
|
350
345
|
Require fields on pages that don't match one or more slugs.
|
|
351
346
|
|
|
352
347
|
```typescript
|
|
353
|
-
operand: string | number | null | Array<string, number
|
|
348
|
+
operand: string | number | null | Array<string, number> // possible slug or slugs you’re testing
|
|
354
349
|
key?: string, // name of sibling if not "slug"
|
|
355
350
|
message?: string // optional custom error message; replaces {slugKey} and {operand} with your input, and {siblingSlugValue} with the value of the sibling you’re testing against.
|
|
356
351
|
```
|
|
@@ -397,7 +392,7 @@ defineField({
|
|
|
397
392
|
type: 'string',
|
|
398
393
|
validation: (rule) => rule.custom(
|
|
399
394
|
regex(
|
|
400
|
-
/^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})*$/,
|
|
395
|
+
/^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})*$/,
|
|
401
396
|
"“{value}” is not a valid email address."
|
|
402
397
|
)
|
|
403
398
|
),
|
|
@@ -405,6 +400,7 @@ defineField({
|
|
|
405
400
|
```
|
|
406
401
|
|
|
407
402
|
**Custom error messages are highly recommended here.** Without the custom message above, the default response would be:
|
|
403
|
+
|
|
408
404
|
```
|
|
409
405
|
“me@googlecom” does not match the pattern /^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})*$/.
|
|
410
406
|
```
|
|
@@ -536,7 +532,7 @@ defineField({
|
|
|
536
532
|
|
|
537
533
|
Most of these validators rely on a function called `getSibling()`. If you’re thinking about picking this apart and writing your own custom validator, take a close look at how these validators use it.
|
|
538
534
|
|
|
539
|
-
##
|
|
535
|
+
## Roadmap
|
|
540
536
|
|
|
541
537
|
### Nested pathfinders
|
|
542
538
|
|
package/dist/index.cjs
CHANGED
|
@@ -25,6 +25,7 @@ __export(index_exports, {
|
|
|
25
25
|
maxDepth: () => maxDepth,
|
|
26
26
|
minDimensions: () => minDimensions,
|
|
27
27
|
referencedDocumentRequires: () => referencedDocumentRequires,
|
|
28
|
+
regex: () => regex,
|
|
28
29
|
requiredIfSiblingEq: () => requiredIfSiblingEq,
|
|
29
30
|
requiredIfSlugEq: () => requiredIfSlugEq
|
|
30
31
|
});
|
|
@@ -69,20 +70,20 @@ var minDimensions = ({ x, y }, message) => (value) => {
|
|
|
69
70
|
}
|
|
70
71
|
const { width, height } = (0, import_asset_utils2.getImageDimensions)(value.asset._ref);
|
|
71
72
|
if (!!x && width < x) {
|
|
72
|
-
return message ? message.replace("{x}", x.toString()).replace("{y}", !y ? "(any)" : y.toString()) : `Image must be at least ${x} pixels wide.`;
|
|
73
|
+
return message ? message.replace("{width}", width.toString()).replace("{height}", height.toString()).replace("{x}", x.toString()).replace("{y}", !y ? "(any)" : y.toString()) : `Image must be at least ${x} pixels wide.`;
|
|
73
74
|
}
|
|
74
75
|
if (!!y && height < y) {
|
|
75
|
-
return message ? message.replace("{x}", !x ? "(any)" : x.toString()).replace("{y}", y.toString()) : `Image must be at least ${y} pixels tall.`;
|
|
76
|
+
return message ? message.replace("{width}", width.toString()).replace("{height}", height.toString()).replace("{x}", !x ? "(any)" : x.toString()).replace("{y}", y.toString()) : `Image must be at least ${y} pixels tall.`;
|
|
76
77
|
}
|
|
77
78
|
return true;
|
|
78
79
|
};
|
|
79
80
|
|
|
80
81
|
// src/maxDepth.ts
|
|
81
|
-
var maxDepth = (maxDepth2,
|
|
82
|
-
let
|
|
83
|
-
const paths = context.path.filter((e) => typeof e === "string" && e.match(
|
|
82
|
+
var maxDepth = (maxDepth2, key, message = `Error: You can only nest {key} {maxDepth} levels deep.`) => (_, context) => {
|
|
83
|
+
let regex2 = new RegExp(String.raw`topLevelItems|${key}`);
|
|
84
|
+
const paths = context.path.filter((e) => typeof e === "string" && e.match(regex2));
|
|
84
85
|
if (paths.length > maxDepth2) {
|
|
85
|
-
return message.replace("{nestedValueName}",
|
|
86
|
+
return message.replace("{key}", key).replace("{nestedValueName}", key).replace("{maxDepth}", maxDepth2.toString());
|
|
86
87
|
}
|
|
87
88
|
return true;
|
|
88
89
|
};
|
|
@@ -91,20 +92,20 @@ var maxDepth = (maxDepth2, nestedValueName, message = `Error: You can only nest
|
|
|
91
92
|
var requiredIfSlugEq = (slug, slugKey = "slug", message = `This is a required field.`) => (value, context) => {
|
|
92
93
|
var _a, _b;
|
|
93
94
|
const slugs = typeof slug === "string" ? [slug] : slug;
|
|
94
|
-
const
|
|
95
|
-
if (!value && !!
|
|
96
|
-
return message.replace("{slugKey}", slugKey).replace("{
|
|
95
|
+
const slugValue = (_b = (_a = context.parent) == null ? void 0 : _a[slugKey]) == null ? void 0 : _b.current;
|
|
96
|
+
if (!value && !!slugValue && slugs.includes(slugValue)) {
|
|
97
|
+
return message.replace("{slugKey}", slugKey).replace("{operand}", slugs.join(", or ")).replace("{siblingSlugValue}", slugValue);
|
|
97
98
|
}
|
|
98
99
|
return true;
|
|
99
100
|
};
|
|
100
101
|
|
|
101
102
|
// src/requiredIfSiblingEq.ts
|
|
102
|
-
var requiredIfSiblingEq = (key,
|
|
103
|
-
var _a;
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
if (!value &&
|
|
107
|
-
return message.replace("{key}", key).replace("{
|
|
103
|
+
var requiredIfSiblingEq = (key, operand, message = "Required if {key} equals {operand}.") => (value, context) => {
|
|
104
|
+
var _a, _b;
|
|
105
|
+
const siblingValue = getSibling(key, context);
|
|
106
|
+
const operands = Array.isArray(operand) ? operand : [operand];
|
|
107
|
+
if (!value && operands.includes(siblingValue)) {
|
|
108
|
+
return message.replace("{key}", key).replace("{operand}", (_a = operands.join(", or ")) != null ? _a : "null").replace("{value}", (_b = operands.join(", or ")) != null ? _b : "null").replace("{siblingValue}", siblingValue);
|
|
108
109
|
}
|
|
109
110
|
return true;
|
|
110
111
|
};
|
|
@@ -116,6 +117,15 @@ var getSibling = (key, context) => {
|
|
|
116
117
|
const sibling = (0, import_lodash_es.get)(context.document, [...pathToParentObject, key]);
|
|
117
118
|
return sibling;
|
|
118
119
|
};
|
|
120
|
+
|
|
121
|
+
// src/regex.ts
|
|
122
|
+
var regex = (pattern, message = `\u201C{value}\u201D does not match the pattern {pattern}.`) => (value) => {
|
|
123
|
+
if (!value) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
const valueAsString = typeof value !== "string" ? value.toString() : value;
|
|
127
|
+
return pattern.test(valueAsString) ? true : message.replace("{value}", valueAsString).replace("{pattern}", pattern.toString());
|
|
128
|
+
};
|
|
119
129
|
// Annotate the CommonJS export names for ESM import in node:
|
|
120
130
|
0 && (module.exports = {
|
|
121
131
|
fileExtension,
|
|
@@ -123,6 +133,7 @@ var getSibling = (key, context) => {
|
|
|
123
133
|
maxDepth,
|
|
124
134
|
minDimensions,
|
|
125
135
|
referencedDocumentRequires,
|
|
136
|
+
regex,
|
|
126
137
|
requiredIfSiblingEq,
|
|
127
138
|
requiredIfSlugEq
|
|
128
139
|
});
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/referencedDocumentRequires.ts","../src/fileExtension.ts","../src/minDimensions.ts","../src/maxDepth.ts","../src/requiredIfSlugEq.ts","../src/requiredIfSiblingEq.ts","../src/lib/getSibling.ts"],"sourcesContent":["export * from \"./referencedDocumentRequires\"\nexport * from \"./fileExtension\"\nexport * from \"./minDimensions\"\nexport * from \"./maxDepth\"\nexport * from \"./requiredIfSlugEq\"\nexport * from \"./requiredIfSiblingEq\"\nexport * from \"./lib\"\n","import { ValidationContext } from \"sanity\"\n\nexport const referencedDocumentRequires = (\n documentType: string, \n field: string, \n message: string = `{documentType}’s {field} must be filled.`\n) => async (value: any | undefined, context: ValidationContext) => {\n if (!value?._ref) {\n return true\n }\n const client = context.getClient({ apiVersion: \"2022-08-12\" })\n // todo: use current API version, or test with no version at all\n\n // todo: if there's a value._type or value.referenced._type or something, we get rid of document.type from inputs\n const data = await client.fetch(`\n *[_type == \"${documentType}\" && _id == \"${value._ref}\"]{\n ${field}\n }[0]\n `) // TODO: why is typescript screaming about this? Fetch takes two parameters.\n if (!data[field]) {\n return message.replace(\"{documentType}\", documentType).replace(\"{field}\", field)\n }\n return true\n}\n","import { getExtension } from \"@sanity/asset-utils\"\nimport { FileValue } from \"sanity\"\n\nexport const fileExtension = (\n validFileExtension: string | Array<string>, \n message: string = `Image must be of type {validFileExtension}`\n) => (value: FileValue | undefined) => {\n if (!value || !value.asset) {\n return true\n }\n const validExtensions = typeof validFileExtension === \"string\" ? [validFileExtension] : validFileExtension\n const filetype = getExtension(value.asset._ref)\n if (!validExtensions.includes(filetype)) {\n return message.replace(\"{validFileExtension}\", validExtensions.join(\", or \"))\n }\n return true\n}\n","import { getImageDimensions } from \"@sanity/asset-utils\"\nimport { FileValue } from \"sanity\"\n\nexport const minDimensions =\n ({ x, y }: { x: number; y: number }, message?: string) =>\n (value: FileValue | undefined) => {\n if (!value || !value.asset) {\n return true\n }\n const { width, height } = getImageDimensions(value.asset._ref)\n if (!!x && width < x) {\n return message ? message.replace(\"{x}\", x.toString()).replace(\"{y}\", !y ? \"(any)\" : y.toString()) : `Image must be at least ${x} pixels wide.`\n }\n if (!!y && height < y) {\n return message ? message.replace(\"{x}\", !x ? \"(any)\" : x.toString()).replace(\"{y}\", y.toString()) : `Image must be at least ${y} pixels tall.`\n }\n return true\n }\n","import { ValidationContext } from \"sanity\"\n\nexport const maxDepth = (\n maxDepth: number, \n nestedValueName: string,\n message: string = `Error: You can only nest {nestedValueName} {maxDepth} levels deep.`\n) => (_: any, context: ValidationContext) => {\n let regex = new RegExp(String.raw`topLevelItems|${nestedValueName}`)\n const paths = (context.path as Array<any>).filter((e) => typeof e === \"string\" && e.match(regex))\n if (paths.length > maxDepth) {\n return message.replace(\"{nestedValueName}\", nestedValueName).replace(\"{maxDepth}\", maxDepth.toString())\n }\n return true\n}\n","import { ValidationContext } from \"sanity\"\n\n/*\nSanity has a funny idea of conditional fields. Every field is _always_ present, but it might be hidden.\nex. hidden: (node) => node.parent.slug === 'hideMe'\nThis works really well — unless a field marked as required gets hidden. \n\nThis validator conditionally marks a field as required only for specific slugs. It accepts a string or array of strings.\n```\nvalidation: (rule) => rule.custom(requiredIfSlugEq('alpha'))\nvalidation: (rule) => rule.custom(requiredIfSlugEq(['alpha', 'beta']))\nvalidation: (rule) => rule.custom(requiredIfSlugNotEq(['beta']))\n```\n\nIf the key of your slug is not simply \"slug\", fill that in the optional second parameter.\n```\nvalidation: (rule) => rule.custom(requiredIfSlugEq('alpha', 'id'))\n```\n\n\"Could this method be simpler if it just checked for the self.hidden state?\"\nNot possible, since the hidden state is not exposed to the context.\n\nBut even if it were, you wouldn't want to. There are valid reasons to make a component required but hidden.\nex. an admin- or developer-level identifier that you don't want civilians to see or edit.\n*/\n\nexport const requiredIfSlugEq = (\n slug: Array<string> | string, \n slugKey: string = \"slug\", \n message: string = `This is a required field.`\n) =>\n (value: unknown | undefined, context: ValidationContext) => {\n const slugs = typeof slug === \"string\" ? [slug] : slug\n const currentSlugValue = (context.parent as any)?.[slugKey]?.current\n \n // todo: does slugKey exist? If not, fail.\n // todo: deal with nested slugKey (ex. metadata.slug)\n \n if (!value && !!currentSlugValue && slugs.includes(currentSlugValue)) {\n return message.replace(\"{slugKey}\", slugKey).replace(\"{slug}\", slugs.join(', or '))\n }\n return true\n }","import {getSibling} from './'\nimport {ValidationContext} from 'sanity'\n\n/*\nFor a given object that has multiple fields, mark a field as `required` if a sibling has a particular value.\n\n```\ndefineType({\n name: 'ifAlphaAlsoBeta',\n type: 'object',\n fields: [\n defineField({\n name: 'alpha',\n type: 'string',\n options: {\n list: ['left', 'right'],\n layout: 'radio',\n direction: 'horizontal',\n },\n }),\n defineField({\n name: 'beta',\n type: 'string',\n placeholder: 'If alpha is “left”, I’m also required',\n validation: (rule) => rule.custom(requiredIfSiblingEq('alpha', 'left')),\n })\n ],\n})\n```\n\nIncidentally, context.path is technically Array<sanity.PathSegment>.\n\nThat shouldn't matter, but dealing with that and remapping siblingKey as a PathSegment could be a possible future enhancement.\n*/\n\nexport const requiredIfSiblingEq = (\n key: string, \n comparison: string | number | null | Array<string | number | null>, \n message: string = 'Required if {key} equals {value}.'\n) =>\n (value: unknown | undefined, context: ValidationContext) => {\n const sibling = getSibling(key, context)\n const comparisons = Array.isArray(comparison) ? comparison : [comparison]\n if (!value && comparisons.includes(sibling)) {\n return message.replace('{key}', key).replace('{value}', comparisons.join(', or ') ?? 'null')\n }\n return true\n }\n","import { get } from \"lodash-es\"\nimport { ValidationContext } from \"sanity\"\n\nexport const getSibling = (key: string | number, context: ValidationContext) => {\n const pathToParentObject = context.path!.slice(0, -1) as Array<string | number>\n const sibling = get(context.document, [...pathToParentObject, key])\n return sibling\n}\n\n/*\nTODO:\n There is an issue with finding a sibling when in an array element.\n If the context document looks something like this…\n {\n someArray: [\n {\n _key: 'abc123',\n targetSibling: 'herpderp'\n }\n ]\n }\n … we wind up with a path of…\n [ 'someArray', { _key: 'ab123' }, 'targetSibling' ]\n lodash.get() is trying to do an exact match, it doesn't know how to get object by _key.\n \n Will probably have to replace get() with a gnarly recursive lookup function.\n*/\n"],"mappings":"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","names":["import_asset_utils","maxDepth"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/referencedDocumentRequires.ts","../src/fileExtension.ts","../src/minDimensions.ts","../src/maxDepth.ts","../src/requiredIfSlugEq.ts","../src/requiredIfSiblingEq.ts","../src/lib/getSibling.ts","../src/regex.ts"],"sourcesContent":["export * from \"./referencedDocumentRequires\"\nexport * from \"./fileExtension\"\nexport * from \"./minDimensions\"\nexport * from \"./maxDepth\"\nexport * from \"./requiredIfSlugEq\"\nexport * from \"./requiredIfSiblingEq\"\nexport * from \"./lib\"\nexport * from \"./regex\"\n","import { ValidationContext } from \"sanity\"\n\nexport const referencedDocumentRequires = (\n documentType: string, \n field: string, \n message: string = `{documentType}’s {field} must be filled.`\n) => async (value: any | undefined, context: ValidationContext) => {\n if (!value?._ref) {\n return true\n }\n const client = context.getClient({ apiVersion: \"2022-08-12\" })\n // todo: use current API version, or test with no version at all\n\n // todo: if there's a value._type or value.referenced._type or something, we get rid of document.type from inputs\n const data = await client.fetch(`\n *[_type == \"${documentType}\" && _id == \"${value._ref}\"]{\n ${field}\n }[0]\n `) // TODO: why is typescript screaming about this? Fetch takes two parameters.\n if (!data[field]) {\n return message.replace(\"{documentType}\", documentType).replace(\"{field}\", field)\n }\n return true\n}\n","import { getExtension } from \"@sanity/asset-utils\"\nimport { FileValue } from \"sanity\"\n\nexport const fileExtension = (\n validFileExtension: string | Array<string>, \n message: string = `Image must be of type {validFileExtension}`\n) => (value: FileValue | undefined) => {\n if (!value || !value.asset) {\n return true\n }\n const validExtensions = typeof validFileExtension === \"string\" ? [validFileExtension] : validFileExtension\n const filetype = getExtension(value.asset._ref)\n if (!validExtensions.includes(filetype)) {\n return message.replace(\"{validFileExtension}\", validExtensions.join(\", or \"))\n }\n return true\n}\n\n// todo: this should fail if its attached to a field that is not of type \"file\"","import { getImageDimensions } from \"@sanity/asset-utils\"\nimport { FileValue } from \"sanity\"\n\nexport const minDimensions =\n ({ x, y }: { x: number; y: number }, message?: string) =>\n (value: FileValue | undefined) => {\n if (!value || !value.asset) {\n return true\n }\n const { width, height } = getImageDimensions(value.asset._ref)\n if (!!x && width < x) {\n return message \n ? message.replace(\"{width}\", width.toString())\n .replace(\"{height}\", height.toString())\n .replace(\"{x}\", x.toString())\n .replace(\"{y}\", !y ? \"(any)\" : y.toString()) \n : `Image must be at least ${x} pixels wide.`\n }\n if (!!y && height < y) {\n return message \n ? message.replace(\"{width}\", width.toString())\n .replace(\"{height}\", height.toString())\n .replace(\"{x}\", !x ? \"(any)\" : x.toString())\n .replace(\"{y}\", y.toString())\n : `Image must be at least ${y} pixels tall.`\n }\n return true\n }\n\n// todo: this should fail if its attached to a field that is not of type \"image\"","import { ValidationContext } from \"sanity\"\n\nexport const maxDepth = (\n maxDepth: number, \n key: string,\n message: string = `Error: You can only nest {key} {maxDepth} levels deep.`\n) => (_: any, context: ValidationContext) => {\n let regex = new RegExp(String.raw`topLevelItems|${key}`)\n const paths = (context.path as Array<any>).filter((e) => typeof e === \"string\" && e.match(regex))\n if (paths.length > maxDepth) {\n return message\n .replace(\"{key}\", key)\n .replace(\"{nestedValueName}\", key) // backward compatibility\n .replace(\"{maxDepth}\", maxDepth.toString())\n }\n return true\n}\n","import { ValidationContext } from \"sanity\"\n\n/*\nSanity has a funny idea of conditional fields. Every field is _always_ present, but it might be hidden.\nex. hidden: (node) => node.parent.slug === 'hideMe'\nThis works really well — unless a field marked as required gets hidden. \n\nThis validator conditionally marks a field as required only for specific slugs. It accepts a string or array of strings.\n```\nvalidation: (rule) => rule.custom(requiredIfSlugEq('alpha'))\nvalidation: (rule) => rule.custom(requiredIfSlugEq(['alpha', 'beta']))\nvalidation: (rule) => rule.custom(requiredIfSlugNotEq(['beta']))\n```\n\nIf the key of your slug is not simply \"slug\", fill that in the optional second parameter.\n```\nvalidation: (rule) => rule.custom(requiredIfSlugEq('alpha', 'id'))\n```\n\n\"Could this method be simpler if it just checked for the self.hidden state?\"\nNot possible, since the hidden state is not exposed to the context.\n\nBut even if it were, you wouldn't want to. There are valid reasons to make a component required but hidden.\nex. an admin- or developer-level identifier that you don't want civilians to see or edit.\n*/\n\nexport const requiredIfSlugEq = (\n slug: Array<string> | string, \n slugKey: string = \"slug\", \n message: string = `This is a required field.`\n) =>\n (value: unknown | undefined, context: ValidationContext) => {\n const slugs = typeof slug === \"string\" ? [slug] : slug\n const slugValue = (context.parent as any)?.[slugKey]?.current\n \n // todo: does slugKey exist? If not, fail.\n // todo: deal with nested slugKey (ex. metadata.slug)\n \n if (!value && !!slugValue && slugs.includes(slugValue)) {\n return message\n .replace(\"{slugKey}\", slugKey)\n .replace(\"{operand}\", slugs.join(', or '))\n .replace(\"{siblingSlugValue}\", slugValue)\n }\n return true\n }","import {getSibling} from './'\nimport {ValidationContext} from 'sanity'\n\n/*\nFor a given object that has multiple fields, mark a field as `required` if a sibling has a particular value.\n\n```\ndefineType({\n name: 'ifAlphaAlsoBeta',\n type: 'object',\n fields: [\n defineField({\n name: 'alpha',\n type: 'string',\n options: {\n list: ['left', 'right'],\n layout: 'radio',\n direction: 'horizontal',\n },\n }),\n defineField({\n name: 'beta',\n type: 'string',\n placeholder: 'If alpha is “left”, I’m also required',\n validation: (rule) => rule.custom(requiredIfSiblingEq('alpha', 'left')),\n })\n ],\n})\n```\n\nIncidentally, context.path is technically Array<sanity.PathSegment>.\n\nThat shouldn't matter, but dealing with that and remapping siblingKey as a PathSegment could be a possible future enhancement.\n*/\n\nexport const requiredIfSiblingEq = (\n key: string, \n operand: string | number | null | Array<string | number | null>, \n message: string = 'Required if {key} equals {operand}.'\n) =>\n (value: unknown | undefined, context: ValidationContext) => {\n const siblingValue = getSibling(key, context)\n const operands = Array.isArray(operand) ? operand : [operand]\n if (!value && operands.includes(siblingValue)) {\n return message\n .replace('{key}', key)\n .replace('{operand}', operands.join(', or ') ?? 'null')\n .replace('{value}', operands.join(', or ') ?? 'null') // backward compatibility\n .replace('{siblingValue}', siblingValue)\n }\n return true\n }\n","import { get } from \"lodash-es\"\nimport { ValidationContext } from \"sanity\"\n\nexport const getSibling = (key: string | number, context: ValidationContext) => {\n const pathToParentObject = context.path!.slice(0, -1) as Array<string | number>\n const sibling = get(context.document, [...pathToParentObject, key])\n return sibling\n}\n\n/*\nTODO:\n There is an issue with finding a sibling when in an array element.\n If the context document looks something like this…\n {\n someArray: [\n {\n _key: 'abc123',\n targetSibling: 'herpderp'\n }\n ]\n }\n … we wind up with a path of…\n [ 'someArray', { _key: 'ab123' }, 'targetSibling' ]\n lodash.get() is trying to do an exact match, it doesn't know how to get object by _key.\n \n Will probably have to replace get() with a gnarly recursive lookup function.\n*/\n","export const regex =\n (pattern: RegExp, message: string = `“{value}” does not match the pattern {pattern}.`) =>\n (value: unknown) => {\n if (!value) {\n return true\n }\n const valueAsString = typeof value !== \"string\" ? value.toString() : value\n return pattern.test(valueAsString) ? true : message.replace(\"{value}\", valueAsString).replace(\"{pattern}\", pattern.toString())\n }\n"],"mappings":"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","names":["import_asset_utils","maxDepth","regex"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -9,12 +9,14 @@ declare const minDimensions: ({ x, y }: {
|
|
|
9
9
|
y: number;
|
|
10
10
|
}, message?: string) => (value: FileValue | undefined) => string | true;
|
|
11
11
|
|
|
12
|
-
declare const maxDepth: (maxDepth: number,
|
|
12
|
+
declare const maxDepth: (maxDepth: number, key: string, message?: string) => (_: any, context: ValidationContext) => string | true;
|
|
13
13
|
|
|
14
14
|
declare const requiredIfSlugEq: (slug: Array<string> | string, slugKey?: string, message?: string) => (value: unknown | undefined, context: ValidationContext) => string | true;
|
|
15
15
|
|
|
16
|
-
declare const requiredIfSiblingEq: (key: string,
|
|
16
|
+
declare const requiredIfSiblingEq: (key: string, operand: string | number | null | Array<string | number | null>, message?: string) => (value: unknown | undefined, context: ValidationContext) => string | true;
|
|
17
17
|
|
|
18
18
|
declare const getSibling: (key: string | number, context: ValidationContext) => any;
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
declare const regex: (pattern: RegExp, message?: string) => (value: unknown) => string | true;
|
|
21
|
+
|
|
22
|
+
export { fileExtension, getSibling, maxDepth, minDimensions, referencedDocumentRequires, regex, requiredIfSiblingEq, requiredIfSlugEq };
|
package/dist/index.d.ts
CHANGED
|
@@ -9,12 +9,14 @@ declare const minDimensions: ({ x, y }: {
|
|
|
9
9
|
y: number;
|
|
10
10
|
}, message?: string) => (value: FileValue | undefined) => string | true;
|
|
11
11
|
|
|
12
|
-
declare const maxDepth: (maxDepth: number,
|
|
12
|
+
declare const maxDepth: (maxDepth: number, key: string, message?: string) => (_: any, context: ValidationContext) => string | true;
|
|
13
13
|
|
|
14
14
|
declare const requiredIfSlugEq: (slug: Array<string> | string, slugKey?: string, message?: string) => (value: unknown | undefined, context: ValidationContext) => string | true;
|
|
15
15
|
|
|
16
|
-
declare const requiredIfSiblingEq: (key: string,
|
|
16
|
+
declare const requiredIfSiblingEq: (key: string, operand: string | number | null | Array<string | number | null>, message?: string) => (value: unknown | undefined, context: ValidationContext) => string | true;
|
|
17
17
|
|
|
18
18
|
declare const getSibling: (key: string | number, context: ValidationContext) => any;
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
declare const regex: (pattern: RegExp, message?: string) => (value: unknown) => string | true;
|
|
21
|
+
|
|
22
|
+
export { fileExtension, getSibling, maxDepth, minDimensions, referencedDocumentRequires, regex, requiredIfSiblingEq, requiredIfSlugEq };
|
package/dist/index.js
CHANGED
|
@@ -37,20 +37,20 @@ var minDimensions = ({ x, y }, message) => (value) => {
|
|
|
37
37
|
}
|
|
38
38
|
const { width, height } = getImageDimensions(value.asset._ref);
|
|
39
39
|
if (!!x && width < x) {
|
|
40
|
-
return message ? message.replace("{x}", x.toString()).replace("{y}", !y ? "(any)" : y.toString()) : `Image must be at least ${x} pixels wide.`;
|
|
40
|
+
return message ? message.replace("{width}", width.toString()).replace("{height}", height.toString()).replace("{x}", x.toString()).replace("{y}", !y ? "(any)" : y.toString()) : `Image must be at least ${x} pixels wide.`;
|
|
41
41
|
}
|
|
42
42
|
if (!!y && height < y) {
|
|
43
|
-
return message ? message.replace("{x}", !x ? "(any)" : x.toString()).replace("{y}", y.toString()) : `Image must be at least ${y} pixels tall.`;
|
|
43
|
+
return message ? message.replace("{width}", width.toString()).replace("{height}", height.toString()).replace("{x}", !x ? "(any)" : x.toString()).replace("{y}", y.toString()) : `Image must be at least ${y} pixels tall.`;
|
|
44
44
|
}
|
|
45
45
|
return true;
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
// src/maxDepth.ts
|
|
49
|
-
var maxDepth = (maxDepth2,
|
|
50
|
-
let
|
|
51
|
-
const paths = context.path.filter((e) => typeof e === "string" && e.match(
|
|
49
|
+
var maxDepth = (maxDepth2, key, message = `Error: You can only nest {key} {maxDepth} levels deep.`) => (_, context) => {
|
|
50
|
+
let regex2 = new RegExp(String.raw`topLevelItems|${key}`);
|
|
51
|
+
const paths = context.path.filter((e) => typeof e === "string" && e.match(regex2));
|
|
52
52
|
if (paths.length > maxDepth2) {
|
|
53
|
-
return message.replace("{nestedValueName}",
|
|
53
|
+
return message.replace("{key}", key).replace("{nestedValueName}", key).replace("{maxDepth}", maxDepth2.toString());
|
|
54
54
|
}
|
|
55
55
|
return true;
|
|
56
56
|
};
|
|
@@ -59,20 +59,20 @@ var maxDepth = (maxDepth2, nestedValueName, message = `Error: You can only nest
|
|
|
59
59
|
var requiredIfSlugEq = (slug, slugKey = "slug", message = `This is a required field.`) => (value, context) => {
|
|
60
60
|
var _a, _b;
|
|
61
61
|
const slugs = typeof slug === "string" ? [slug] : slug;
|
|
62
|
-
const
|
|
63
|
-
if (!value && !!
|
|
64
|
-
return message.replace("{slugKey}", slugKey).replace("{
|
|
62
|
+
const slugValue = (_b = (_a = context.parent) == null ? void 0 : _a[slugKey]) == null ? void 0 : _b.current;
|
|
63
|
+
if (!value && !!slugValue && slugs.includes(slugValue)) {
|
|
64
|
+
return message.replace("{slugKey}", slugKey).replace("{operand}", slugs.join(", or ")).replace("{siblingSlugValue}", slugValue);
|
|
65
65
|
}
|
|
66
66
|
return true;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
// src/requiredIfSiblingEq.ts
|
|
70
|
-
var requiredIfSiblingEq = (key,
|
|
71
|
-
var _a;
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
if (!value &&
|
|
75
|
-
return message.replace("{key}", key).replace("{
|
|
70
|
+
var requiredIfSiblingEq = (key, operand, message = "Required if {key} equals {operand}.") => (value, context) => {
|
|
71
|
+
var _a, _b;
|
|
72
|
+
const siblingValue = getSibling(key, context);
|
|
73
|
+
const operands = Array.isArray(operand) ? operand : [operand];
|
|
74
|
+
if (!value && operands.includes(siblingValue)) {
|
|
75
|
+
return message.replace("{key}", key).replace("{operand}", (_a = operands.join(", or ")) != null ? _a : "null").replace("{value}", (_b = operands.join(", or ")) != null ? _b : "null").replace("{siblingValue}", siblingValue);
|
|
76
76
|
}
|
|
77
77
|
return true;
|
|
78
78
|
};
|
|
@@ -84,12 +84,22 @@ var getSibling = (key, context) => {
|
|
|
84
84
|
const sibling = get(context.document, [...pathToParentObject, key]);
|
|
85
85
|
return sibling;
|
|
86
86
|
};
|
|
87
|
+
|
|
88
|
+
// src/regex.ts
|
|
89
|
+
var regex = (pattern, message = `\u201C{value}\u201D does not match the pattern {pattern}.`) => (value) => {
|
|
90
|
+
if (!value) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
const valueAsString = typeof value !== "string" ? value.toString() : value;
|
|
94
|
+
return pattern.test(valueAsString) ? true : message.replace("{value}", valueAsString).replace("{pattern}", pattern.toString());
|
|
95
|
+
};
|
|
87
96
|
export {
|
|
88
97
|
fileExtension,
|
|
89
98
|
getSibling,
|
|
90
99
|
maxDepth,
|
|
91
100
|
minDimensions,
|
|
92
101
|
referencedDocumentRequires,
|
|
102
|
+
regex,
|
|
93
103
|
requiredIfSiblingEq,
|
|
94
104
|
requiredIfSlugEq
|
|
95
105
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/referencedDocumentRequires.ts","../src/fileExtension.ts","../src/minDimensions.ts","../src/maxDepth.ts","../src/requiredIfSlugEq.ts","../src/requiredIfSiblingEq.ts","../src/lib/getSibling.ts"],"sourcesContent":["import { ValidationContext } from \"sanity\"\n\nexport const referencedDocumentRequires = (\n documentType: string, \n field: string, \n message: string = `{documentType}’s {field} must be filled.`\n) => async (value: any | undefined, context: ValidationContext) => {\n if (!value?._ref) {\n return true\n }\n const client = context.getClient({ apiVersion: \"2022-08-12\" })\n // todo: use current API version, or test with no version at all\n\n // todo: if there's a value._type or value.referenced._type or something, we get rid of document.type from inputs\n const data = await client.fetch(`\n *[_type == \"${documentType}\" && _id == \"${value._ref}\"]{\n ${field}\n }[0]\n `) // TODO: why is typescript screaming about this? Fetch takes two parameters.\n if (!data[field]) {\n return message.replace(\"{documentType}\", documentType).replace(\"{field}\", field)\n }\n return true\n}\n","import { getExtension } from \"@sanity/asset-utils\"\nimport { FileValue } from \"sanity\"\n\nexport const fileExtension = (\n validFileExtension: string | Array<string>, \n message: string = `Image must be of type {validFileExtension}`\n) => (value: FileValue | undefined) => {\n if (!value || !value.asset) {\n return true\n }\n const validExtensions = typeof validFileExtension === \"string\" ? [validFileExtension] : validFileExtension\n const filetype = getExtension(value.asset._ref)\n if (!validExtensions.includes(filetype)) {\n return message.replace(\"{validFileExtension}\", validExtensions.join(\", or \"))\n }\n return true\n}\n","import { getImageDimensions } from \"@sanity/asset-utils\"\nimport { FileValue } from \"sanity\"\n\nexport const minDimensions =\n ({ x, y }: { x: number; y: number }, message?: string) =>\n (value: FileValue | undefined) => {\n if (!value || !value.asset) {\n return true\n }\n const { width, height } = getImageDimensions(value.asset._ref)\n if (!!x && width < x) {\n return message ? message.replace(\"{x}\", x.toString()).replace(\"{y}\", !y ? \"(any)\" : y.toString()) : `Image must be at least ${x} pixels wide.`\n }\n if (!!y && height < y) {\n return message ? message.replace(\"{x}\", !x ? \"(any)\" : x.toString()).replace(\"{y}\", y.toString()) : `Image must be at least ${y} pixels tall.`\n }\n return true\n }\n","import { ValidationContext } from \"sanity\"\n\nexport const maxDepth = (\n maxDepth: number, \n nestedValueName: string,\n message: string = `Error: You can only nest {nestedValueName} {maxDepth} levels deep.`\n) => (_: any, context: ValidationContext) => {\n let regex = new RegExp(String.raw`topLevelItems|${nestedValueName}`)\n const paths = (context.path as Array<any>).filter((e) => typeof e === \"string\" && e.match(regex))\n if (paths.length > maxDepth) {\n return message.replace(\"{nestedValueName}\", nestedValueName).replace(\"{maxDepth}\", maxDepth.toString())\n }\n return true\n}\n","import { ValidationContext } from \"sanity\"\n\n/*\nSanity has a funny idea of conditional fields. Every field is _always_ present, but it might be hidden.\nex. hidden: (node) => node.parent.slug === 'hideMe'\nThis works really well — unless a field marked as required gets hidden. \n\nThis validator conditionally marks a field as required only for specific slugs. It accepts a string or array of strings.\n```\nvalidation: (rule) => rule.custom(requiredIfSlugEq('alpha'))\nvalidation: (rule) => rule.custom(requiredIfSlugEq(['alpha', 'beta']))\nvalidation: (rule) => rule.custom(requiredIfSlugNotEq(['beta']))\n```\n\nIf the key of your slug is not simply \"slug\", fill that in the optional second parameter.\n```\nvalidation: (rule) => rule.custom(requiredIfSlugEq('alpha', 'id'))\n```\n\n\"Could this method be simpler if it just checked for the self.hidden state?\"\nNot possible, since the hidden state is not exposed to the context.\n\nBut even if it were, you wouldn't want to. There are valid reasons to make a component required but hidden.\nex. an admin- or developer-level identifier that you don't want civilians to see or edit.\n*/\n\nexport const requiredIfSlugEq = (\n slug: Array<string> | string, \n slugKey: string = \"slug\", \n message: string = `This is a required field.`\n) =>\n (value: unknown | undefined, context: ValidationContext) => {\n const slugs = typeof slug === \"string\" ? [slug] : slug\n const currentSlugValue = (context.parent as any)?.[slugKey]?.current\n \n // todo: does slugKey exist? If not, fail.\n // todo: deal with nested slugKey (ex. metadata.slug)\n \n if (!value && !!currentSlugValue && slugs.includes(currentSlugValue)) {\n return message.replace(\"{slugKey}\", slugKey).replace(\"{slug}\", slugs.join(', or '))\n }\n return true\n }","import {getSibling} from './'\nimport {ValidationContext} from 'sanity'\n\n/*\nFor a given object that has multiple fields, mark a field as `required` if a sibling has a particular value.\n\n```\ndefineType({\n name: 'ifAlphaAlsoBeta',\n type: 'object',\n fields: [\n defineField({\n name: 'alpha',\n type: 'string',\n options: {\n list: ['left', 'right'],\n layout: 'radio',\n direction: 'horizontal',\n },\n }),\n defineField({\n name: 'beta',\n type: 'string',\n placeholder: 'If alpha is “left”, I’m also required',\n validation: (rule) => rule.custom(requiredIfSiblingEq('alpha', 'left')),\n })\n ],\n})\n```\n\nIncidentally, context.path is technically Array<sanity.PathSegment>.\n\nThat shouldn't matter, but dealing with that and remapping siblingKey as a PathSegment could be a possible future enhancement.\n*/\n\nexport const requiredIfSiblingEq = (\n key: string, \n comparison: string | number | null | Array<string | number | null>, \n message: string = 'Required if {key} equals {value}.'\n) =>\n (value: unknown | undefined, context: ValidationContext) => {\n const sibling = getSibling(key, context)\n const comparisons = Array.isArray(comparison) ? comparison : [comparison]\n if (!value && comparisons.includes(sibling)) {\n return message.replace('{key}', key).replace('{value}', comparisons.join(', or ') ?? 'null')\n }\n return true\n }\n","import { get } from \"lodash-es\"\nimport { ValidationContext } from \"sanity\"\n\nexport const getSibling = (key: string | number, context: ValidationContext) => {\n const pathToParentObject = context.path!.slice(0, -1) as Array<string | number>\n const sibling = get(context.document, [...pathToParentObject, key])\n return sibling\n}\n\n/*\nTODO:\n There is an issue with finding a sibling when in an array element.\n If the context document looks something like this…\n {\n someArray: [\n {\n _key: 'abc123',\n targetSibling: 'herpderp'\n }\n ]\n }\n … we wind up with a path of…\n [ 'someArray', { _key: 'ab123' }, 'targetSibling' ]\n lodash.get() is trying to do an exact match, it doesn't know how to get object by _key.\n \n Will probably have to replace get() with a gnarly recursive lookup function.\n*/\n"],"mappings":"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","names":["maxDepth"]}
|
|
1
|
+
{"version":3,"sources":["../src/referencedDocumentRequires.ts","../src/fileExtension.ts","../src/minDimensions.ts","../src/maxDepth.ts","../src/requiredIfSlugEq.ts","../src/requiredIfSiblingEq.ts","../src/lib/getSibling.ts","../src/regex.ts"],"sourcesContent":["import { ValidationContext } from \"sanity\"\n\nexport const referencedDocumentRequires = (\n documentType: string, \n field: string, \n message: string = `{documentType}’s {field} must be filled.`\n) => async (value: any | undefined, context: ValidationContext) => {\n if (!value?._ref) {\n return true\n }\n const client = context.getClient({ apiVersion: \"2022-08-12\" })\n // todo: use current API version, or test with no version at all\n\n // todo: if there's a value._type or value.referenced._type or something, we get rid of document.type from inputs\n const data = await client.fetch(`\n *[_type == \"${documentType}\" && _id == \"${value._ref}\"]{\n ${field}\n }[0]\n `) // TODO: why is typescript screaming about this? Fetch takes two parameters.\n if (!data[field]) {\n return message.replace(\"{documentType}\", documentType).replace(\"{field}\", field)\n }\n return true\n}\n","import { getExtension } from \"@sanity/asset-utils\"\nimport { FileValue } from \"sanity\"\n\nexport const fileExtension = (\n validFileExtension: string | Array<string>, \n message: string = `Image must be of type {validFileExtension}`\n) => (value: FileValue | undefined) => {\n if (!value || !value.asset) {\n return true\n }\n const validExtensions = typeof validFileExtension === \"string\" ? [validFileExtension] : validFileExtension\n const filetype = getExtension(value.asset._ref)\n if (!validExtensions.includes(filetype)) {\n return message.replace(\"{validFileExtension}\", validExtensions.join(\", or \"))\n }\n return true\n}\n\n// todo: this should fail if its attached to a field that is not of type \"file\"","import { getImageDimensions } from \"@sanity/asset-utils\"\nimport { FileValue } from \"sanity\"\n\nexport const minDimensions =\n ({ x, y }: { x: number; y: number }, message?: string) =>\n (value: FileValue | undefined) => {\n if (!value || !value.asset) {\n return true\n }\n const { width, height } = getImageDimensions(value.asset._ref)\n if (!!x && width < x) {\n return message \n ? message.replace(\"{width}\", width.toString())\n .replace(\"{height}\", height.toString())\n .replace(\"{x}\", x.toString())\n .replace(\"{y}\", !y ? \"(any)\" : y.toString()) \n : `Image must be at least ${x} pixels wide.`\n }\n if (!!y && height < y) {\n return message \n ? message.replace(\"{width}\", width.toString())\n .replace(\"{height}\", height.toString())\n .replace(\"{x}\", !x ? \"(any)\" : x.toString())\n .replace(\"{y}\", y.toString())\n : `Image must be at least ${y} pixels tall.`\n }\n return true\n }\n\n// todo: this should fail if its attached to a field that is not of type \"image\"","import { ValidationContext } from \"sanity\"\n\nexport const maxDepth = (\n maxDepth: number, \n key: string,\n message: string = `Error: You can only nest {key} {maxDepth} levels deep.`\n) => (_: any, context: ValidationContext) => {\n let regex = new RegExp(String.raw`topLevelItems|${key}`)\n const paths = (context.path as Array<any>).filter((e) => typeof e === \"string\" && e.match(regex))\n if (paths.length > maxDepth) {\n return message\n .replace(\"{key}\", key)\n .replace(\"{nestedValueName}\", key) // backward compatibility\n .replace(\"{maxDepth}\", maxDepth.toString())\n }\n return true\n}\n","import { ValidationContext } from \"sanity\"\n\n/*\nSanity has a funny idea of conditional fields. Every field is _always_ present, but it might be hidden.\nex. hidden: (node) => node.parent.slug === 'hideMe'\nThis works really well — unless a field marked as required gets hidden. \n\nThis validator conditionally marks a field as required only for specific slugs. It accepts a string or array of strings.\n```\nvalidation: (rule) => rule.custom(requiredIfSlugEq('alpha'))\nvalidation: (rule) => rule.custom(requiredIfSlugEq(['alpha', 'beta']))\nvalidation: (rule) => rule.custom(requiredIfSlugNotEq(['beta']))\n```\n\nIf the key of your slug is not simply \"slug\", fill that in the optional second parameter.\n```\nvalidation: (rule) => rule.custom(requiredIfSlugEq('alpha', 'id'))\n```\n\n\"Could this method be simpler if it just checked for the self.hidden state?\"\nNot possible, since the hidden state is not exposed to the context.\n\nBut even if it were, you wouldn't want to. There are valid reasons to make a component required but hidden.\nex. an admin- or developer-level identifier that you don't want civilians to see or edit.\n*/\n\nexport const requiredIfSlugEq = (\n slug: Array<string> | string, \n slugKey: string = \"slug\", \n message: string = `This is a required field.`\n) =>\n (value: unknown | undefined, context: ValidationContext) => {\n const slugs = typeof slug === \"string\" ? [slug] : slug\n const slugValue = (context.parent as any)?.[slugKey]?.current\n \n // todo: does slugKey exist? If not, fail.\n // todo: deal with nested slugKey (ex. metadata.slug)\n \n if (!value && !!slugValue && slugs.includes(slugValue)) {\n return message\n .replace(\"{slugKey}\", slugKey)\n .replace(\"{operand}\", slugs.join(', or '))\n .replace(\"{siblingSlugValue}\", slugValue)\n }\n return true\n }","import {getSibling} from './'\nimport {ValidationContext} from 'sanity'\n\n/*\nFor a given object that has multiple fields, mark a field as `required` if a sibling has a particular value.\n\n```\ndefineType({\n name: 'ifAlphaAlsoBeta',\n type: 'object',\n fields: [\n defineField({\n name: 'alpha',\n type: 'string',\n options: {\n list: ['left', 'right'],\n layout: 'radio',\n direction: 'horizontal',\n },\n }),\n defineField({\n name: 'beta',\n type: 'string',\n placeholder: 'If alpha is “left”, I’m also required',\n validation: (rule) => rule.custom(requiredIfSiblingEq('alpha', 'left')),\n })\n ],\n})\n```\n\nIncidentally, context.path is technically Array<sanity.PathSegment>.\n\nThat shouldn't matter, but dealing with that and remapping siblingKey as a PathSegment could be a possible future enhancement.\n*/\n\nexport const requiredIfSiblingEq = (\n key: string, \n operand: string | number | null | Array<string | number | null>, \n message: string = 'Required if {key} equals {operand}.'\n) =>\n (value: unknown | undefined, context: ValidationContext) => {\n const siblingValue = getSibling(key, context)\n const operands = Array.isArray(operand) ? operand : [operand]\n if (!value && operands.includes(siblingValue)) {\n return message\n .replace('{key}', key)\n .replace('{operand}', operands.join(', or ') ?? 'null')\n .replace('{value}', operands.join(', or ') ?? 'null') // backward compatibility\n .replace('{siblingValue}', siblingValue)\n }\n return true\n }\n","import { get } from \"lodash-es\"\nimport { ValidationContext } from \"sanity\"\n\nexport const getSibling = (key: string | number, context: ValidationContext) => {\n const pathToParentObject = context.path!.slice(0, -1) as Array<string | number>\n const sibling = get(context.document, [...pathToParentObject, key])\n return sibling\n}\n\n/*\nTODO:\n There is an issue with finding a sibling when in an array element.\n If the context document looks something like this…\n {\n someArray: [\n {\n _key: 'abc123',\n targetSibling: 'herpderp'\n }\n ]\n }\n … we wind up with a path of…\n [ 'someArray', { _key: 'ab123' }, 'targetSibling' ]\n lodash.get() is trying to do an exact match, it doesn't know how to get object by _key.\n \n Will probably have to replace get() with a gnarly recursive lookup function.\n*/\n","export const regex =\n (pattern: RegExp, message: string = `“{value}” does not match the pattern {pattern}.`) =>\n (value: unknown) => {\n if (!value) {\n return true\n }\n const valueAsString = typeof value !== \"string\" ? value.toString() : value\n return pattern.test(valueAsString) ? true : message.replace(\"{value}\", valueAsString).replace(\"{pattern}\", pattern.toString())\n }\n"],"mappings":"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","names":["maxDepth","regex"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package-name": "sanity-advanced-validators",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Advanced input validation tools for Sanity CMS.",
|
|
5
5
|
"author": "Eric_WVGG",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,13 +22,13 @@
|
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@sanity/asset-utils": "^2.2.1",
|
|
25
|
-
"lodash-es": "^4.
|
|
26
|
-
"sanity": "^
|
|
25
|
+
"lodash-es": "^4.17.0",
|
|
26
|
+
"sanity": "^3.9.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@types/lodash-es": "^4.
|
|
29
|
+
"@types/lodash-es": "^4.17.0",
|
|
30
30
|
"tsup": "^8.5.0",
|
|
31
|
-
"typescript": "^5.
|
|
31
|
+
"typescript": "^5.8.0",
|
|
32
32
|
"vitest": "^3.2.4"
|
|
33
33
|
},
|
|
34
34
|
"name": "sanity-advanced-validators",
|