@sanity/validation 3.0.0-v3-pkg-utils.59 → 3.0.0-v3-pkg-utils.79
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 +9 -1
- package/lib/index.js +131 -50
- package/lib/index.js.map +1 -1
- package/lib/{index.cjs → index.mjs} +109 -71
- package/lib/index.mjs.map +1 -0
- package/package.json +11 -10
- package/src/index.ts +2 -0
- package/src/util/requestIdleCallback.ts +31 -0
- package/src/validateDocument.test.ts +14 -86
- package/src/validateDocument.ts +118 -52
- package/src/validators/slugValidator.ts +2 -2
- package/lib/index.cjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/validation",
|
|
3
|
-
"version": "3.0.0-v3-pkg-utils.
|
|
3
|
+
"version": "3.0.0-v3-pkg-utils.79+73676e30fc",
|
|
4
4
|
"description": "Validation and warning infrastructure for Sanity projects",
|
|
5
|
-
"source": "./src/index.ts",
|
|
6
|
-
"main": "./lib/index.cjs",
|
|
7
|
-
"module": "./lib/index.js",
|
|
8
5
|
"types": "./lib/dts/src/index.d.ts",
|
|
6
|
+
"source": "./src/index.ts",
|
|
7
|
+
"module": "./lib/index.mjs",
|
|
8
|
+
"main": "./lib/index.js",
|
|
9
9
|
"files": [
|
|
10
10
|
"lib",
|
|
11
11
|
"src"
|
|
@@ -43,17 +43,18 @@
|
|
|
43
43
|
"directory": "packages/@sanity/validation"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@sanity/types": "3.0.0-v3-pkg-utils.
|
|
46
|
+
"@sanity/types": "3.0.0-v3-pkg-utils.79+73676e30fc",
|
|
47
47
|
"date-fns": "^2.26.1",
|
|
48
|
-
"lodash": "^4.17.21"
|
|
48
|
+
"lodash": "^4.17.21",
|
|
49
|
+
"rxjs": "^6.5.3"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
|
-
"@sanity/client": "^3.
|
|
52
|
-
"@sanity/schema": "3.0.0-v3-pkg-utils.
|
|
52
|
+
"@sanity/client": "^3.4.1",
|
|
53
|
+
"@sanity/schema": "3.0.0-v3-pkg-utils.79+73676e30fc"
|
|
53
54
|
},
|
|
54
55
|
"peerDependencies": {
|
|
55
|
-
"@sanity/client": "^3.
|
|
56
|
+
"@sanity/client": "^3.4.1",
|
|
56
57
|
"@sanity/schema": "dev-preview"
|
|
57
58
|
},
|
|
58
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "73676e30fcc7d17f60ca574f45b632eb6823b60f"
|
|
59
60
|
}
|
package/src/index.ts
CHANGED
|
@@ -5,3 +5,5 @@ import inferFromSchemaType from './inferFromSchemaType'
|
|
|
5
5
|
|
|
6
6
|
// export default {Rule: RuleClass, validateDocument, inferFromSchema, inferFromSchemaType}
|
|
7
7
|
export {RuleClass as Rule, validateDocument, inferFromSchema, inferFromSchemaType}
|
|
8
|
+
|
|
9
|
+
export {validateDocumentObservable} from './validateDocument'
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple requestIdleCallback polyfill
|
|
3
|
+
* Can be removed when all browsers support requestIdleCallback: https://caniuse.com/requestidlecallback
|
|
4
|
+
* @param callback
|
|
5
|
+
* @param options
|
|
6
|
+
*/
|
|
7
|
+
const requestIdleCallbackShim: typeof window.requestIdleCallback = function requestIdleCallbackShim(
|
|
8
|
+
callback,
|
|
9
|
+
options?
|
|
10
|
+
): number {
|
|
11
|
+
const start = Date.now()
|
|
12
|
+
return window.setTimeout(() => {
|
|
13
|
+
callback({
|
|
14
|
+
didTimeout: false,
|
|
15
|
+
timeRemaining() {
|
|
16
|
+
return Math.max(0, Date.now() - start)
|
|
17
|
+
},
|
|
18
|
+
})
|
|
19
|
+
}, 0)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const cancelIdleCallbackShim: typeof window.cancelIdleCallback = function cancelIdleCallbackShim(
|
|
23
|
+
handle: number
|
|
24
|
+
): void {
|
|
25
|
+
return window.clearTimeout(handle)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const win = typeof window === 'undefined' ? undefined : window
|
|
29
|
+
|
|
30
|
+
export const requestIdleCallback = win?.requestIdleCallback || requestIdleCallbackShim
|
|
31
|
+
export const cancelIdleCallback = win?.cancelIdleCallback || cancelIdleCallbackShim
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type {SanityClient} from '@sanity/client'
|
|
1
2
|
import {Rule, SchemaType, SanityDocument, Schema, ArraySchemaType, Block} from '@sanity/types'
|
|
2
3
|
import {createSchema} from '../test/createSchema'
|
|
3
4
|
import {createMockSanityClient} from '../test/mocks/mockSanityClient'
|
|
@@ -17,7 +18,8 @@ beforeEach(() => {
|
|
|
17
18
|
})
|
|
18
19
|
|
|
19
20
|
// mock client
|
|
20
|
-
const client = createMockSanityClient()
|
|
21
|
+
const client = createMockSanityClient() as any as SanityClient
|
|
22
|
+
const getClient = (options: {apiVersion: string}) => client
|
|
21
23
|
|
|
22
24
|
describe('resolveTypeForArrayItem', () => {
|
|
23
25
|
const schema: Schema = createSchema({
|
|
@@ -93,7 +95,7 @@ describe('validateDocument', () => {
|
|
|
93
95
|
title: null,
|
|
94
96
|
}
|
|
95
97
|
|
|
96
|
-
const result = await validateDocument(
|
|
98
|
+
const result = await validateDocument(getClient, document, schema)
|
|
97
99
|
expect(result).toMatchObject([
|
|
98
100
|
{
|
|
99
101
|
level: 'error',
|
|
@@ -167,7 +169,8 @@ describe('validateItem', () => {
|
|
|
167
169
|
|
|
168
170
|
await expect(
|
|
169
171
|
validateItem({
|
|
170
|
-
client
|
|
172
|
+
client,
|
|
173
|
+
getClient,
|
|
171
174
|
schema,
|
|
172
175
|
value: {},
|
|
173
176
|
document: undefined,
|
|
@@ -237,7 +240,8 @@ describe('validateItem', () => {
|
|
|
237
240
|
|
|
238
241
|
await expect(
|
|
239
242
|
validateItem({
|
|
240
|
-
client
|
|
243
|
+
client,
|
|
244
|
+
getClient,
|
|
241
245
|
schema,
|
|
242
246
|
document: undefined,
|
|
243
247
|
parent: undefined,
|
|
@@ -404,7 +408,8 @@ describe('validateItem', () => {
|
|
|
404
408
|
}
|
|
405
409
|
|
|
406
410
|
const result = await validateItem({
|
|
407
|
-
client
|
|
411
|
+
client,
|
|
412
|
+
getClient,
|
|
408
413
|
schema,
|
|
409
414
|
document: document,
|
|
410
415
|
parent: undefined,
|
|
@@ -507,7 +512,8 @@ describe('validateItem', () => {
|
|
|
507
512
|
|
|
508
513
|
await expect(
|
|
509
514
|
validateItem({
|
|
510
|
-
client
|
|
515
|
+
client,
|
|
516
|
+
getClient,
|
|
511
517
|
schema,
|
|
512
518
|
document: undefined,
|
|
513
519
|
parent: undefined,
|
|
@@ -606,7 +612,8 @@ describe('validateItem', () => {
|
|
|
606
612
|
|
|
607
613
|
await expect(
|
|
608
614
|
validateItem({
|
|
609
|
-
client
|
|
615
|
+
client,
|
|
616
|
+
getClient,
|
|
610
617
|
schema,
|
|
611
618
|
value,
|
|
612
619
|
type: rootType,
|
|
@@ -691,83 +698,4 @@ describe('validateItem', () => {
|
|
|
691
698
|
},
|
|
692
699
|
])
|
|
693
700
|
})
|
|
694
|
-
|
|
695
|
-
it('runs all nested validation checks concurrently', async () => {
|
|
696
|
-
type Resolver = (value: true) => void
|
|
697
|
-
const resolvers = new Set<Resolver>()
|
|
698
|
-
const customValidationFn = () => new Promise<true>((resolve) => resolvers.add(resolve))
|
|
699
|
-
|
|
700
|
-
const schema: Schema = createSchema({
|
|
701
|
-
types: [
|
|
702
|
-
{
|
|
703
|
-
name: 'root',
|
|
704
|
-
type: 'object',
|
|
705
|
-
fields: [
|
|
706
|
-
{
|
|
707
|
-
name: 'level1Object',
|
|
708
|
-
type: 'object',
|
|
709
|
-
validation: (rule: Rule) => [
|
|
710
|
-
rule.custom(customValidationFn),
|
|
711
|
-
rule.fields({
|
|
712
|
-
level2String: (r) => r.custom(customValidationFn),
|
|
713
|
-
}),
|
|
714
|
-
],
|
|
715
|
-
fields: [
|
|
716
|
-
{
|
|
717
|
-
name: 'level2String',
|
|
718
|
-
type: 'string',
|
|
719
|
-
validation: (rule: Rule) => rule.custom(customValidationFn),
|
|
720
|
-
},
|
|
721
|
-
],
|
|
722
|
-
},
|
|
723
|
-
{
|
|
724
|
-
name: 'level1Array',
|
|
725
|
-
type: 'array',
|
|
726
|
-
validation: (rule: Rule) => rule.custom(customValidationFn),
|
|
727
|
-
of: [
|
|
728
|
-
{
|
|
729
|
-
type: 'object',
|
|
730
|
-
fields: [
|
|
731
|
-
{
|
|
732
|
-
name: 'level2Number',
|
|
733
|
-
type: 'number',
|
|
734
|
-
validation: (rule: Rule) => rule.custom(customValidationFn),
|
|
735
|
-
},
|
|
736
|
-
],
|
|
737
|
-
},
|
|
738
|
-
],
|
|
739
|
-
},
|
|
740
|
-
],
|
|
741
|
-
validation: (rule: Rule) => rule.custom(customValidationFn),
|
|
742
|
-
},
|
|
743
|
-
],
|
|
744
|
-
})
|
|
745
|
-
|
|
746
|
-
const value = {
|
|
747
|
-
level1Object: {level3String: 'a string'},
|
|
748
|
-
level1Array: [{level2Number: 5}],
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
const resultPromise = validateItem({
|
|
752
|
-
client: client as any,
|
|
753
|
-
schema,
|
|
754
|
-
value,
|
|
755
|
-
document: undefined,
|
|
756
|
-
parent: undefined,
|
|
757
|
-
path: undefined,
|
|
758
|
-
type: schema.get('root'),
|
|
759
|
-
getDocumentExists: undefined,
|
|
760
|
-
})
|
|
761
|
-
|
|
762
|
-
// after `validateItem(...)` has been initiated, all of the custom
|
|
763
|
-
// validation calls should have fired so the resolver size should equal the
|
|
764
|
-
// amount of total fields
|
|
765
|
-
expect(resolvers.size).toBe(6)
|
|
766
|
-
|
|
767
|
-
for (const resolver of resolvers) {
|
|
768
|
-
resolver(true)
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
await resultPromise
|
|
772
|
-
})
|
|
773
701
|
})
|
package/src/validateDocument.ts
CHANGED
|
@@ -10,9 +10,12 @@ import {
|
|
|
10
10
|
isBlockSchemaType,
|
|
11
11
|
isSpanSchemaType,
|
|
12
12
|
} from '@sanity/types'
|
|
13
|
-
import {
|
|
13
|
+
import {concat, defer, merge, Observable, of} from 'rxjs'
|
|
14
|
+
import {catchError, map, mergeAll, mergeMap, toArray} from 'rxjs/operators'
|
|
15
|
+
import {flatten, uniqBy} from 'lodash'
|
|
14
16
|
import type {SanityClient} from '@sanity/client'
|
|
15
17
|
import typeString from './util/typeString'
|
|
18
|
+
import {cancelIdleCallback, requestIdleCallback} from './util/requestIdleCallback'
|
|
16
19
|
import ValidationErrorClass from './ValidationError'
|
|
17
20
|
import normalizeValidationRules from './util/normalizeValidationRules'
|
|
18
21
|
|
|
@@ -46,40 +49,78 @@ export function resolveTypeForArrayItem(
|
|
|
46
49
|
candidates.find((candidate) => candidate.name === 'object' && primitive === 'object')
|
|
47
50
|
)
|
|
48
51
|
}
|
|
52
|
+
const EMPTY_MARKERS: ValidationMarker[] = []
|
|
49
53
|
|
|
50
54
|
export default async function validateDocument(
|
|
51
|
-
|
|
55
|
+
getClient: (options: {apiVersion: string}) => SanityClient,
|
|
52
56
|
doc: SanityDocument,
|
|
53
57
|
schema: Schema,
|
|
54
58
|
context?: Pick<ValidationContext, 'getDocumentExists'>
|
|
55
59
|
): Promise<ValidationMarker[]> {
|
|
60
|
+
return validateDocumentObservable(getClient, doc, schema, context).toPromise()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function validateDocumentObservable(
|
|
64
|
+
getClient: (options: {apiVersion: string}) => SanityClient,
|
|
65
|
+
doc: SanityDocument,
|
|
66
|
+
schema: Schema,
|
|
67
|
+
context?: Pick<ValidationContext, 'getDocumentExists'>
|
|
68
|
+
): Observable<ValidationMarker[]> {
|
|
56
69
|
const documentType = schema.get(doc._type)
|
|
57
70
|
if (!documentType) {
|
|
58
71
|
console.warn('Schema type for object type "%s" not found, skipping validation', doc._type)
|
|
59
|
-
return
|
|
72
|
+
return of(EMPTY_MARKERS)
|
|
60
73
|
}
|
|
61
74
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
} catch (err) {
|
|
74
|
-
console.error(err)
|
|
75
|
-
return [
|
|
76
|
-
{
|
|
77
|
-
level: 'error',
|
|
78
|
-
path: [],
|
|
79
|
-
item: new ValidationErrorClass(err?.message),
|
|
80
|
-
},
|
|
81
|
-
]
|
|
75
|
+
const client = getClient({apiVersion: '2021-06-07'})
|
|
76
|
+
const validationOptions: ValidateItemOptions = {
|
|
77
|
+
client,
|
|
78
|
+
getClient,
|
|
79
|
+
schema,
|
|
80
|
+
parent: undefined,
|
|
81
|
+
value: doc,
|
|
82
|
+
path: [],
|
|
83
|
+
document: doc,
|
|
84
|
+
type: documentType,
|
|
85
|
+
getDocumentExists: context?.getDocumentExists,
|
|
82
86
|
}
|
|
87
|
+
|
|
88
|
+
// <TEMPORARY UGLY HACK TO PRINT DEPRECATION WARNINGS ON USE>
|
|
89
|
+
/* eslint-disable no-proto */
|
|
90
|
+
const wrappedClient = client as any
|
|
91
|
+
validationOptions.client = [
|
|
92
|
+
...Object.keys(client),
|
|
93
|
+
...Object.keys(wrappedClient.__proto__),
|
|
94
|
+
].reduce((acc, key) => {
|
|
95
|
+
const original = Object.hasOwnProperty.call(client, key)
|
|
96
|
+
? wrappedClient[key]
|
|
97
|
+
: wrappedClient.__proto__[key]
|
|
98
|
+
|
|
99
|
+
return Object.defineProperty(acc, key, {
|
|
100
|
+
get() {
|
|
101
|
+
console.warn(
|
|
102
|
+
'`configContext.client` is deprecated and will be removed in the next release! Use `context.getClient({apiVersion: "2021-06-07"})` instead'
|
|
103
|
+
)
|
|
104
|
+
return original
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
}, {}) as any as SanityClient
|
|
108
|
+
/* eslint-enable no-proto */
|
|
109
|
+
// </TEMPORARY UGLY HACK TO PRINT DEPRECATION WARNINGS ON USE>
|
|
110
|
+
|
|
111
|
+
return validateItemObservable(validationOptions).pipe(
|
|
112
|
+
catchError((err) => {
|
|
113
|
+
console.error(err)
|
|
114
|
+
return of([
|
|
115
|
+
{
|
|
116
|
+
type: 'validation' as const,
|
|
117
|
+
level: 'error' as const,
|
|
118
|
+
path: [],
|
|
119
|
+
item: new ValidationErrorClass(err?.message),
|
|
120
|
+
},
|
|
121
|
+
])
|
|
122
|
+
})
|
|
123
|
+
)
|
|
83
124
|
}
|
|
84
125
|
|
|
85
126
|
/**
|
|
@@ -97,27 +138,32 @@ type ValidateItemOptions = {
|
|
|
97
138
|
value: unknown
|
|
98
139
|
} & ExplicitUndefined<ValidationContext>
|
|
99
140
|
|
|
100
|
-
export
|
|
141
|
+
export function validateItem(opts: ValidateItemOptions): Promise<ValidationMarker[]> {
|
|
142
|
+
return validateItemObservable(opts).toPromise()
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function validateItemObservable({
|
|
101
146
|
value,
|
|
102
147
|
type,
|
|
103
148
|
path = [],
|
|
104
149
|
parent,
|
|
105
150
|
...restOfContext
|
|
106
|
-
}: ValidateItemOptions):
|
|
151
|
+
}: ValidateItemOptions): Observable<ValidationMarker[]> {
|
|
107
152
|
const rules = normalizeValidationRules(type)
|
|
108
|
-
|
|
109
153
|
// run validation for the current value
|
|
110
154
|
const selfChecks = rules.map((rule) =>
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
155
|
+
defer(() =>
|
|
156
|
+
rule.validate(value, {
|
|
157
|
+
...restOfContext,
|
|
158
|
+
parent,
|
|
159
|
+
path,
|
|
160
|
+
type,
|
|
161
|
+
})
|
|
162
|
+
)
|
|
117
163
|
)
|
|
118
164
|
|
|
119
165
|
// run validation for nested values (conditionally)
|
|
120
|
-
let nestedChecks: Array<
|
|
166
|
+
let nestedChecks: Array<Observable<ValidationMarker[]>> = []
|
|
121
167
|
|
|
122
168
|
const selfIsRequired = rules.some((rule) => rule.isRequired())
|
|
123
169
|
const shouldRunNestedObjectValidation =
|
|
@@ -144,12 +190,14 @@ export async function validateItem({
|
|
|
144
190
|
const fieldType = fieldTypes[name]
|
|
145
191
|
return normalizeValidationRules({...fieldType, validation}).map((subRule) => {
|
|
146
192
|
const nestedValue = isRecord(value) ? value[name] : undefined
|
|
147
|
-
return
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
193
|
+
return defer(() =>
|
|
194
|
+
subRule.validate(nestedValue, {
|
|
195
|
+
...restOfContext,
|
|
196
|
+
parent: value,
|
|
197
|
+
path: path.concat(name),
|
|
198
|
+
type: fieldType,
|
|
199
|
+
})
|
|
200
|
+
)
|
|
153
201
|
})
|
|
154
202
|
})
|
|
155
203
|
)
|
|
@@ -157,7 +205,7 @@ export async function validateItem({
|
|
|
157
205
|
// Validation from each field's schema `validation: Rule => {/* ... */}` function
|
|
158
206
|
nestedChecks = nestedChecks.concat(
|
|
159
207
|
type.fields.map((field) =>
|
|
160
|
-
|
|
208
|
+
validateItemObservable({
|
|
161
209
|
...restOfContext,
|
|
162
210
|
parent: value,
|
|
163
211
|
value: isRecord(value) ? value[field.name] : undefined,
|
|
@@ -177,7 +225,7 @@ export async function validateItem({
|
|
|
177
225
|
if (shouldRunNestedValidationForArrays) {
|
|
178
226
|
nestedChecks = nestedChecks.concat(
|
|
179
227
|
value.map((item) =>
|
|
180
|
-
|
|
228
|
+
validateItemObservable({
|
|
181
229
|
...restOfContext,
|
|
182
230
|
parent: value,
|
|
183
231
|
value: item,
|
|
@@ -198,16 +246,16 @@ export async function validateItem({
|
|
|
198
246
|
const spanType = spanChildrenField.type.of.find(isSpanSchemaType)
|
|
199
247
|
|
|
200
248
|
const annotations = (spanType?.annotations || []).reduce<Map<string, SchemaType>>(
|
|
201
|
-
(
|
|
202
|
-
|
|
203
|
-
return
|
|
249
|
+
(acc, annotationType) => {
|
|
250
|
+
acc.set(annotationType.name, annotationType)
|
|
251
|
+
return acc
|
|
204
252
|
},
|
|
205
253
|
new Map()
|
|
206
254
|
)
|
|
207
255
|
|
|
208
256
|
nestedChecks = nestedChecks.concat(
|
|
209
257
|
value.markDefs.map((markDef) =>
|
|
210
|
-
|
|
258
|
+
validateItemObservable({
|
|
211
259
|
...restOfContext,
|
|
212
260
|
parent: value,
|
|
213
261
|
value: markDef,
|
|
@@ -218,13 +266,31 @@ export async function validateItem({
|
|
|
218
266
|
)
|
|
219
267
|
}
|
|
220
268
|
|
|
221
|
-
|
|
269
|
+
return defer(() => merge([...selfChecks, ...nestedChecks])).pipe(
|
|
270
|
+
mergeMap((validateNode) => concat(idle(), validateNode), 40),
|
|
271
|
+
mergeAll(),
|
|
272
|
+
toArray(),
|
|
273
|
+
map(flatten),
|
|
274
|
+
map((results) => {
|
|
275
|
+
// run `uniqBy` if `_fieldRules` are present because they can
|
|
276
|
+
// cause repeat markers
|
|
277
|
+
if (rules.some((rule) => rule._fieldRules)) {
|
|
278
|
+
return uniqBy(results, (rule) => JSON.stringify(rule))
|
|
279
|
+
}
|
|
280
|
+
return results
|
|
281
|
+
})
|
|
282
|
+
)
|
|
283
|
+
}
|
|
222
284
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
285
|
+
function idle(timeout?: number): Observable<never> {
|
|
286
|
+
return new Observable<never>((observer) => {
|
|
287
|
+
const handle = requestIdleCallback(
|
|
288
|
+
() => {
|
|
289
|
+
observer.complete()
|
|
290
|
+
},
|
|
291
|
+
timeout ? {timeout} : undefined
|
|
292
|
+
)
|
|
228
293
|
|
|
229
|
-
|
|
294
|
+
return () => cancelIdleCallback(handle)
|
|
295
|
+
})
|
|
230
296
|
}
|
|
@@ -23,7 +23,7 @@ function serializePath(path: Path): string {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
const defaultIsUnique: SlugIsUniqueValidator = (slug, context) => {
|
|
26
|
-
const {
|
|
26
|
+
const {getClient, document, path, type} = context
|
|
27
27
|
const schemaOptions = type?.options as {disableArrayWarning?: boolean} | undefined
|
|
28
28
|
|
|
29
29
|
if (!document) {
|
|
@@ -48,7 +48,7 @@ const defaultIsUnique: SlugIsUniqueValidator = (slug, context) => {
|
|
|
48
48
|
`${atPath} == $slug`,
|
|
49
49
|
].join(' && ')
|
|
50
50
|
|
|
51
|
-
return
|
|
51
|
+
return getClient({apiVersion: '2022-09-09'}).fetch<boolean>(
|
|
52
52
|
`!defined(*[${constraints}][0]._id)`,
|
|
53
53
|
{
|
|
54
54
|
docType,
|