@sanity/agent-schema 0.2.0 → 0.3.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/dist/_chunks-es/{navigateToField.js → walkTree.js} +40 -2
- package/dist/_chunks-es/walkTree.js.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/validation/index.d.ts +51 -2
- package/dist/validation/index.d.ts.map +1 -1
- package/dist/validation/index.js +158 -9
- package/dist/validation/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/_chunks-es/navigateToField.js.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { a as ValidateValueFn, c as ValidationErrorCode, h as ManifestSchemaType, i as PatchOperations, l as ValidationResult, n as InsertOperation, o as ValidationContext, r as LocalizationConfig, s as ValidationError, t as FieldSchemaLookupResult } from "../_chunks-dts/types.js";
|
|
1
|
+
import { a as ValidateValueFn, c as ValidationErrorCode, h as ManifestSchemaType, i as PatchOperations, l as ValidationResult, m as ManifestField, n as InsertOperation, o as ValidationContext, r as LocalizationConfig, s as ValidationError, t as FieldSchemaLookupResult } from "../_chunks-dts/types.js";
|
|
2
|
+
import { SanityClient } from "@sanity/client";
|
|
2
3
|
/**
|
|
3
4
|
* Validate an array value and its items.
|
|
4
5
|
*/
|
|
@@ -9,6 +10,11 @@ declare function validateArray(value: unknown, fieldSchema: ManifestSchemaType,
|
|
|
9
10
|
* against the existing document state.
|
|
10
11
|
*/
|
|
11
12
|
declare function validateUniqueItems(newItems: unknown[], existingArray: unknown[], pathPrefix: string, errors: ValidationError[]): void;
|
|
13
|
+
/**
|
|
14
|
+
* Return paths of fields with custom validators on the document type.
|
|
15
|
+
* Document-level custom validators are reported at `(document)`.
|
|
16
|
+
*/
|
|
17
|
+
declare function detectCustomValidators(documentType: string, schema: ManifestSchemaType[]): string[];
|
|
12
18
|
interface PathResolutionResult {
|
|
13
19
|
/** The resolved field schema, or null if not found */
|
|
14
20
|
schema: ManifestSchemaType | null;
|
|
@@ -162,6 +168,20 @@ declare function getValidImageMetadataFields(imagePath: string, typeSchema: Mani
|
|
|
162
168
|
* @returns Object with schemas array and any validation errors
|
|
163
169
|
*/
|
|
164
170
|
declare function getFieldSchemaAtPath(path: string, documentType: string, schema: ManifestSchemaType[], existingDocument?: Record<string, unknown>): FieldSchemaLookupResult;
|
|
171
|
+
/**
|
|
172
|
+
* Whether the field at `path` is an image field.
|
|
173
|
+
*
|
|
174
|
+
* Resolves the path via getFieldSchemaAtPath — handling array items, union
|
|
175
|
+
* arrays, named-type indirection, and document-based resolution — and returns
|
|
176
|
+
* true when any resolved schema is an `image` type. Boolean counterpart to
|
|
177
|
+
* validateImagePath, for callers that just need a yes/no answer.
|
|
178
|
+
*
|
|
179
|
+
* @param path - Dot-notation path to the field
|
|
180
|
+
* @param documentType - The document type name
|
|
181
|
+
* @param schema - Full schema array
|
|
182
|
+
* @param existingDocument - Optional document for dynamic path resolution
|
|
183
|
+
*/
|
|
184
|
+
declare function isImageFieldAtPath(path: string, documentType: string, schema: ManifestSchemaType[], existingDocument?: Record<string, unknown>): boolean;
|
|
165
185
|
/**
|
|
166
186
|
* Validate that a path points to an image field.
|
|
167
187
|
*
|
|
@@ -212,6 +232,19 @@ declare function validateSchemaRules(value: unknown, fieldSchema: ManifestSchema
|
|
|
212
232
|
* Checks structure and optionally validates existence via client.
|
|
213
233
|
*/
|
|
214
234
|
declare function validateReference(value: unknown, fieldSchema: ManifestSchemaType, path: string, errors: ValidationError[], context: ValidationContext): Promise<void>;
|
|
235
|
+
declare function validateRequiredFields(document: Record<string, unknown>, documentType: string, schema: ManifestSchemaType[]): ValidationError[];
|
|
236
|
+
/** True when the field has an error-level required validator. */
|
|
237
|
+
declare const hasRequiredValidator: (field: ManifestField | ManifestSchemaType) => boolean;
|
|
238
|
+
/** True when the field has a `Rule.custom(...)` validator at any level. */
|
|
239
|
+
declare const hasCustomValidator: (field: ManifestField | ManifestSchemaType) => boolean;
|
|
240
|
+
/**
|
|
241
|
+
* Check whether the slug values on a draft collide with any other document in
|
|
242
|
+
* the dataset (excluding the draft and its published twin).
|
|
243
|
+
*/
|
|
244
|
+
declare function validateSlugCollisions(document: Record<string, unknown>, documentType: string, schema: ManifestSchemaType[], client: SanityClient, ids: {
|
|
245
|
+
publishedId: string;
|
|
246
|
+
draftId: string;
|
|
247
|
+
}): Promise<ValidationError[]>;
|
|
215
248
|
/**
|
|
216
249
|
* Validate a slug value.
|
|
217
250
|
*/
|
|
@@ -282,5 +315,21 @@ declare function formatValidationErrors(errors: ValidationError[]): string;
|
|
|
282
315
|
* This is the core recursive validator that dispatches to type-specific validators.
|
|
283
316
|
*/
|
|
284
317
|
declare function validateValue(value: unknown, fieldSchema: ManifestSchemaType, path: string, errors: ValidationError[], context: ValidationContext, schema: ManifestSchemaType[], warnings?: ValidationError[]): Promise<void>;
|
|
285
|
-
|
|
318
|
+
type ValidateForPublishInput = {
|
|
319
|
+
document: Record<string, unknown>;
|
|
320
|
+
documentType: string;
|
|
321
|
+
schema: ManifestSchemaType[];
|
|
322
|
+
client: SanityClient;
|
|
323
|
+
publishedId: string;
|
|
324
|
+
draftId: string;
|
|
325
|
+
};
|
|
326
|
+
declare function validateForPublish({
|
|
327
|
+
document,
|
|
328
|
+
documentType,
|
|
329
|
+
schema,
|
|
330
|
+
client,
|
|
331
|
+
publishedId,
|
|
332
|
+
draftId
|
|
333
|
+
}: ValidateForPublishInput): Promise<ValidationResult>;
|
|
334
|
+
export { type FieldSchemaLookupResult, type InsertOperation, type LocalizationConfig, type PatchOperations, type ValidateValueFn, type ValidationContext, type ValidationError, type ValidationErrorCode, type ValidationResult, createError, detectCustomValidators, formatValidationErrors, formatValue, getActualJsType, getExpectedJsType, getFieldSchemaAtPath, getUniquenessKey, getValidImageMetadataFields, getValueAtPath, hasCustomValidator, hasRequiredValidator, isImageFieldAtPath, isInternationalizedArrayField, isV5InternationalizedArray, resolveFieldSchemaAtPath, validateArray, validateBlock, validateDocumentLanguageField, validateFieldLevelLanguageField, validateFieldLevelLanguageKey, validateFile, validateForPublish, validateGeopoint, validateImage, validateImageMetadata, validateImagePath, validateInternationalizedArrayItems, validateInternationalizedArraySet, validateNoExtraProperties, validateObject, validatePrimitive, validateReference, validateRequiredFields, validateSchemaRules, validateSlug, validateSlugCollisions, validateUniqueItems, validateValue };
|
|
286
335
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/validation/array.validator.ts","../../src/validation/document-path-resolver.ts","../../src/validation/language.validator.ts","../../src/validation/object.validator.ts","../../src/validation/path-validation.ts","../../src/validation/portable-text.validator.ts","../../src/validation/primitive.validator.ts","../../src/validation/reference.validator.ts","../../src/validation/special-types.validator.ts","../../src/validation/utils.ts","../../src/validation/validate-value.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/validation/array.validator.ts","../../src/validation/customValidators.ts","../../src/validation/document-path-resolver.ts","../../src/validation/language.validator.ts","../../src/validation/object.validator.ts","../../src/validation/path-validation.ts","../../src/validation/portable-text.validator.ts","../../src/validation/primitive.validator.ts","../../src/validation/reference.validator.ts","../../src/validation/requiredFields.ts","../../src/validation/rules.ts","../../src/validation/slugCollisions.ts","../../src/validation/special-types.validator.ts","../../src/validation/utils.ts","../../src/validation/validate-value.ts","../../src/validation/validateForPublish.ts"],"mappings":"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"}
|
package/dist/validation/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isPrimitiveType, resolveFieldSchema, BUILT_IN_TYPE_FIELDS, resolveFieldSchemaAllUnions } from "../_chunks-es/
|
|
1
|
+
import { isPrimitiveType, walkSchemaTree, resolveFieldSchema, BUILT_IN_TYPE_FIELDS, resolveFieldSchemaAllUnions, joinSchemaPath } from "../_chunks-es/walkTree.js";
|
|
2
2
|
function createError(path, code, message, received, expected, fix) {
|
|
3
3
|
return { path, code, message, received, expected, fix };
|
|
4
4
|
}
|
|
@@ -152,10 +152,10 @@ async function validateArray(value, fieldSchema, path, schema, errors, context,
|
|
|
152
152
|
(t) => !t.name && isPrimitiveType(t.type)
|
|
153
153
|
), seenKeys = /* @__PURE__ */ new Set();
|
|
154
154
|
for (let i = 0; i < value.length; i++) {
|
|
155
|
-
const item = value[i],
|
|
155
|
+
const item = value[i], itemPath2 = `${path}[${i}]`, errorCountBefore = errors.length, itemObj = item, itemType = itemObj?._type, itemKey = itemObj?._key;
|
|
156
156
|
!isPrimitiveArray && typeof item == "object" && item !== null && (itemKey === void 0 ? errors.push(
|
|
157
157
|
createError(
|
|
158
|
-
|
|
158
|
+
itemPath2,
|
|
159
159
|
"ARRAY_ITEM_INVALID",
|
|
160
160
|
'Object array item missing "_key" property',
|
|
161
161
|
formatValue(item),
|
|
@@ -164,7 +164,7 @@ async function validateArray(value, fieldSchema, path, schema, errors, context,
|
|
|
164
164
|
)
|
|
165
165
|
) : typeof itemKey == "string" && itemKey !== "" && (seenKeys.has(itemKey) ? errors.push(
|
|
166
166
|
createError(
|
|
167
|
-
`${
|
|
167
|
+
`${itemPath2}._key`,
|
|
168
168
|
"ARRAY_ITEM_INVALID",
|
|
169
169
|
`duplicate _key "${itemKey}" in array`,
|
|
170
170
|
itemKey,
|
|
@@ -200,7 +200,7 @@ async function validateArray(value, fieldSchema, path, schema, errors, context,
|
|
|
200
200
|
if (!isPrimitiveArray && (typeof item == "string" || typeof item == "number" || typeof item == "boolean" || item === null)) {
|
|
201
201
|
errors.push(
|
|
202
202
|
createError(
|
|
203
|
-
|
|
203
|
+
itemPath2,
|
|
204
204
|
"TYPE_MISMATCH",
|
|
205
205
|
"Expected object but found primitive in array",
|
|
206
206
|
formatValue(item),
|
|
@@ -213,7 +213,7 @@ async function validateArray(value, fieldSchema, path, schema, errors, context,
|
|
|
213
213
|
const namedTypes = itemTypes.filter((t) => t.name);
|
|
214
214
|
namedTypes.length > 0 && itemType ? errors.push(
|
|
215
215
|
createError(
|
|
216
|
-
|
|
216
|
+
itemPath2,
|
|
217
217
|
"ARRAY_ITEM_INVALID",
|
|
218
218
|
`Wrong _type "${itemType}" for array item`,
|
|
219
219
|
formatValue(item),
|
|
@@ -222,7 +222,7 @@ async function validateArray(value, fieldSchema, path, schema, errors, context,
|
|
|
222
222
|
)
|
|
223
223
|
) : errors.push(
|
|
224
224
|
createError(
|
|
225
|
-
|
|
225
|
+
itemPath2,
|
|
226
226
|
"ARRAY_ITEM_INVALID",
|
|
227
227
|
itemType ? `Unknown array item type: ${itemType}` : "Invalid array item",
|
|
228
228
|
formatValue(item),
|
|
@@ -232,7 +232,7 @@ async function validateArray(value, fieldSchema, path, schema, errors, context,
|
|
|
232
232
|
), tagItemErrors(errors, errorCountBefore, i, path);
|
|
233
233
|
continue;
|
|
234
234
|
}
|
|
235
|
-
await validateValue2(item, matchingSchema,
|
|
235
|
+
await validateValue2(item, matchingSchema, itemPath2, errors, context, schema), tagItemErrors(errors, errorCountBefore, i, path);
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
238
|
function tagItemErrors(errors, startIndex, itemIndex, arrayPath) {
|
|
@@ -267,6 +267,17 @@ function validateUniqueItems(newItems, existingArray, pathPrefix, errors) {
|
|
|
267
267
|
), newKeys.add(uniquenessKey);
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
|
+
const isRequiredRule = (rule) => rule.type === "required" || rule.flag === "presence" && rule.constraint === "required", isCustomRule = (rule) => rule.type === "custom" || rule.flag === "custom", matchesAnyRule = (field, predicate, errorLevelOnly) => (field.validation ?? []).some(
|
|
271
|
+
(group) => (!errorLevelOnly || (group.level ?? "error") === "error") && (group.rules ?? []).some((rule) => predicate(rule))
|
|
272
|
+
), hasRequiredValidator = (field) => matchesAnyRule(field, isRequiredRule, !0), hasCustomValidator = (field) => matchesAnyRule(field, isCustomRule, !1);
|
|
273
|
+
function detectCustomValidators(documentType, schema) {
|
|
274
|
+
const typeSchema = schema.find((s) => s.name === documentType);
|
|
275
|
+
if (!typeSchema) return [];
|
|
276
|
+
const paths = [];
|
|
277
|
+
return hasCustomValidator(typeSchema) && paths.push("(document)"), walkSchemaTree(documentType, schema, (field, path) => {
|
|
278
|
+
hasCustomValidator(field) && paths.push(path);
|
|
279
|
+
}), paths;
|
|
280
|
+
}
|
|
270
281
|
function pathHasArraySelectors(path) {
|
|
271
282
|
return /\[(_key==|[0-9])/.test(path);
|
|
272
283
|
}
|
|
@@ -697,6 +708,10 @@ function getFieldSchemaAtPath(path, documentType, schema, existingDocument) {
|
|
|
697
708
|
}
|
|
698
709
|
return { schemas: fieldSchemas, errors: [] };
|
|
699
710
|
}
|
|
711
|
+
function isImageFieldAtPath(path, documentType, schema, existingDocument) {
|
|
712
|
+
const { schemas, errors } = getFieldSchemaAtPath(path, documentType, schema, existingDocument);
|
|
713
|
+
return errors.length > 0 || !schemas?.length ? !1 : schemas.some((s) => s.type === "image");
|
|
714
|
+
}
|
|
700
715
|
function validateImagePath(path, documentType, schema, existingDocument) {
|
|
701
716
|
const { schemas, errors } = getFieldSchemaAtPath(path, documentType, schema, existingDocument);
|
|
702
717
|
if (errors.length > 0)
|
|
@@ -716,7 +731,7 @@ function validateImagePath(path, documentType, schema, existingDocument) {
|
|
|
716
731
|
)
|
|
717
732
|
]
|
|
718
733
|
};
|
|
719
|
-
if (!
|
|
734
|
+
if (!isImageFieldAtPath(path, documentType, schema, existingDocument)) {
|
|
720
735
|
const types = schemas.map((s) => s.type || "unknown").join(", ");
|
|
721
736
|
return {
|
|
722
737
|
valid: !1,
|
|
@@ -1533,6 +1548,95 @@ async function validateReference(value, fieldSchema, path, errors, context) {
|
|
|
1533
1548
|
} catch {
|
|
1534
1549
|
}
|
|
1535
1550
|
}
|
|
1551
|
+
const isPlainObject$1 = (value) => typeof value == "object" && value !== null && !Array.isArray(value), isMissing = (value) => value == null ? !0 : typeof value == "string" || Array.isArray(value) ? value.length === 0 : !1, missingRequiredError = (path, field) => createError(
|
|
1552
|
+
path,
|
|
1553
|
+
"REQUIRED_FIELD_MISSING",
|
|
1554
|
+
`Required field "${field.name}" is missing`,
|
|
1555
|
+
formatValue(void 0),
|
|
1556
|
+
`${field.title ?? field.name} (${field.type})`,
|
|
1557
|
+
`Set a value for "${field.name}" before publishing`
|
|
1558
|
+
), itemPath = (parent, item, index) => {
|
|
1559
|
+
const key = item._key;
|
|
1560
|
+
return typeof key == "string" ? `${parent}[_key=="${key}"]` : `${parent}[${index}]`;
|
|
1561
|
+
}, resolveItemFields = (itemSchema, schema) => itemSchema.fields?.length ? itemSchema.fields : !itemSchema.type || isPrimitiveType(itemSchema.type) ? void 0 : schema.find((s) => s.name === itemSchema.type)?.fields;
|
|
1562
|
+
function walkArray(field, value, path, schema, errors) {
|
|
1563
|
+
if (field.of?.length)
|
|
1564
|
+
for (let index = 0; index < value.length; index++) {
|
|
1565
|
+
const item = value[index];
|
|
1566
|
+
if (!isPlainObject$1(item)) continue;
|
|
1567
|
+
const matched = field.of.find((member) => member.type === item._type) ?? field.of[0], itemFields = resolveItemFields(matched, schema);
|
|
1568
|
+
itemFields?.length && walkFields(itemFields, item, itemPath(path, item, index), schema, errors);
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
function walkFields(fields, value, path, schema, errors) {
|
|
1572
|
+
const obj = isPlainObject$1(value) ? value : {};
|
|
1573
|
+
for (const field of fields) {
|
|
1574
|
+
const fieldValue = obj[field.name], fieldPath = joinSchemaPath(path, field.name);
|
|
1575
|
+
if (hasRequiredValidator(field) && isMissing(fieldValue)) {
|
|
1576
|
+
errors.push(missingRequiredError(fieldPath, field));
|
|
1577
|
+
continue;
|
|
1578
|
+
}
|
|
1579
|
+
if (isMissing(fieldValue)) continue;
|
|
1580
|
+
if (Array.isArray(fieldValue)) {
|
|
1581
|
+
walkArray(field, fieldValue, fieldPath, schema, errors);
|
|
1582
|
+
continue;
|
|
1583
|
+
}
|
|
1584
|
+
if (field.fields?.length) {
|
|
1585
|
+
walkFields(field.fields, fieldValue, fieldPath, schema, errors);
|
|
1586
|
+
continue;
|
|
1587
|
+
}
|
|
1588
|
+
if (!field.type || isPrimitiveType(field.type)) continue;
|
|
1589
|
+
const referenced = schema.find((s) => s.name === field.type);
|
|
1590
|
+
referenced?.fields?.length && walkFields(referenced.fields, fieldValue, fieldPath, schema, errors);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
function validateRequiredFields(document, documentType, schema) {
|
|
1594
|
+
const typeSchema = schema.find((s) => s.name === documentType);
|
|
1595
|
+
if (!typeSchema?.fields?.length) return [];
|
|
1596
|
+
const errors = [];
|
|
1597
|
+
return walkFields(typeSchema.fields, document, "", schema, errors), errors;
|
|
1598
|
+
}
|
|
1599
|
+
const isPlainObject = (value) => typeof value == "object" && value !== null && !Array.isArray(value), isSlugType = (field, schema) => field.type === "slug" ? !0 : schema.find((s) => s.name === field.type)?.type === "slug", hasCustomIsUnique = (field) => {
|
|
1600
|
+
const isUnique = field.options?.isUnique;
|
|
1601
|
+
return isPlainObject(isUnique) && isUnique.__type === "function";
|
|
1602
|
+
}, readSlugCurrent = (value) => {
|
|
1603
|
+
if (!isPlainObject(value)) return;
|
|
1604
|
+
const current = value.current;
|
|
1605
|
+
return typeof current == "string" && current.length > 0 ? current : void 0;
|
|
1606
|
+
};
|
|
1607
|
+
function collectSlugFields(document, documentType, schema) {
|
|
1608
|
+
const typeSchema = schema.find((s) => s.name === documentType);
|
|
1609
|
+
if (!typeSchema?.fields?.length) return [];
|
|
1610
|
+
const out = [];
|
|
1611
|
+
for (const field of typeSchema.fields) {
|
|
1612
|
+
if (!isSlugType(field, schema)) continue;
|
|
1613
|
+
const current = readSlugCurrent(document[field.name]);
|
|
1614
|
+
current !== void 0 && out.push({ path: field.name, field, current });
|
|
1615
|
+
}
|
|
1616
|
+
return out;
|
|
1617
|
+
}
|
|
1618
|
+
const collisionError = (path, current, conflictingId) => createError(
|
|
1619
|
+
`${path}.current`,
|
|
1620
|
+
"INVALID_FORMAT",
|
|
1621
|
+
`Slug "${current}" is already in use by another document`,
|
|
1622
|
+
formatValue(current),
|
|
1623
|
+
"A slug not used by any other document",
|
|
1624
|
+
`Choose a different slug for "${path}". The conflicting document is "${conflictingId}".`
|
|
1625
|
+
);
|
|
1626
|
+
async function validateSlugCollisions(document, documentType, schema, client, ids) {
|
|
1627
|
+
const slugs = collectSlugFields(document, documentType, schema);
|
|
1628
|
+
return slugs.length === 0 ? [] : (await Promise.all(
|
|
1629
|
+
slugs.map(async ({ path, field, current }) => {
|
|
1630
|
+
if (hasCustomIsUnique(field)) return;
|
|
1631
|
+
const query = `*[!(_id in [$publishedId, $draftId]) && ${path}.current == $slug][0]._id`, conflictingId = await client.fetch(query, {
|
|
1632
|
+
publishedId: ids.publishedId,
|
|
1633
|
+
draftId: ids.draftId,
|
|
1634
|
+
slug: current
|
|
1635
|
+
});
|
|
1636
|
+
return conflictingId ? collisionError(path, current, conflictingId) : void 0;
|
|
1637
|
+
})
|
|
1638
|
+
)).filter((e) => e !== void 0);
|
|
1639
|
+
}
|
|
1536
1640
|
function validateSlug(value, path, errors) {
|
|
1537
1641
|
if (typeof value != "object" || value === null) {
|
|
1538
1642
|
errors.push(
|
|
@@ -1882,8 +1986,47 @@ async function validateValue(value, fieldSchema, path, errors, context, schema,
|
|
|
1882
1986
|
}
|
|
1883
1987
|
}
|
|
1884
1988
|
}
|
|
1989
|
+
async function validateForPublish({
|
|
1990
|
+
document,
|
|
1991
|
+
documentType,
|
|
1992
|
+
schema,
|
|
1993
|
+
client,
|
|
1994
|
+
publishedId,
|
|
1995
|
+
draftId
|
|
1996
|
+
}) {
|
|
1997
|
+
const typeSchema = schema.find((s) => s.name === documentType);
|
|
1998
|
+
if (!typeSchema)
|
|
1999
|
+
return {
|
|
2000
|
+
valid: !1,
|
|
2001
|
+
errors: [
|
|
2002
|
+
createError(
|
|
2003
|
+
"_type",
|
|
2004
|
+
"FIELD_NOT_IN_SCHEMA",
|
|
2005
|
+
`Document type "${documentType}" not found in schema`,
|
|
2006
|
+
documentType,
|
|
2007
|
+
"Valid document type",
|
|
2008
|
+
"Check the schema for valid document type names"
|
|
2009
|
+
)
|
|
2010
|
+
],
|
|
2011
|
+
warnings: []
|
|
2012
|
+
};
|
|
2013
|
+
const structuralErrors = [], [, slugs] = await Promise.all([
|
|
2014
|
+
validateObject(
|
|
2015
|
+
document,
|
|
2016
|
+
typeSchema,
|
|
2017
|
+
"",
|
|
2018
|
+
schema,
|
|
2019
|
+
structuralErrors,
|
|
2020
|
+
{ documentType, client },
|
|
2021
|
+
validateValue
|
|
2022
|
+
),
|
|
2023
|
+
validateSlugCollisions(document, documentType, schema, client, { publishedId, draftId })
|
|
2024
|
+
]), required = validateRequiredFields(document, documentType, schema), errors = [...structuralErrors, ...required, ...slugs];
|
|
2025
|
+
return { valid: errors.length === 0, errors, warnings: [] };
|
|
2026
|
+
}
|
|
1885
2027
|
export {
|
|
1886
2028
|
createError,
|
|
2029
|
+
detectCustomValidators,
|
|
1887
2030
|
formatValidationErrors,
|
|
1888
2031
|
formatValue,
|
|
1889
2032
|
getActualJsType,
|
|
@@ -1892,6 +2035,9 @@ export {
|
|
|
1892
2035
|
getUniquenessKey,
|
|
1893
2036
|
getValidImageMetadataFields,
|
|
1894
2037
|
getValueAtPath,
|
|
2038
|
+
hasCustomValidator,
|
|
2039
|
+
hasRequiredValidator,
|
|
2040
|
+
isImageFieldAtPath,
|
|
1895
2041
|
isInternationalizedArrayField,
|
|
1896
2042
|
isV5InternationalizedArray,
|
|
1897
2043
|
resolveFieldSchemaAtPath,
|
|
@@ -1901,6 +2047,7 @@ export {
|
|
|
1901
2047
|
validateFieldLevelLanguageField,
|
|
1902
2048
|
validateFieldLevelLanguageKey,
|
|
1903
2049
|
validateFile,
|
|
2050
|
+
validateForPublish,
|
|
1904
2051
|
validateGeopoint,
|
|
1905
2052
|
validateImage,
|
|
1906
2053
|
validateImageMetadata,
|
|
@@ -1911,8 +2058,10 @@ export {
|
|
|
1911
2058
|
validateObject,
|
|
1912
2059
|
validatePrimitive,
|
|
1913
2060
|
validateReference,
|
|
2061
|
+
validateRequiredFields,
|
|
1914
2062
|
validateSchemaRules,
|
|
1915
2063
|
validateSlug,
|
|
2064
|
+
validateSlugCollisions,
|
|
1916
2065
|
validateUniqueItems,
|
|
1917
2066
|
validateValue
|
|
1918
2067
|
};
|