@sanity/agent-schema 0.1.0 → 0.3.0

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.
@@ -0,0 +1,266 @@
1
+ import { SanityClient } from "@sanity/client";
2
+ import { z } from "zod";
3
+ import { LexiconResponse } from "@sanity/schema-descriptor-utils";
4
+ type ManifestSerializable = string | number | boolean | {
5
+ [k: string]: ManifestSerializable;
6
+ } | ManifestSerializable[];
7
+ type ManifestSchemaType = {
8
+ type: string;
9
+ name: string;
10
+ title?: string;
11
+ description?: string;
12
+ deprecated?: {
13
+ reason: string;
14
+ };
15
+ readOnly?: boolean | 'conditional';
16
+ hidden?: boolean | 'conditional';
17
+ validation?: ManifestValidationGroup[];
18
+ fields?: ManifestField[];
19
+ to?: ManifestReferenceMember[];
20
+ of?: ManifestArrayMember[];
21
+ preview?: {
22
+ select: Record<string, string>;
23
+ };
24
+ fieldsets?: ManifestFieldset[];
25
+ options?: Record<string, ManifestSerializable>;
26
+ marks?: {
27
+ annotations?: ManifestArrayMember[];
28
+ decorators?: ManifestTitledValue[];
29
+ };
30
+ lists?: ManifestTitledValue[];
31
+ styles?: ManifestTitledValue[];
32
+ [index: string]: unknown;
33
+ };
34
+ type ManifestFieldset = {
35
+ name: string;
36
+ title?: string;
37
+ [index: string]: ManifestSerializable | undefined;
38
+ };
39
+ type ManifestTitledValue = {
40
+ value: string;
41
+ title?: string;
42
+ };
43
+ type ManifestField = ManifestSchemaType & {
44
+ fieldset?: string;
45
+ };
46
+ type ManifestArrayMember = Omit<ManifestSchemaType, 'name'> & {
47
+ name?: string;
48
+ };
49
+ type ManifestReferenceMember = Omit<ManifestSchemaType, 'name'> & {
50
+ name?: string;
51
+ };
52
+ type ManifestValidationGroup = {
53
+ rules: ManifestValidationRule[];
54
+ message?: string;
55
+ level?: 'error' | 'warning' | 'info';
56
+ };
57
+ type ManifestValidationRule = {
58
+ flag: 'presence' | string;
59
+ constraint?: 'required' | ManifestSerializable;
60
+ [index: string]: ManifestSerializable | undefined;
61
+ };
62
+ declare const DatasetStatsSchema: z.ZodObject<{
63
+ documentCount: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
64
+ referenceCount: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
65
+ incoming: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"unknown">]>>;
66
+ outgoing: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"unknown">]>>;
67
+ }, "strip", z.ZodTypeAny, {
68
+ incoming: Record<string, number | "unknown">;
69
+ outgoing: Record<string, number | "unknown">;
70
+ }, {
71
+ incoming: Record<string, number | "unknown">;
72
+ outgoing: Record<string, number | "unknown">;
73
+ }>>>;
74
+ }, "strip", z.ZodTypeAny, {
75
+ documentCount?: Record<string, number> | undefined;
76
+ referenceCount?: Record<string, {
77
+ incoming: Record<string, number | "unknown">;
78
+ outgoing: Record<string, number | "unknown">;
79
+ }> | undefined;
80
+ }, {
81
+ documentCount?: Record<string, number> | undefined;
82
+ referenceCount?: Record<string, {
83
+ incoming: Record<string, number | "unknown">;
84
+ outgoing: Record<string, number | "unknown">;
85
+ }> | undefined;
86
+ }>;
87
+ type DatasetStats = z.infer<typeof DatasetStatsSchema>;
88
+ type ReferenceInfo = {
89
+ type: string;
90
+ path: string;
91
+ };
92
+ type ProcessedDocumentType = {
93
+ name: string;
94
+ title?: string;
95
+ description?: string;
96
+ deprecated?: {
97
+ reason: string;
98
+ };
99
+ liveEdit?: boolean;
100
+ titleField: string;
101
+ fields: ManifestField[];
102
+ outgoingReferences: string[];
103
+ incomingReferences: string[];
104
+ outgoingReferencePaths?: ReferenceInfo[];
105
+ incomingReferencePaths?: ReferenceInfo[];
106
+ };
107
+ type SchemaTypes = {
108
+ documentTypes: Map<string, ProcessedDocumentType>;
109
+ objectTypes: Map<string, ManifestSchemaType>;
110
+ };
111
+ /**
112
+ * Filter document types by GROQ expressions or an explicit list.
113
+ * - `{ read?, write? }` — GROQ boolean expressions (requires groq-js peer dep).
114
+ * Types matching either expression are included (union).
115
+ * - `string[]` — explicit list of document type names to include.
116
+ * - `undefined` / empty — include all document types.
117
+ */
118
+ type SchemaFilter = {
119
+ read?: string;
120
+ write?: string;
121
+ } | string[];
122
+ type SchemaFieldDisplayOptions = {
123
+ showAll?: boolean;
124
+ maxCount?: number;
125
+ includeDescription?: boolean;
126
+ includeHidden?: boolean;
127
+ includeDeprecated?: boolean;
128
+ maxEnumValues?: number;
129
+ maxDescriptionLength?: number;
130
+ };
131
+ type CompressedSchemaOptions = {
132
+ datasetStats?: DatasetStats;
133
+ filter?: SchemaFilter;
134
+ fields?: SchemaFieldDisplayOptions;
135
+ /**
136
+ * When `true`, document types with `documentCount === 0` are still rendered
137
+ * (and their references fall back to the count-less format, since all edges
138
+ * would be zero anyway). Default `false` preserves the existing behavior of
139
+ * dropping empty types when `datasetStats` is provided.
140
+ */
141
+ includeEmpty?: boolean;
142
+ };
143
+ type SchemaProcessorOptions = {
144
+ filter?: SchemaFilter;
145
+ fields?: SchemaFieldDisplayOptions;
146
+ };
147
+ /** Insert operation structure for patch operations. */
148
+ interface InsertOperation {
149
+ arrayPath: string;
150
+ key: string;
151
+ items: unknown[];
152
+ }
153
+ /** Localization configuration for document-level and field-level translations. */
154
+ type LocalizationConfig = {
155
+ isFieldLevel: boolean;
156
+ isDocumentLevel: boolean;
157
+ isUnknown: boolean;
158
+ fieldLevel: {
159
+ languages: Array<{
160
+ id: string;
161
+ title: string | null;
162
+ }>;
163
+ pluginVersion: 'v4' | 'v5';
164
+ isV5: boolean;
165
+ } | null;
166
+ documentLevel: {
167
+ languageField: string | null;
168
+ currentLanguage: string | null;
169
+ existingTranslations: Array<{
170
+ locale: string;
171
+ documentId: string | null;
172
+ }>;
173
+ availableLanguages: string[];
174
+ pluginVersion: 'v4' | 'v5';
175
+ } | null;
176
+ };
177
+ /**
178
+ * Error codes for validation errors.
179
+ * Used for programmatic handling of specific error types.
180
+ */
181
+ type ValidationErrorCode = 'TYPE_MISMATCH' | 'REQUIRED_FIELD_MISSING' | 'FIELD_NOT_IN_SCHEMA' | 'INVALID_FORMAT' | 'INVALID_REFERENCE' | 'REFERENCE_NOT_FOUND' | 'REFERENCE_WRONG_TYPE' | 'ARRAY_ITEM_INVALID' | 'VALUE_OUT_OF_RANGE' | 'INVALID_ENUM_VALUE' | 'DUPLICATE_ARRAY_ITEM' | 'INVALID_IMAGE_PATH' | 'IMAGE_NOT_FOUND' | 'INVALID_MARK_REFERENCE' | 'INVALID_PATH' | 'INVALID_LANGUAGE';
182
+ /**
183
+ * A validation error with actionable information.
184
+ *
185
+ * Error messages follow the format:
186
+ * At path "{path}": {message}
187
+ * Received: {received}
188
+ * Expected: {expected}
189
+ * Fix: {fix}
190
+ */
191
+ interface ValidationError {
192
+ /** Field path (e.g., "author.name", "tags[0]") */
193
+ path: string;
194
+ /** Error code for programmatic handling */
195
+ code: ValidationErrorCode;
196
+ /** Human-readable error message */
197
+ message: string;
198
+ /** String representation of actual value received */
199
+ received: string;
200
+ /** Description of expected value */
201
+ expected: string;
202
+ /** Actionable fix advice */
203
+ fix: string;
204
+ /** When set, this error is for a specific item in an array and can be resolved by filtering that item */
205
+ itemIndex?: number;
206
+ /** The array field path this item belongs to (e.g., "content") — set alongside itemIndex */
207
+ arrayPath?: string;
208
+ }
209
+ /**
210
+ * Result of a validation operation.
211
+ */
212
+ interface ValidationResult {
213
+ /** Whether validation passed with no errors */
214
+ valid: boolean;
215
+ /** List of validation errors (empty if valid) */
216
+ errors: ValidationError[];
217
+ /** List of warning-level validation issues (non-blocking) */
218
+ warnings: ValidationError[];
219
+ }
220
+ /**
221
+ * Context for validation operations.
222
+ */
223
+ interface ValidationContext {
224
+ /** The document type name */
225
+ documentType: string;
226
+ /** Target document ID (for reference validation in drafts) */
227
+ targetDocumentId?: string;
228
+ /** Existing document state (for patch operations) */
229
+ existingDocument?: Record<string, unknown>;
230
+ /** Sanity client for reference existence checks */
231
+ client?: SanityClient;
232
+ /** Localization config for language field validation */
233
+ localizationConfig?: LocalizationConfig;
234
+ }
235
+ /**
236
+ * Patch operations structure from patch.tool.ts
237
+ */
238
+ interface PatchOperations {
239
+ set?: Array<{
240
+ path: string;
241
+ value?: unknown;
242
+ }>;
243
+ unset?: string[];
244
+ append?: Array<{
245
+ path: string;
246
+ items: unknown[];
247
+ }>;
248
+ insertBefore?: InsertOperation[];
249
+ insertAfter?: InsertOperation[];
250
+ }
251
+ /**
252
+ * Result of field schema lookup at a path.
253
+ */
254
+ interface FieldSchemaLookupResult {
255
+ /** All possible schemas at the path (for union types in arrays) */
256
+ schemas: ManifestSchemaType[] | null;
257
+ /** Validation errors if path is invalid */
258
+ errors: ValidationError[];
259
+ }
260
+ /**
261
+ * Type for the recursive validateValue function.
262
+ * Used to pass validateValue to validators that need recursion.
263
+ */
264
+ type ValidateValueFn = (value: unknown, fieldSchema: ManifestSchemaType, path: string, errors: ValidationError[], context: ValidationContext, schema: ManifestSchemaType[], warnings?: ValidationError[]) => Promise<void>;
265
+ export { SchemaFieldDisplayOptions as _, ValidateValueFn as a, SchemaTypes as b, ValidationErrorCode as c, DatasetStats as d, DatasetStatsSchema as f, ProcessedDocumentType as g, ManifestSchemaType as h, PatchOperations as i, ValidationResult as l, ManifestField as m, InsertOperation as n, ValidationContext as o, LexiconResponse as p, LocalizationConfig as r, ValidationError as s, FieldSchemaLookupResult as t, CompressedSchemaOptions as u, SchemaFilter as v, SchemaProcessorOptions as y };
266
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/types.ts","../../src/validation/types.ts"],"mappings":"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"}
@@ -0,0 +1,312 @@
1
+ const BUILT_IN_TYPE_FIELDS = {
2
+ slug: {
3
+ current: { name: "current", type: "string" },
4
+ _type: { name: "_type", type: "string" }
5
+ },
6
+ geopoint: {
7
+ lat: { name: "lat", type: "number" },
8
+ lng: { name: "lng", type: "number" },
9
+ alt: { name: "alt", type: "number" },
10
+ _type: { name: "_type", type: "string" }
11
+ },
12
+ reference: {
13
+ _ref: { name: "_ref", type: "string" },
14
+ _type: { name: "_type", type: "string" },
15
+ _weak: { name: "_weak", type: "boolean" }
16
+ },
17
+ image: {
18
+ asset: { name: "asset", type: "reference" },
19
+ hotspot: {
20
+ name: "hotspot",
21
+ type: "object",
22
+ fields: [
23
+ { name: "x", type: "number" },
24
+ { name: "y", type: "number" },
25
+ { name: "height", type: "number" },
26
+ { name: "width", type: "number" }
27
+ ]
28
+ },
29
+ crop: {
30
+ name: "crop",
31
+ type: "object",
32
+ fields: [
33
+ { name: "top", type: "number" },
34
+ { name: "bottom", type: "number" },
35
+ { name: "left", type: "number" },
36
+ { name: "right", type: "number" }
37
+ ]
38
+ },
39
+ _type: { name: "_type", type: "string" }
40
+ },
41
+ file: {
42
+ asset: { name: "asset", type: "reference" },
43
+ _type: { name: "_type", type: "string" }
44
+ },
45
+ block: {
46
+ style: { name: "style", type: "string" },
47
+ listItem: { name: "listItem", type: "string" },
48
+ level: { name: "level", type: "number" },
49
+ children: {
50
+ name: "children",
51
+ type: "array",
52
+ of: [{ name: "span", type: "span" }]
53
+ },
54
+ markDefs: {
55
+ name: "markDefs",
56
+ type: "array",
57
+ of: [{ name: "object", type: "object" }]
58
+ },
59
+ _type: { name: "_type", type: "string" }
60
+ },
61
+ span: {
62
+ text: { name: "text", type: "string" },
63
+ marks: {
64
+ name: "marks",
65
+ type: "array",
66
+ of: [{ name: "string", type: "string" }]
67
+ },
68
+ _type: { name: "_type", type: "string" }
69
+ }
70
+ }, DEFAULT_LINK_ANNOTATION = {
71
+ name: "link",
72
+ type: "object",
73
+ fields: [
74
+ { name: "href", type: "string" },
75
+ { name: "blank", type: "boolean" }
76
+ ]
77
+ }, ARRAY_ITEM_SYSTEM_FIELDS = {
78
+ _key: { name: "_key", type: "string" },
79
+ _type: { name: "_type", type: "string" }
80
+ };
81
+ function toSchemaPath(path) {
82
+ return path ? path.replace(/\[append:\d+\]/g, "").replace(/\[_key\s*==\s*["'][^"']*["']\]/g, "").replace(/\[\d+\]/g, "").replace(/\[\]/g, "").replace(/\.{2,}/g, ".").replace(/^\.+|\.+$/g, "") : "";
83
+ }
84
+ const BASE_PRIMITIVES = ["string", "number", "boolean", "date", "datetime", "text", "url", "email"], BLOCK_TYPES = ["block", "reference"];
85
+ function isPrimitiveType(typeName, options = {}) {
86
+ return typeName ? options.includeBlockTypes ? BASE_PRIMITIVES.includes(typeName) || BLOCK_TYPES.includes(typeName) : BASE_PRIMITIVES.includes(typeName) : !1;
87
+ }
88
+ function isBuiltInType(type) {
89
+ return BUILT_IN_TYPES.has(type);
90
+ }
91
+ const BUILT_IN_TYPES = /* @__PURE__ */ new Set([
92
+ "string",
93
+ "text",
94
+ "number",
95
+ "boolean",
96
+ "array",
97
+ "object",
98
+ "reference",
99
+ "image",
100
+ "file",
101
+ "date",
102
+ "datetime",
103
+ "url",
104
+ "slug",
105
+ "block",
106
+ "geopoint"
107
+ ]);
108
+ function isGenericObject(node) {
109
+ if (typeof node != "object" || node === null || Array.isArray(node)) return !1;
110
+ const obj = node;
111
+ return !obj.fields && !(obj.type === "array" && Array.isArray(obj.of));
112
+ }
113
+ function resolveFieldSchemaAllUnions(path, typeSchema, schema) {
114
+ const pathParts = toSchemaPath(path).split(".").filter(Boolean);
115
+ let currentSchemas = [typeSchema];
116
+ for (let i = 0; i < pathParts.length; i++) {
117
+ const part = pathParts[i], isLastPart = i === pathParts.length - 1, nextSchemas = [];
118
+ for (const currentSchema of currentSchemas) {
119
+ if (!currentSchema?.fields || !Array.isArray(currentSchema.fields))
120
+ continue;
121
+ const field = currentSchema.fields.find((f) => f.name === part);
122
+ if (field)
123
+ if (field.type === "array" && field.of && field.of.length > 0)
124
+ for (const itemSchema of field.of) {
125
+ const itemType = typeof itemSchema.type == "string" ? itemSchema.type : void 0;
126
+ if (isLastPart && (itemType === "image" || itemType === "file"))
127
+ nextSchemas.push(itemSchema);
128
+ else if (itemType && !isBuiltInType(itemType)) {
129
+ const foundSchema = schema.find((s) => s.name === itemType);
130
+ foundSchema && nextSchemas.push(foundSchema);
131
+ } else itemSchema.fields && nextSchemas.push(itemSchema);
132
+ }
133
+ else if (field.type && !isBuiltInType(field.type)) {
134
+ const foundSchema = schema.find((s) => s.name === field.type);
135
+ if (foundSchema)
136
+ if (foundSchema.type === "array" && foundSchema.of && foundSchema.of.length > 0)
137
+ for (const itemSchema of foundSchema.of) {
138
+ const itemType = typeof itemSchema.type == "string" ? itemSchema.type : void 0;
139
+ if (isLastPart && (itemType === "image" || itemType === "file"))
140
+ nextSchemas.push(itemSchema);
141
+ else if (itemType && !isBuiltInType(itemType)) {
142
+ const itemFoundSchema = schema.find((s) => s.name === itemType);
143
+ itemFoundSchema && nextSchemas.push(itemFoundSchema);
144
+ } else itemSchema.fields && nextSchemas.push(itemSchema);
145
+ }
146
+ else
147
+ nextSchemas.push(foundSchema);
148
+ } else
149
+ nextSchemas.push(field);
150
+ }
151
+ currentSchemas = nextSchemas;
152
+ }
153
+ return currentSchemas;
154
+ }
155
+ function getBuiltInFieldSchema(segment, currentSchema) {
156
+ if (!currentSchema?.type || !BUILT_IN_TYPE_FIELDS[currentSchema.type]?.[segment])
157
+ return null;
158
+ let builtInField = BUILT_IN_TYPE_FIELDS[currentSchema.type][segment];
159
+ if (currentSchema.type === "block" && segment === "children" && currentSchema.of && (builtInField = {
160
+ ...builtInField,
161
+ of: [...builtInField.of || [], ...currentSchema.of]
162
+ }), currentSchema.type === "block" && segment === "markDefs") {
163
+ const annotations = currentSchema.marks?.annotations;
164
+ annotations ? builtInField = {
165
+ ...builtInField,
166
+ of: [...builtInField.of || [], ...annotations]
167
+ } : builtInField = {
168
+ ...builtInField,
169
+ of: [...builtInField.of || [], DEFAULT_LINK_ANNOTATION]
170
+ };
171
+ }
172
+ return builtInField;
173
+ }
174
+ function findSchemaInUnionArray(segment, arraySchema, allSchemas, isLastSegment) {
175
+ if (!arraySchema.of || arraySchema.of.length === 0)
176
+ return { schema: null, earlyReturn: null };
177
+ for (const itemSchema of arraySchema.of) {
178
+ if (BUILT_IN_TYPE_FIELDS[itemSchema.type]?.[segment]) {
179
+ const builtInField = BUILT_IN_TYPE_FIELDS[itemSchema.type][segment];
180
+ return isLastSegment ? { schema: null, earlyReturn: builtInField } : { schema: builtInField, earlyReturn: null };
181
+ }
182
+ if (itemSchema.fields?.some((f) => f.name === segment))
183
+ return { schema: itemSchema, earlyReturn: null };
184
+ if (itemSchema.type && !isPrimitiveType(itemSchema.type)) {
185
+ const referencedSchema2 = allSchemas.find((s) => s.name === itemSchema.type);
186
+ if (referencedSchema2?.fields?.some((f) => f.name === segment))
187
+ return { schema: referencedSchema2, earlyReturn: null };
188
+ }
189
+ }
190
+ const firstItem = arraySchema.of[0];
191
+ if (firstItem.fields)
192
+ return { schema: firstItem, earlyReturn: null };
193
+ const referencedSchema = allSchemas.find((s) => s.name === firstItem.type);
194
+ return referencedSchema?.fields ? { schema: referencedSchema, earlyReturn: null } : { schema: null, earlyReturn: null };
195
+ }
196
+ function resolveCurrentSchema(segment, currentSchema, allSchemas, isLastSegment) {
197
+ if (!currentSchema?.type)
198
+ return { schema: null, earlyReturn: null };
199
+ if (currentSchema.type === "array" && currentSchema.of && currentSchema.of.length > 0)
200
+ return findSchemaInUnionArray(segment, currentSchema, allSchemas, isLastSegment);
201
+ const referencedSchema = allSchemas.find((s) => s.name === currentSchema.type);
202
+ if (referencedSchema?.fields)
203
+ return { schema: referencedSchema, earlyReturn: null };
204
+ if (BUILT_IN_TYPE_FIELDS[currentSchema.type]?.[segment]) {
205
+ const builtInField = BUILT_IN_TYPE_FIELDS[currentSchema.type][segment];
206
+ return isLastSegment ? { schema: null, earlyReturn: builtInField } : { schema: builtInField, earlyReturn: null };
207
+ }
208
+ return { schema: null, earlyReturn: null };
209
+ }
210
+ function getNextSchemaForField(field, nextSegment, allSchemas) {
211
+ let resolvedField = field;
212
+ if (field.type && !isPrimitiveType(field.type) && field.type !== "array") {
213
+ const referencedSchema = allSchemas.find((s) => s.name === field.type);
214
+ referencedSchema && (resolvedField = referencedSchema);
215
+ }
216
+ if (resolvedField.type === "array" && resolvedField.of && resolvedField.of.length > 0) {
217
+ for (const itemSchema of resolvedField.of) {
218
+ if (BUILT_IN_TYPE_FIELDS[itemSchema.type]?.[nextSegment] || itemSchema.fields?.some((f) => f.name === nextSegment))
219
+ return itemSchema;
220
+ if (itemSchema.type && !isPrimitiveType(itemSchema.type)) {
221
+ const refSchema = allSchemas.find((s) => s.name === itemSchema.type);
222
+ if (refSchema?.fields?.some((f) => f.name === nextSegment))
223
+ return refSchema;
224
+ }
225
+ }
226
+ return resolvedField.of[0];
227
+ }
228
+ return resolvedField;
229
+ }
230
+ function resolveFieldSchema(path, typeSchema, schema) {
231
+ const segments = toSchemaPath(path).split(".").filter(Boolean);
232
+ let currentSchema = typeSchema;
233
+ for (let i = 0; i < segments.length; i++) {
234
+ const segment = segments[i], isLastSegment = i === segments.length - 1;
235
+ if (ARRAY_ITEM_SYSTEM_FIELDS[segment])
236
+ return ARRAY_ITEM_SYSTEM_FIELDS[segment];
237
+ const builtInField = getBuiltInFieldSchema(segment, currentSchema);
238
+ if (builtInField) {
239
+ if (isLastSegment) return builtInField;
240
+ currentSchema = builtInField;
241
+ continue;
242
+ }
243
+ if (!currentSchema?.fields) {
244
+ const resolved = resolveCurrentSchema(segment, currentSchema, schema, isLastSegment);
245
+ if (resolved.earlyReturn) return resolved.earlyReturn;
246
+ if (!resolved.schema) return null;
247
+ currentSchema = resolved.schema;
248
+ const resolvedBuiltInField = getBuiltInFieldSchema(segment, currentSchema);
249
+ if (resolvedBuiltInField) {
250
+ if (isLastSegment) return resolvedBuiltInField;
251
+ currentSchema = resolvedBuiltInField;
252
+ continue;
253
+ }
254
+ }
255
+ if (!currentSchema?.fields) return null;
256
+ const field = currentSchema.fields.find((f) => f.name === segment);
257
+ if (!field) return null;
258
+ if (isLastSegment) return field;
259
+ currentSchema = getNextSchemaForField(field, segments[i + 1], schema);
260
+ }
261
+ return currentSchema || null;
262
+ }
263
+ const joinSchemaPath = (parent, child) => parent ? `${parent}.${child}` : child, findReferencedType = (field, schema) => {
264
+ if (!isPrimitiveType(field.type))
265
+ return schema.find((s) => s.name === field.type);
266
+ };
267
+ function walkArrayItems(field, path, schema, visited, visit) {
268
+ if (field.of?.length)
269
+ for (const rawItem of field.of) {
270
+ const item = rawItem;
271
+ if (item.fields?.length) {
272
+ walkFields(item.fields, path, schema, visited, visit);
273
+ continue;
274
+ }
275
+ if (!item.type || isPrimitiveType(item.type)) continue;
276
+ const referenced = schema.find((s) => s.name === item.type);
277
+ !referenced || visited.has(referenced.name) || referenced.fields?.length && (visited.add(referenced.name), walkFields(referenced.fields, path, schema, visited, visit));
278
+ }
279
+ }
280
+ function walkFields(fields, path, schema, visited, visit) {
281
+ for (const field of fields) {
282
+ const fieldPath = joinSchemaPath(path, field.name);
283
+ if (visit(field, fieldPath), field.fields?.length) {
284
+ walkFields(field.fields, fieldPath, schema, visited, visit);
285
+ continue;
286
+ }
287
+ if (field.of?.length) {
288
+ walkArrayItems(field, fieldPath, schema, visited, visit);
289
+ continue;
290
+ }
291
+ const referenced = findReferencedType(field, schema);
292
+ referenced?.fields?.length && (visited.has(referenced.name) || (visited.add(referenced.name), walkFields(referenced.fields, fieldPath, schema, visited, visit)));
293
+ }
294
+ }
295
+ function walkSchemaTree(documentType, schema, visit) {
296
+ const typeSchema = schema.find((s) => s.name === documentType);
297
+ typeSchema?.fields?.length && walkFields(typeSchema.fields, "", schema, /* @__PURE__ */ new Set([typeSchema.name]), visit);
298
+ }
299
+ export {
300
+ ARRAY_ITEM_SYSTEM_FIELDS,
301
+ BUILT_IN_TYPE_FIELDS,
302
+ DEFAULT_LINK_ANNOTATION,
303
+ isBuiltInType,
304
+ isGenericObject,
305
+ isPrimitiveType,
306
+ joinSchemaPath,
307
+ resolveFieldSchema,
308
+ resolveFieldSchemaAllUnions,
309
+ toSchemaPath,
310
+ walkSchemaTree
311
+ };
312
+ //# sourceMappingURL=walkTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walkTree.js","sources":["../../src/navigate/constants.ts","../../src/navigate/path.ts","../../src/navigate/types.ts","../../src/navigate/navigateAllUnions.ts","../../src/navigate/navigateToField.ts","../../src/navigate/walkTree.ts"],"sourcesContent":["import type { ManifestSchemaType } from '../types.js'\n\n/**\n * Built-in Sanity type fields that exist implicitly (not in schema).\n * Maps type name to field definitions.\n */\nexport const BUILT_IN_TYPE_FIELDS: Record<string, Record<string, ManifestSchemaType>> = {\n slug: {\n current: { name: 'current', type: 'string' } as ManifestSchemaType,\n _type: { name: '_type', type: 'string' } as ManifestSchemaType,\n },\n geopoint: {\n lat: { name: 'lat', type: 'number' } as ManifestSchemaType,\n lng: { name: 'lng', type: 'number' } as ManifestSchemaType,\n alt: { name: 'alt', type: 'number' } as ManifestSchemaType,\n _type: { name: '_type', type: 'string' } as ManifestSchemaType,\n },\n reference: {\n _ref: { name: '_ref', type: 'string' } as ManifestSchemaType,\n _type: { name: '_type', type: 'string' } as ManifestSchemaType,\n _weak: { name: '_weak', type: 'boolean' } as ManifestSchemaType,\n },\n image: {\n asset: { name: 'asset', type: 'reference' } as ManifestSchemaType,\n hotspot: {\n name: 'hotspot',\n type: 'object',\n fields: [\n { name: 'x', type: 'number' },\n { name: 'y', type: 'number' },\n { name: 'height', type: 'number' },\n { name: 'width', type: 'number' },\n ],\n } as ManifestSchemaType,\n crop: {\n name: 'crop',\n type: 'object',\n fields: [\n { name: 'top', type: 'number' },\n { name: 'bottom', type: 'number' },\n { name: 'left', type: 'number' },\n { name: 'right', type: 'number' },\n ],\n } as ManifestSchemaType,\n _type: { name: '_type', type: 'string' } as ManifestSchemaType,\n },\n file: {\n asset: { name: 'asset', type: 'reference' } as ManifestSchemaType,\n _type: { name: '_type', type: 'string' } as ManifestSchemaType,\n },\n block: {\n style: { name: 'style', type: 'string' } as ManifestSchemaType,\n listItem: { name: 'listItem', type: 'string' } as ManifestSchemaType,\n level: { name: 'level', type: 'number' } as ManifestSchemaType,\n children: {\n name: 'children',\n type: 'array',\n of: [{ name: 'span', type: 'span' }],\n } as ManifestSchemaType,\n markDefs: {\n name: 'markDefs',\n type: 'array',\n of: [{ name: 'object', type: 'object' }],\n } as ManifestSchemaType,\n _type: { name: '_type', type: 'string' } as ManifestSchemaType,\n },\n span: {\n text: { name: 'text', type: 'string' } as ManifestSchemaType,\n marks: {\n name: 'marks',\n type: 'array',\n of: [{ name: 'string', type: 'string' }],\n } as ManifestSchemaType,\n _type: { name: '_type', type: 'string' } as ManifestSchemaType,\n },\n}\n\n/**\n * Default annotation type for Portable Text blocks.\n * Sanity implicitly includes \"link\" when no marks.annotations are declared.\n */\nexport const DEFAULT_LINK_ANNOTATION: ManifestSchemaType = {\n name: 'link',\n type: 'object',\n fields: [\n { name: 'href', type: 'string' },\n { name: 'blank', type: 'boolean' },\n ],\n} as ManifestSchemaType\n\n/**\n * System fields that exist on all array items.\n */\nexport const ARRAY_ITEM_SYSTEM_FIELDS: Record<string, ManifestSchemaType> = {\n _key: { name: '_key', type: 'string' } as ManifestSchemaType,\n _type: { name: '_type', type: 'string' } as ManifestSchemaType,\n}\n","/**\n * Convert a document path string to a schema path string.\n * Strips array indices, _key selectors, and internal markers.\n *\n * Examples:\n * - `\"content[_key==\\\"abc\\\"].children[0].text\"` → `\"content.children.text\"`\n * - `\"tags[0]\"` → `\"tags\"`\n * - `\"seo.image.asset\"` → `\"seo.image.asset\"`\n * - `\"items[append:3]\"` → `\"items\"`\n *\n * This is a self-contained implementation that avoids depending on\n * `@sanity/types` for path segment parsing.\n */\nexport function toSchemaPath(path: string): string {\n if (!path) return ''\n\n return (\n path\n // Strip internal markers: [append:N]\n .replace(/\\[append:\\d+\\]/g, '')\n // Strip _key selectors: [_key==\"value\"] or [_key=='value']\n .replace(/\\[_key\\s*==\\s*[\"'][^\"']*[\"']\\]/g, '')\n // Strip numeric indices: [0], [123]\n .replace(/\\[\\d+\\]/g, '')\n // Strip empty brackets: []\n .replace(/\\[\\]/g, '')\n // Collapse any resulting double dots\n .replace(/\\.{2,}/g, '.')\n // Trim leading/trailing dots\n .replace(/^\\.+|\\.+$/g, '')\n )\n}\n","const BASE_PRIMITIVES = ['string', 'number', 'boolean', 'date', 'datetime', 'text', 'url', 'email']\n\nconst BLOCK_TYPES = ['block', 'reference']\n\n/**\n * Check if a type name represents a primitive type.\n *\n * When `includeBlockTypes` is true, 'block' and 'reference' are also\n * considered primitive (useful for navigator/large-node detection where\n * you don't want to drill into these).\n */\nexport function isPrimitiveType(\n typeName: string | undefined,\n options: { includeBlockTypes?: boolean } = {},\n): boolean {\n if (!typeName) return false\n if (options.includeBlockTypes) {\n return BASE_PRIMITIVES.includes(typeName) || BLOCK_TYPES.includes(typeName)\n }\n return BASE_PRIMITIVES.includes(typeName)\n}\n\n/**\n * Check if a type is a built-in Sanity type (superset of primitives).\n * Includes complex built-in types like array, object, image, file, slug, etc.\n */\nexport function isBuiltInType(type: string): boolean {\n return BUILT_IN_TYPES.has(type)\n}\n\nconst BUILT_IN_TYPES = new Set([\n 'string',\n 'text',\n 'number',\n 'boolean',\n 'array',\n 'object',\n 'reference',\n 'image',\n 'file',\n 'date',\n 'datetime',\n 'url',\n 'slug',\n 'block',\n 'geopoint',\n])\n\n/**\n * Check if a node is a generic object-like node.\n * Generic objects are objects that don't have a `fields` array and\n * aren't array types with `of`. These include block types and other\n * object-shaped schemas with properties like marks, lists, styles, etc.\n */\nexport function isGenericObject(node: unknown): boolean {\n if (typeof node !== 'object' || node === null || Array.isArray(node)) return false\n const obj = node as Record<string, unknown>\n return !obj.fields && !(obj.type === 'array' && Array.isArray(obj.of))\n}\n","import type { ManifestSchemaType } from '../types.js'\nimport { toSchemaPath } from './path.js'\nimport { isBuiltInType } from './types.js'\n\n/**\n * Resolves a document path to field schemas, returning ALL possible schemas for union types.\n * This is important for arrays with multiple `of` types where a field might exist\n * in some but not all union types.\n */\nexport function resolveFieldSchemaAllUnions(\n path: string,\n typeSchema: ManifestSchemaType,\n schema: ManifestSchemaType[],\n): ManifestSchemaType[] {\n const pathParts = toSchemaPath(path).split('.').filter(Boolean)\n\n let currentSchemas: ManifestSchemaType[] = [typeSchema]\n\n for (let i = 0; i < pathParts.length; i++) {\n const part = pathParts[i]\n const isLastPart = i === pathParts.length - 1\n const nextSchemas: ManifestSchemaType[] = []\n\n for (const currentSchema of currentSchemas) {\n if (!currentSchema?.fields || !Array.isArray(currentSchema.fields)) {\n continue\n }\n\n const field = currentSchema.fields.find((f) => f.name === part)\n if (!field) continue\n\n if (field.type === 'array' && field.of && field.of.length > 0) {\n for (const itemSchema of field.of) {\n const itemType = typeof itemSchema.type === 'string' ? itemSchema.type : undefined\n if (isLastPart && (itemType === 'image' || itemType === 'file')) {\n nextSchemas.push(itemSchema as ManifestSchemaType)\n } else if (itemType && !isBuiltInType(itemType)) {\n const foundSchema = schema.find((s) => s.name === itemType)\n if (foundSchema) nextSchemas.push(foundSchema)\n } else if ((itemSchema as ManifestSchemaType).fields) {\n nextSchemas.push(itemSchema as ManifestSchemaType)\n }\n }\n } else if (field.type && !isBuiltInType(field.type)) {\n const foundSchema = schema.find((s) => s.name === field.type)\n if (foundSchema) {\n if (foundSchema.type === 'array' && foundSchema.of && foundSchema.of.length > 0) {\n for (const itemSchema of foundSchema.of) {\n const itemType = typeof itemSchema.type === 'string' ? itemSchema.type : undefined\n if (isLastPart && (itemType === 'image' || itemType === 'file')) {\n nextSchemas.push(itemSchema as ManifestSchemaType)\n } else if (itemType && !isBuiltInType(itemType)) {\n const itemFoundSchema = schema.find((s) => s.name === itemType)\n if (itemFoundSchema) nextSchemas.push(itemFoundSchema)\n } else if ((itemSchema as ManifestSchemaType).fields) {\n nextSchemas.push(itemSchema as ManifestSchemaType)\n }\n }\n } else {\n nextSchemas.push(foundSchema)\n }\n }\n } else {\n nextSchemas.push(field as ManifestSchemaType)\n }\n }\n\n currentSchemas = nextSchemas\n }\n\n return currentSchemas\n}\n","import type { ManifestField, ManifestSchemaType } from '../types.js'\nimport {\n ARRAY_ITEM_SYSTEM_FIELDS,\n BUILT_IN_TYPE_FIELDS,\n DEFAULT_LINK_ANNOTATION,\n} from './constants.js'\nimport { toSchemaPath } from './path.js'\nimport { isPrimitiveType } from './types.js'\n\ninterface SchemaResolutionResult {\n schema: ManifestSchemaType | null\n earlyReturn: ManifestSchemaType | null\n}\n\nfunction getBuiltInFieldSchema(\n segment: string,\n currentSchema: ManifestSchemaType,\n): ManifestSchemaType | null {\n if (!currentSchema?.type || !BUILT_IN_TYPE_FIELDS[currentSchema.type]?.[segment]) {\n return null\n }\n\n let builtInField: ManifestSchemaType = BUILT_IN_TYPE_FIELDS[currentSchema.type][segment]\n\n // For block.children, merge in block.of (inline objects) from the schema\n if (currentSchema.type === 'block' && segment === 'children' && currentSchema.of) {\n builtInField = {\n ...builtInField,\n of: [...(builtInField.of || []), ...(currentSchema.of as ManifestSchemaType[])],\n }\n }\n\n // For block.markDefs, merge in block.marks.annotations from the schema\n // If no annotations are declared, add default \"link\" annotation (Sanity built-in)\n if (currentSchema.type === 'block' && segment === 'markDefs') {\n const annotations = (\n currentSchema as ManifestSchemaType & { marks?: { annotations?: ManifestSchemaType[] } }\n ).marks?.annotations\n if (annotations) {\n builtInField = {\n ...builtInField,\n of: [...(builtInField.of || []), ...annotations],\n }\n } else {\n builtInField = {\n ...builtInField,\n of: [...(builtInField.of || []), DEFAULT_LINK_ANNOTATION],\n }\n }\n }\n\n return builtInField\n}\n\nfunction findSchemaInUnionArray(\n segment: string,\n arraySchema: ManifestSchemaType,\n allSchemas: ManifestSchemaType[],\n isLastSegment: boolean,\n): SchemaResolutionResult {\n if (!arraySchema.of || arraySchema.of.length === 0) {\n return { schema: null, earlyReturn: null }\n }\n\n for (const itemSchema of arraySchema.of as ManifestSchemaType[]) {\n if (BUILT_IN_TYPE_FIELDS[itemSchema.type]?.[segment]) {\n const builtInField = BUILT_IN_TYPE_FIELDS[itemSchema.type][segment]\n if (isLastSegment) {\n return { schema: null, earlyReturn: builtInField }\n }\n return { schema: builtInField, earlyReturn: null }\n }\n\n if (itemSchema.fields?.some((f) => f.name === segment)) {\n return { schema: itemSchema, earlyReturn: null }\n }\n\n if (itemSchema.type && !isPrimitiveType(itemSchema.type)) {\n const referencedSchema = allSchemas.find((s) => s.name === itemSchema.type)\n if (referencedSchema?.fields?.some((f) => f.name === segment)) {\n return { schema: referencedSchema, earlyReturn: null }\n }\n }\n }\n\n const firstItem = arraySchema.of[0] as ManifestSchemaType\n if (firstItem.fields) {\n return { schema: firstItem, earlyReturn: null }\n }\n\n const referencedSchema = allSchemas.find((s) => s.name === firstItem.type)\n if (referencedSchema?.fields) {\n return { schema: referencedSchema, earlyReturn: null }\n }\n\n return { schema: null, earlyReturn: null }\n}\n\nfunction resolveCurrentSchema(\n segment: string,\n currentSchema: ManifestSchemaType,\n allSchemas: ManifestSchemaType[],\n isLastSegment: boolean,\n): SchemaResolutionResult {\n if (!currentSchema?.type) {\n return { schema: null, earlyReturn: null }\n }\n\n if (currentSchema.type === 'array' && currentSchema.of && currentSchema.of.length > 0) {\n return findSchemaInUnionArray(segment, currentSchema, allSchemas, isLastSegment)\n }\n\n const referencedSchema = allSchemas.find((s) => s.name === currentSchema.type)\n if (referencedSchema?.fields) {\n return { schema: referencedSchema, earlyReturn: null }\n }\n\n if (BUILT_IN_TYPE_FIELDS[currentSchema.type]?.[segment]) {\n const builtInField = BUILT_IN_TYPE_FIELDS[currentSchema.type][segment]\n if (isLastSegment) {\n return { schema: null, earlyReturn: builtInField }\n }\n return { schema: builtInField, earlyReturn: null }\n }\n\n return { schema: null, earlyReturn: null }\n}\n\nfunction getNextSchemaForField(\n field: ManifestField,\n nextSegment: string,\n allSchemas: ManifestSchemaType[],\n): ManifestSchemaType {\n let resolvedField: ManifestSchemaType = field as ManifestSchemaType\n if (field.type && !isPrimitiveType(field.type) && field.type !== 'array') {\n const referencedSchema = allSchemas.find((s) => s.name === field.type)\n if (referencedSchema) {\n resolvedField = referencedSchema\n }\n }\n\n if (resolvedField.type === 'array' && resolvedField.of && resolvedField.of.length > 0) {\n for (const itemSchema of resolvedField.of as ManifestSchemaType[]) {\n if (BUILT_IN_TYPE_FIELDS[itemSchema.type]?.[nextSegment]) {\n return itemSchema\n }\n if (itemSchema.fields?.some((f) => f.name === nextSegment)) {\n return itemSchema\n }\n if (itemSchema.type && !isPrimitiveType(itemSchema.type)) {\n const refSchema = allSchemas.find((s) => s.name === itemSchema.type)\n if (refSchema?.fields?.some((f) => f.name === nextSegment)) {\n return refSchema\n }\n }\n }\n return resolvedField.of[0] as ManifestSchemaType\n }\n\n return resolvedField\n}\n\n/**\n * Resolves a document path to the field schema at that location.\n * Handles nested paths like \"author.name\" and array paths like \"tags[0]\".\n *\n * Returns the field schema at the path, NOT navigating into arrays.\n * For \"tags\" (an array field), returns the array field schema (with 'of').\n * For \"tags[0].foo\", returns the \"foo\" field from the array item schema.\n */\nexport function resolveFieldSchema(\n path: string,\n typeSchema: ManifestSchemaType,\n schema: ManifestSchemaType[],\n): ManifestSchemaType | null {\n const segments = toSchemaPath(path).split('.').filter(Boolean)\n\n let currentSchema: ManifestSchemaType | undefined = typeSchema\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i]\n const isLastSegment = i === segments.length - 1\n\n if (ARRAY_ITEM_SYSTEM_FIELDS[segment]) {\n return ARRAY_ITEM_SYSTEM_FIELDS[segment]\n }\n\n const builtInField = getBuiltInFieldSchema(segment, currentSchema!)\n if (builtInField) {\n if (isLastSegment) return builtInField\n currentSchema = builtInField\n continue\n }\n\n if (!currentSchema?.fields) {\n const resolved = resolveCurrentSchema(segment, currentSchema!, schema, isLastSegment)\n if (resolved.earlyReturn) return resolved.earlyReturn\n if (!resolved.schema) return null\n currentSchema = resolved.schema\n\n const resolvedBuiltInField = getBuiltInFieldSchema(segment, currentSchema)\n if (resolvedBuiltInField) {\n if (isLastSegment) return resolvedBuiltInField\n currentSchema = resolvedBuiltInField\n continue\n }\n }\n\n if (!currentSchema?.fields) return null\n\n const field = currentSchema.fields.find((f) => f.name === segment)\n if (!field) return null\n if (isLastSegment) return field\n\n currentSchema = getNextSchemaForField(field, segments[i + 1], schema)\n }\n\n return currentSchema || null\n}\n","/**\n * Whole-tree schema walker.\n *\n * Where `navigateToField` and `navigateAllUnions` resolve a single path string\n * to its field schema, this walks every reachable field in a document type.\n * Used by validators that need to inspect the full schema graph (required\n * fields, custom validators).\n *\n * Handles:\n * - Inline objects (`field.fields`)\n * - Aliased object types (looked up in the schema array)\n * - Arrays of objects (`field.of` items recursed with the same logic)\n *\n * Cycles are guarded by tracking visited type names. Built-in primitive types\n * are skipped: there's nothing to walk into.\n */\n\nimport type { ManifestField, ManifestSchemaType } from '../types.js'\nimport { isPrimitiveType } from './types.js'\n\nexport type WalkVisitor = (field: ManifestField, path: string) => void\n\nexport const joinSchemaPath = (parent: string, child: string): string =>\n parent ? `${parent}.${child}` : child\n\nconst findReferencedType = (\n field: ManifestField,\n schema: ManifestSchemaType[],\n): ManifestSchemaType | undefined => {\n if (isPrimitiveType(field.type)) return undefined\n return schema.find((s) => s.name === field.type)\n}\n\nfunction walkArrayItems(\n field: ManifestField,\n path: string,\n schema: ManifestSchemaType[],\n visited: Set<string>,\n visit: WalkVisitor,\n): void {\n if (!field.of?.length) return\n\n for (const rawItem of field.of) {\n const item = rawItem as ManifestSchemaType\n // Inline object items in `of` carry their own fields; aliased items just\n // reference a type by name and need a schema lookup.\n if (item.fields?.length) {\n walkFields(item.fields, path, schema, visited, visit)\n continue\n }\n if (!item.type || isPrimitiveType(item.type)) continue\n const referenced = schema.find((s) => s.name === item.type)\n if (!referenced || visited.has(referenced.name)) continue\n if (referenced.fields?.length) {\n visited.add(referenced.name)\n walkFields(referenced.fields, path, schema, visited, visit)\n }\n }\n}\n\nfunction walkFields(\n fields: ManifestField[],\n path: string,\n schema: ManifestSchemaType[],\n visited: Set<string>,\n visit: WalkVisitor,\n): void {\n for (const field of fields) {\n const fieldPath = joinSchemaPath(path, field.name)\n visit(field, fieldPath)\n\n if (field.fields?.length) {\n walkFields(field.fields, fieldPath, schema, visited, visit)\n continue\n }\n\n if (field.of?.length) {\n walkArrayItems(field, fieldPath, schema, visited, visit)\n continue\n }\n\n const referenced = findReferencedType(field, schema)\n if (!referenced?.fields?.length) continue\n if (visited.has(referenced.name)) continue\n\n visited.add(referenced.name)\n walkFields(referenced.fields, fieldPath, schema, visited, visit)\n }\n}\n\n/**\n * Visit every field reachable from a document type. The visitor is called once\n * per field with the field schema and its dotted path from the document root.\n */\nexport function walkSchemaTree(\n documentType: string,\n schema: ManifestSchemaType[],\n visit: WalkVisitor,\n): void {\n const typeSchema = schema.find((s) => s.name === documentType)\n if (!typeSchema?.fields?.length) return\n\n walkFields(typeSchema.fields, '', schema, new Set([typeSchema.name]), visit)\n}\n"],"names":["referencedSchema"],"mappings":"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"}