@sanity/agent-schema 0.0.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 +277 -0
- package/dist/index.d.ts +356 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1051 -0
- package/dist/index.js.map +1 -0
- package/package.json +65 -0
package/README.md
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
# @sanity/agent-schema
|
|
2
|
+
|
|
3
|
+
Schema processing utilities for Sanity Agent. Parses Lexicon schemas, compresses them for LLM context, provides full JSON views for schema explorers, and navigates schema trees for validation and mutation agents.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @sanity/agent-schema
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import {
|
|
15
|
+
fetchSchemaByDescriptorId,
|
|
16
|
+
fetchDatasetStats,
|
|
17
|
+
compressedSchema,
|
|
18
|
+
} from "@sanity/agent-schema";
|
|
19
|
+
|
|
20
|
+
// 1. Fetch and parse the schema
|
|
21
|
+
const types = await fetchSchemaByDescriptorId(lexiconClient, descriptorId);
|
|
22
|
+
|
|
23
|
+
// 2. Optionally fetch dataset stats (enriches output with counts)
|
|
24
|
+
const statsResult = await fetchDatasetStats(agentClient, {
|
|
25
|
+
organizationId,
|
|
26
|
+
projectId,
|
|
27
|
+
dataset,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// 3. Compress into agent-friendly text
|
|
31
|
+
const text = await compressedSchema(types, {
|
|
32
|
+
datasetStats: statsResult.status === "ready" ? statsResult.stats : undefined,
|
|
33
|
+
filter: { read: '_type in ["post", "author"]' },
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## API
|
|
38
|
+
|
|
39
|
+
### Fetch
|
|
40
|
+
|
|
41
|
+
#### `fetchSchemaByDescriptorId(client, descriptorId, options?)`
|
|
42
|
+
|
|
43
|
+
Fetches a schema from the Lexicon API and returns parsed `ManifestSchemaType[]`.
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
const types = await fetchSchemaByDescriptorId(client, descriptorId);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Enable caching with `{ cache: true }` (in-memory, 5 min TTL) or a custom adapter:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
// Built-in memory cache
|
|
53
|
+
const types = await fetchSchemaByDescriptorId(client, id, { cache: true });
|
|
54
|
+
|
|
55
|
+
// Custom cache (e.g. Redis)
|
|
56
|
+
const types = await fetchSchemaByDescriptorId(client, id, {
|
|
57
|
+
cache: {
|
|
58
|
+
get: (id) => redis.get(id),
|
|
59
|
+
set: (id, response) => redis.set(id, response),
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### `fetchDatasetStats(client, options)`
|
|
65
|
+
|
|
66
|
+
Fetches document and reference counts from the agent API. Returns `{ status: 'ready', stats }` or `{ status: 'processing' }` if still being computed.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
const result = await fetchDatasetStats(client, {
|
|
70
|
+
organizationId: "org-abc",
|
|
71
|
+
projectId: "my-project",
|
|
72
|
+
dataset: "production",
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (result.status === "ready") {
|
|
76
|
+
result.stats.documentCount; // { post: 42, author: 7 }
|
|
77
|
+
result.stats.referenceCount; // { post: { incoming: {...}, outgoing: {...} } }
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Compress
|
|
82
|
+
|
|
83
|
+
#### `compressedSchema(types, options?)`
|
|
84
|
+
|
|
85
|
+
The main entry point. Takes parsed types and returns compact text for agents.
|
|
86
|
+
|
|
87
|
+
The `filter` option controls which document types to include. Pass a GROQ filter (requires `groq-js` peer dep) or an explicit list of type names:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
// GROQ filter — types are inferred from the expression
|
|
91
|
+
await compressedSchema(types, {
|
|
92
|
+
filter: { read: '_type in ["post", "author"]' },
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Explicit type list
|
|
96
|
+
await compressedSchema(types, {
|
|
97
|
+
filter: ["post", "author"],
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// All options
|
|
101
|
+
await compressedSchema(types, {
|
|
102
|
+
filter: { read: '_type == "post"', write: '_type == "draft"' },
|
|
103
|
+
datasetStats,
|
|
104
|
+
fields: { maxCount: 5, includeDescription: true },
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
| Option | Type | Description |
|
|
109
|
+
| -------------- | --------------------------- | --------------------------------------------- |
|
|
110
|
+
| `filter` | `SchemaFilter` | GROQ filter `{ read?, write? }` or `string[]` |
|
|
111
|
+
| `datasetStats` | `DatasetStats` | Document/reference counts to enrich output |
|
|
112
|
+
| `fields` | `SchemaFieldDisplayOptions` | Control field display (see below) |
|
|
113
|
+
|
|
114
|
+
**Field display options:**
|
|
115
|
+
|
|
116
|
+
| Option | Type | Default | Description |
|
|
117
|
+
| ---------------------- | --------- | ------- | --------------------------------------------------- |
|
|
118
|
+
| `showAll` | `boolean` | `false` | Show all fields (ignores `maxCount`) |
|
|
119
|
+
| `maxCount` | `number` | `10` | Max fields to display per type |
|
|
120
|
+
| `includeDescription` | `boolean` | `false` | Append field titles that differ from the field name |
|
|
121
|
+
| `includeHidden` | `boolean` | `false` | Include hidden fields |
|
|
122
|
+
| `includeDeprecated` | `boolean` | `false` | Include deprecated fields |
|
|
123
|
+
| `maxEnumValues` | `number` | `10` | Max enum values before truncating |
|
|
124
|
+
| `maxDescriptionLength` | `number` | `50` | Truncate field descriptions beyond this length |
|
|
125
|
+
|
|
126
|
+
### Full schema
|
|
127
|
+
|
|
128
|
+
#### `fullSchema(types, options)`
|
|
129
|
+
|
|
130
|
+
Returns a **JSON subtree** of a schema type — everything inside it (all fields, nested objects, validation rules, options). Used by schema explorer tools to let the LLM browse type structures.
|
|
131
|
+
|
|
132
|
+
Without `path`, you get the entire type. With `path`, you get the subtree rooted at that field — still the full structure from that point down, just scoped to a smaller starting point. This is useful because some types are huge; `path` lets you zoom in.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { fullSchema } from "@sanity/agent-schema";
|
|
136
|
+
|
|
137
|
+
fullSchema(types, { type: "post" });
|
|
138
|
+
// Returns: { name: "post", type: "document", fields: [
|
|
139
|
+
// { name: "title", type: "string" },
|
|
140
|
+
// { name: "content", type: "array", of: [
|
|
141
|
+
// { name: "block", type: "block", marks: {...}, styles: [...], ... },
|
|
142
|
+
// { name: "codeBlock", type: "object", fields: [
|
|
143
|
+
// { name: "language", type: "string", options: { list: [...] } },
|
|
144
|
+
// { name: "code", type: "text" },
|
|
145
|
+
// ]},
|
|
146
|
+
// ]},
|
|
147
|
+
// ... every field, fully expanded ...
|
|
148
|
+
// ]}
|
|
149
|
+
|
|
150
|
+
// Same structure, just starting from content[].codeBlock instead of the root
|
|
151
|
+
fullSchema(types, { type: "post", path: "content[].codeBlock" });
|
|
152
|
+
// Returns: { name: "codeBlock", type: "object", fields: [
|
|
153
|
+
// { name: "language", type: "string", options: { list: [...] } },
|
|
154
|
+
// { name: "code", type: "text" },
|
|
155
|
+
// ]}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
If the output exceeds `sizeThreshold`, a navigator object is returned instead with child paths to drill into.
|
|
159
|
+
|
|
160
|
+
| Option | Type | Default | Description |
|
|
161
|
+
| --------------- | -------- | -------- | ----------------------------------------------------- |
|
|
162
|
+
| `type` | `string` | required | Document type name to return |
|
|
163
|
+
| `path` | `string` | | Field path — returns the subtree from this point down |
|
|
164
|
+
| `sizeThreshold` | `number` | `200KB` | Byte limit before returning a navigator instead |
|
|
165
|
+
|
|
166
|
+
### Navigate
|
|
167
|
+
|
|
168
|
+
#### `resolveFieldSchema(path, typeSchema, schema)`
|
|
169
|
+
|
|
170
|
+
Returns the **single field definition** at the end of a path. No subtree, no nested fields — just the node itself. Used by validators and mutation code that need to answer "what type is the value at this path?"
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import { resolveFieldSchema } from "@sanity/agent-schema";
|
|
174
|
+
|
|
175
|
+
resolveFieldSchema("content[0].text", postSchema, allTypes);
|
|
176
|
+
// Returns: { name: "text", type: "string" }
|
|
177
|
+
//
|
|
178
|
+
// Compare with fullSchema — that would return the entire content array
|
|
179
|
+
// with all its item types expanded. This just tells you "it's a string."
|
|
180
|
+
|
|
181
|
+
resolveFieldSchema("tags", postSchema, allTypes);
|
|
182
|
+
// Returns: { name: "tags", type: "array", of: [...] }
|
|
183
|
+
//
|
|
184
|
+
// You get the field node, not the expanded contents of every array item.
|
|
185
|
+
|
|
186
|
+
resolveFieldSchema("nonexistent.path", postSchema, allTypes);
|
|
187
|
+
// Returns: null
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Handles nested objects, array indices, built-in type fields (`slug.current`, `block.children`), and type references.
|
|
191
|
+
|
|
192
|
+
#### `resolveFieldSchemaAllUnions(path, typeSchema, schema)`
|
|
193
|
+
|
|
194
|
+
Same as `resolveFieldSchema`, but when the path crosses a union array, returns the field definition from **every** item type instead of just the first match.
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
import { resolveFieldSchemaAllUnions } from "@sanity/agent-schema";
|
|
198
|
+
|
|
199
|
+
resolveFieldSchemaAllUnions("content", postSchema, allTypes);
|
|
200
|
+
// Returns: [blockSchema, imageSchema, codeSchema]
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
#### `filterToPath(type, path, schema)`
|
|
204
|
+
|
|
205
|
+
Returns a schema type narrowed to a specific field path — the same subtree extraction that `fullSchema` uses internally.
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
import { filterToPath } from "@sanity/agent-schema";
|
|
209
|
+
|
|
210
|
+
const filtered = filterToPath(postType, "content[].codeBlock", allTypes);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### `toSchemaPath(path)`
|
|
214
|
+
|
|
215
|
+
Converts a document path to a schema path by stripping array indices and key selectors.
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
import { toSchemaPath } from "@sanity/agent-schema";
|
|
219
|
+
|
|
220
|
+
toSchemaPath('content[_key=="abc"].children[0].text');
|
|
221
|
+
// "content.children.text"
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### Type helpers
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
import {
|
|
228
|
+
isPrimitiveType,
|
|
229
|
+
isBuiltInType,
|
|
230
|
+
isGenericObject,
|
|
231
|
+
} from "@sanity/agent-schema";
|
|
232
|
+
|
|
233
|
+
isPrimitiveType("string"); // true
|
|
234
|
+
isPrimitiveType("block", { includeBlockTypes: true }); // true
|
|
235
|
+
isBuiltInType("image"); // true
|
|
236
|
+
isGenericObject(node); // true for object-like nodes without fields array
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
#### Constants
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
import {
|
|
243
|
+
BUILT_IN_TYPE_FIELDS,
|
|
244
|
+
ARRAY_ITEM_SYSTEM_FIELDS,
|
|
245
|
+
} from "@sanity/agent-schema";
|
|
246
|
+
|
|
247
|
+
BUILT_IN_TYPE_FIELDS.slug.current; // { name: "current", type: "string" }
|
|
248
|
+
ARRAY_ITEM_SYSTEM_FIELDS._key; // { name: "_key", type: "string" }
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Types
|
|
252
|
+
|
|
253
|
+
| Type | Description |
|
|
254
|
+
| --------------------------- | --------------------------------------------------------------- |
|
|
255
|
+
| `ManifestSchemaType` | A parsed schema type (document, object, array, etc.) |
|
|
256
|
+
| `ManifestField` | A field definition (ManifestSchemaType with optional fieldset) |
|
|
257
|
+
| `DatasetStats` | `{ documentCount?, referenceCount? }` |
|
|
258
|
+
| `CompressedSchemaOptions` | Options for `compressedSchema()` (filter, datasetStats, fields) |
|
|
259
|
+
| `SchemaFilter` | `{ read?, write? }` GROQ filter or `string[]` of type names |
|
|
260
|
+
| `FullSchemaOptions` | Options for `fullSchema()` |
|
|
261
|
+
| `SchemaFieldDisplayOptions` | Options for field display in `compressedSchema` |
|
|
262
|
+
| `SchemaCache` | Cache adapter for `fetchSchemaByDescriptorId` |
|
|
263
|
+
|
|
264
|
+
## Architecture
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
fetchSchemaByDescriptorId() fetchDatasetStats()
|
|
268
|
+
│ │
|
|
269
|
+
▼ │
|
|
270
|
+
ManifestSchemaType[] │
|
|
271
|
+
│ │
|
|
272
|
+
├──► compressedSchema() ──► text summary of all types
|
|
273
|
+
├──► fullSchema() ──► JSON subtree of one type (all fields expanded)
|
|
274
|
+
├──► resolveFieldSchema() ──► single field definition at a path
|
|
275
|
+
├──► resolveFieldSchemaAllUnions() ──► same, all union branches
|
|
276
|
+
└──► processSchema() ──► categorize types, expand fields, compute refs
|
|
277
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { SanityClient } from "@sanity/client";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
type ManifestSerializable = string | number | boolean | {
|
|
4
|
+
[k: string]: ManifestSerializable;
|
|
5
|
+
} | ManifestSerializable[];
|
|
6
|
+
type ManifestSchemaType = {
|
|
7
|
+
type: string;
|
|
8
|
+
name: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
deprecated?: {
|
|
12
|
+
reason: string;
|
|
13
|
+
};
|
|
14
|
+
readOnly?: boolean | 'conditional';
|
|
15
|
+
hidden?: boolean | 'conditional';
|
|
16
|
+
validation?: ManifestValidationGroup[];
|
|
17
|
+
fields?: ManifestField[];
|
|
18
|
+
to?: ManifestReferenceMember[];
|
|
19
|
+
of?: ManifestArrayMember[];
|
|
20
|
+
preview?: {
|
|
21
|
+
select: Record<string, string>;
|
|
22
|
+
};
|
|
23
|
+
fieldsets?: ManifestFieldset[];
|
|
24
|
+
options?: Record<string, ManifestSerializable>;
|
|
25
|
+
marks?: {
|
|
26
|
+
annotations?: ManifestArrayMember[];
|
|
27
|
+
decorators?: ManifestTitledValue[];
|
|
28
|
+
};
|
|
29
|
+
lists?: ManifestTitledValue[];
|
|
30
|
+
styles?: ManifestTitledValue[];
|
|
31
|
+
[index: string]: unknown;
|
|
32
|
+
};
|
|
33
|
+
type ManifestFieldset = {
|
|
34
|
+
name: string;
|
|
35
|
+
title?: string;
|
|
36
|
+
[index: string]: ManifestSerializable | undefined;
|
|
37
|
+
};
|
|
38
|
+
type ManifestTitledValue = {
|
|
39
|
+
value: string;
|
|
40
|
+
title?: string;
|
|
41
|
+
};
|
|
42
|
+
type ManifestField = ManifestSchemaType & {
|
|
43
|
+
fieldset?: string;
|
|
44
|
+
};
|
|
45
|
+
type ManifestArrayMember = Omit<ManifestSchemaType, 'name'> & {
|
|
46
|
+
name?: string;
|
|
47
|
+
};
|
|
48
|
+
type ManifestReferenceMember = Omit<ManifestSchemaType, 'name'> & {
|
|
49
|
+
name?: string;
|
|
50
|
+
};
|
|
51
|
+
type ManifestValidationGroup = {
|
|
52
|
+
rules: ManifestValidationRule[];
|
|
53
|
+
message?: string;
|
|
54
|
+
level?: 'error' | 'warning' | 'info';
|
|
55
|
+
};
|
|
56
|
+
type ManifestValidationRule = {
|
|
57
|
+
flag: 'presence' | string;
|
|
58
|
+
constraint?: 'required' | ManifestSerializable;
|
|
59
|
+
[index: string]: ManifestSerializable | undefined;
|
|
60
|
+
};
|
|
61
|
+
type HoistedEntry = {
|
|
62
|
+
name: string;
|
|
63
|
+
typeDef: TypeDef;
|
|
64
|
+
groups?: unknown;
|
|
65
|
+
fieldset?: unknown;
|
|
66
|
+
};
|
|
67
|
+
type HoistedMarker = {
|
|
68
|
+
__type: 'hoisted';
|
|
69
|
+
key: string;
|
|
70
|
+
};
|
|
71
|
+
type InlineOrHoisted = {
|
|
72
|
+
name: string;
|
|
73
|
+
typeDef: TypeDef;
|
|
74
|
+
} | HoistedMarker;
|
|
75
|
+
type LexiconResponse = {
|
|
76
|
+
types: Record<string, TypeDef>;
|
|
77
|
+
hoisted: Record<string, HoistedEntry>;
|
|
78
|
+
registries?: string[];
|
|
79
|
+
};
|
|
80
|
+
type TypeDef = {
|
|
81
|
+
extends: string;
|
|
82
|
+
fields?: InlineOrHoisted[];
|
|
83
|
+
to?: Array<{
|
|
84
|
+
name: string;
|
|
85
|
+
}>;
|
|
86
|
+
of?: InlineOrHoisted[];
|
|
87
|
+
fieldsets?: string[];
|
|
88
|
+
validation?: unknown;
|
|
89
|
+
[key: string]: unknown;
|
|
90
|
+
};
|
|
91
|
+
declare const DatasetStatsSchema: z.ZodObject<{
|
|
92
|
+
documentCount: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
93
|
+
referenceCount: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
94
|
+
incoming: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"unknown">]>>;
|
|
95
|
+
outgoing: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"unknown">]>>;
|
|
96
|
+
}, "strip", z.ZodTypeAny, {
|
|
97
|
+
incoming: Record<string, number | "unknown">;
|
|
98
|
+
outgoing: Record<string, number | "unknown">;
|
|
99
|
+
}, {
|
|
100
|
+
incoming: Record<string, number | "unknown">;
|
|
101
|
+
outgoing: Record<string, number | "unknown">;
|
|
102
|
+
}>>>;
|
|
103
|
+
}, "strip", z.ZodTypeAny, {
|
|
104
|
+
documentCount?: Record<string, number> | undefined;
|
|
105
|
+
referenceCount?: Record<string, {
|
|
106
|
+
incoming: Record<string, number | "unknown">;
|
|
107
|
+
outgoing: Record<string, number | "unknown">;
|
|
108
|
+
}> | undefined;
|
|
109
|
+
}, {
|
|
110
|
+
documentCount?: Record<string, number> | undefined;
|
|
111
|
+
referenceCount?: Record<string, {
|
|
112
|
+
incoming: Record<string, number | "unknown">;
|
|
113
|
+
outgoing: Record<string, number | "unknown">;
|
|
114
|
+
}> | undefined;
|
|
115
|
+
}>;
|
|
116
|
+
type DatasetStats = z.infer<typeof DatasetStatsSchema>;
|
|
117
|
+
type ReferenceInfo = {
|
|
118
|
+
type: string;
|
|
119
|
+
path: string;
|
|
120
|
+
};
|
|
121
|
+
type ProcessedDocumentType = {
|
|
122
|
+
name: string;
|
|
123
|
+
title?: string;
|
|
124
|
+
description?: string;
|
|
125
|
+
deprecated?: {
|
|
126
|
+
reason: string;
|
|
127
|
+
};
|
|
128
|
+
titleField: string;
|
|
129
|
+
fields: ManifestField[];
|
|
130
|
+
outgoingReferences: string[];
|
|
131
|
+
incomingReferences: string[];
|
|
132
|
+
outgoingReferencePaths?: ReferenceInfo[];
|
|
133
|
+
incomingReferencePaths?: ReferenceInfo[];
|
|
134
|
+
};
|
|
135
|
+
type SchemaTypes = {
|
|
136
|
+
documentTypes: Map<string, ProcessedDocumentType>;
|
|
137
|
+
objectTypes: Map<string, ManifestSchemaType>;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Filter document types by GROQ expressions or an explicit list.
|
|
141
|
+
* - `{ read?, write? }` — GROQ boolean expressions (requires groq-js peer dep).
|
|
142
|
+
* Types matching either expression are included (union).
|
|
143
|
+
* - `string[]` — explicit list of document type names to include.
|
|
144
|
+
* - `undefined` / empty — include all document types.
|
|
145
|
+
*/
|
|
146
|
+
type SchemaFilter = {
|
|
147
|
+
read?: string;
|
|
148
|
+
write?: string;
|
|
149
|
+
} | string[];
|
|
150
|
+
type SchemaFieldDisplayOptions = {
|
|
151
|
+
showAll?: boolean;
|
|
152
|
+
maxCount?: number;
|
|
153
|
+
includeDescription?: boolean;
|
|
154
|
+
includeHidden?: boolean;
|
|
155
|
+
includeDeprecated?: boolean;
|
|
156
|
+
maxEnumValues?: number;
|
|
157
|
+
maxDescriptionLength?: number;
|
|
158
|
+
};
|
|
159
|
+
type CompressedSchemaOptions = {
|
|
160
|
+
datasetStats?: DatasetStats;
|
|
161
|
+
filter?: SchemaFilter;
|
|
162
|
+
fields?: SchemaFieldDisplayOptions;
|
|
163
|
+
};
|
|
164
|
+
type SchemaProcessorOptions = {
|
|
165
|
+
filter?: SchemaFilter;
|
|
166
|
+
fields?: SchemaFieldDisplayOptions;
|
|
167
|
+
};
|
|
168
|
+
type DatasetStatsResult = {
|
|
169
|
+
status: 'ready';
|
|
170
|
+
stats: DatasetStats;
|
|
171
|
+
} | {
|
|
172
|
+
status: 'processing';
|
|
173
|
+
};
|
|
174
|
+
type FetchDatasetStatsOptions = {
|
|
175
|
+
organizationId: string;
|
|
176
|
+
projectId: string;
|
|
177
|
+
dataset: string;
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* Fetches dataset stats (document counts, reference counts) from the agent API.
|
|
181
|
+
*
|
|
182
|
+
* Returns `{ status: 'processing' }` if stats are still being computed (HTTP 202).
|
|
183
|
+
* The caller should retry after a short delay.
|
|
184
|
+
*
|
|
185
|
+
* The `client` should be configured to point at the agent API host
|
|
186
|
+
* (e.g. `api.sanity.io`) with `useProjectHostname: false`.
|
|
187
|
+
*/
|
|
188
|
+
declare function fetchDatasetStats(client: SanityClient, options: FetchDatasetStatsOptions): Promise<DatasetStatsResult>;
|
|
189
|
+
/**
|
|
190
|
+
* Cache adapter for raw Lexicon API responses.
|
|
191
|
+
* Wire this to any backing store (Redis, in-memory Map, etc.).
|
|
192
|
+
*/
|
|
193
|
+
type SchemaCache = {
|
|
194
|
+
get: (descriptorId: string) => Promise<LexiconResponse | null | undefined>;
|
|
195
|
+
set: (descriptorId: string, response: LexiconResponse) => Promise<void>;
|
|
196
|
+
};
|
|
197
|
+
type FetchSchemaOptions = {
|
|
198
|
+
/**
|
|
199
|
+
* Enable caching of raw Lexicon responses.
|
|
200
|
+
* - `true` uses a built-in in-memory cache with a 5-minute TTL
|
|
201
|
+
* - A `SchemaCache` adapter delegates to any external store (Redis, etc.)
|
|
202
|
+
*/
|
|
203
|
+
cache?: boolean | SchemaCache; /** Cache TTL in milliseconds (default 5 min). Only applies to the built-in memory cache. */
|
|
204
|
+
ttlMs?: number;
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* Fetches and parses a schema from the Lexicon descriptor API.
|
|
208
|
+
*
|
|
209
|
+
* Takes a configured `@sanity/client` instance (which handles auth, host, timeouts)
|
|
210
|
+
* and a descriptor ID. Returns the fully parsed ManifestSchemaType array.
|
|
211
|
+
*
|
|
212
|
+
* Pass `{ cache: true }` to enable in-memory caching (5 min TTL),
|
|
213
|
+
* or provide a custom `SchemaCache` adapter for external stores.
|
|
214
|
+
*/
|
|
215
|
+
declare function fetchSchemaByDescriptorId(client: SanityClient, descriptorId: string, options?: FetchSchemaOptions): Promise<ManifestSchemaType[]>;
|
|
216
|
+
/**
|
|
217
|
+
* Processes a ManifestSchemaType[] into categorized document/object types
|
|
218
|
+
* with expanded fields, computed references, and identified title fields.
|
|
219
|
+
*/
|
|
220
|
+
declare function processSchema(schema: ManifestSchemaType[], options?: SchemaProcessorOptions): SchemaTypes;
|
|
221
|
+
/**
|
|
222
|
+
* Built-in Sanity type fields that exist implicitly (not in schema).
|
|
223
|
+
* Maps type name to field definitions.
|
|
224
|
+
*/
|
|
225
|
+
declare const BUILT_IN_TYPE_FIELDS: Record<string, Record<string, ManifestSchemaType>>;
|
|
226
|
+
/**
|
|
227
|
+
* Default annotation type for Portable Text blocks.
|
|
228
|
+
* Sanity implicitly includes "link" when no marks.annotations are declared.
|
|
229
|
+
*/
|
|
230
|
+
declare const DEFAULT_LINK_ANNOTATION: ManifestSchemaType;
|
|
231
|
+
/**
|
|
232
|
+
* System fields that exist on all array items.
|
|
233
|
+
*/
|
|
234
|
+
declare const ARRAY_ITEM_SYSTEM_FIELDS: Record<string, ManifestSchemaType>;
|
|
235
|
+
/**
|
|
236
|
+
* Filter a schema type to a specific field path.
|
|
237
|
+
* Supports complex path navigation including:
|
|
238
|
+
* - Dot notation: "author.person"
|
|
239
|
+
* - Array notation: "content[]"
|
|
240
|
+
* - Array item navigation: "content[].image"
|
|
241
|
+
* - of[N] indexed navigation: "of[0]", "content.of[1]"
|
|
242
|
+
* - Property navigation: "of[0].marks", "of[0].marks.annotations"
|
|
243
|
+
*
|
|
244
|
+
* @param type - The schema type to filter
|
|
245
|
+
* @param path - The path to filter to
|
|
246
|
+
* @param schema - Full schema array to resolve type references
|
|
247
|
+
* @returns A modified type containing only the specified field path, or a not-found marker
|
|
248
|
+
*/
|
|
249
|
+
declare function filterToPath(type: ManifestSchemaType, path: string, schema: ManifestSchemaType[]): ManifestSchemaType;
|
|
250
|
+
/**
|
|
251
|
+
* Resolves a document path to field schemas, returning ALL possible schemas for union types.
|
|
252
|
+
* This is important for arrays with multiple `of` types where a field might exist
|
|
253
|
+
* in some but not all union types.
|
|
254
|
+
*/
|
|
255
|
+
declare function resolveFieldSchemaAllUnions(path: string, typeSchema: ManifestSchemaType, schema: ManifestSchemaType[]): ManifestSchemaType[];
|
|
256
|
+
/**
|
|
257
|
+
* Resolves a document path to the field schema at that location.
|
|
258
|
+
* Handles nested paths like "author.name" and array paths like "tags[0]".
|
|
259
|
+
*
|
|
260
|
+
* Returns the field schema at the path, NOT navigating into arrays.
|
|
261
|
+
* For "tags" (an array field), returns the array field schema (with 'of').
|
|
262
|
+
* For "tags[0].foo", returns the "foo" field from the array item schema.
|
|
263
|
+
*/
|
|
264
|
+
declare function resolveFieldSchema(path: string, typeSchema: ManifestSchemaType, schema: ManifestSchemaType[]): ManifestSchemaType | null;
|
|
265
|
+
/**
|
|
266
|
+
* Convert a document path string to a schema path string.
|
|
267
|
+
* Strips array indices, _key selectors, and internal markers.
|
|
268
|
+
*
|
|
269
|
+
* Examples:
|
|
270
|
+
* - `"content[_key==\"abc\"].children[0].text"` → `"content.children.text"`
|
|
271
|
+
* - `"tags[0]"` → `"tags"`
|
|
272
|
+
* - `"seo.image.asset"` → `"seo.image.asset"`
|
|
273
|
+
* - `"items[append:3]"` → `"items"`
|
|
274
|
+
*
|
|
275
|
+
* This is a self-contained implementation that avoids depending on
|
|
276
|
+
* `@sanity/types` for path segment parsing.
|
|
277
|
+
*/
|
|
278
|
+
declare function toSchemaPath(path: string): string;
|
|
279
|
+
/**
|
|
280
|
+
* Check if a type name represents a primitive type.
|
|
281
|
+
*
|
|
282
|
+
* When `includeBlockTypes` is true, 'block' and 'reference' are also
|
|
283
|
+
* considered primitive (useful for navigator/large-node detection where
|
|
284
|
+
* you don't want to drill into these).
|
|
285
|
+
*/
|
|
286
|
+
declare function isPrimitiveType(typeName: string | undefined, options?: {
|
|
287
|
+
includeBlockTypes?: boolean;
|
|
288
|
+
}): boolean;
|
|
289
|
+
/**
|
|
290
|
+
* Check if a type is a built-in Sanity type (superset of primitives).
|
|
291
|
+
* Includes complex built-in types like array, object, image, file, slug, etc.
|
|
292
|
+
*/
|
|
293
|
+
declare function isBuiltInType(type: string): boolean;
|
|
294
|
+
/**
|
|
295
|
+
* Check if a node is a generic object-like node.
|
|
296
|
+
* Generic objects are objects that don't have a `fields` array and
|
|
297
|
+
* aren't array types with `of`. These include block types and other
|
|
298
|
+
* object-shaped schemas with properties like marks, lists, styles, etc.
|
|
299
|
+
*/
|
|
300
|
+
declare function isGenericObject(node: unknown): boolean;
|
|
301
|
+
type FullSchemaOptions = {
|
|
302
|
+
/** The document type name to return (e.g. "post"). */type: string; /** Optional field path to scope the result (e.g. "content" or "content[].codeBlock"). */
|
|
303
|
+
path?: string; /** Size threshold in bytes before returning a navigator instead of the full JSON (default 200KB). */
|
|
304
|
+
sizeThreshold?: number;
|
|
305
|
+
};
|
|
306
|
+
type LargeNodeNavigator = {
|
|
307
|
+
_rawLargeNode: true;
|
|
308
|
+
name: string;
|
|
309
|
+
type: string;
|
|
310
|
+
children: Array<{
|
|
311
|
+
type: string;
|
|
312
|
+
path: string;
|
|
313
|
+
}>;
|
|
314
|
+
hint: string;
|
|
315
|
+
};
|
|
316
|
+
/**
|
|
317
|
+
* Returns the complete JSON structure for a specific document type, optionally
|
|
318
|
+
* scoped to a field path. Internal/system types are filtered out.
|
|
319
|
+
*
|
|
320
|
+
* When the JSON output exceeds `sizeThreshold`, a navigator object is returned
|
|
321
|
+
* instead — listing child paths the caller can drill into.
|
|
322
|
+
*
|
|
323
|
+
* This is the counterpart to `compressedSchema`:
|
|
324
|
+
* - `compressedSchema` → lossy text summary for LLM context windows
|
|
325
|
+
* - `fullSchema` → complete JSON for schema explorer tools and mutation agents
|
|
326
|
+
*/
|
|
327
|
+
declare function fullSchema(schema: ManifestSchemaType[], options: FullSchemaOptions): Record<string, unknown> | LargeNodeNavigator;
|
|
328
|
+
declare const SCHEMA_CONSTANTS: {
|
|
329
|
+
readonly SKIP_PATTERNS: RegExp;
|
|
330
|
+
readonly TITLE_FIELD_CANDIDATES: readonly ["title", "name", "heading", "label"];
|
|
331
|
+
readonly DEFAULT_OPTIONS: {
|
|
332
|
+
readonly trackPaths: boolean;
|
|
333
|
+
readonly maxExpansionDepth: number;
|
|
334
|
+
};
|
|
335
|
+
readonly DEFAULTS: {
|
|
336
|
+
readonly titleField: "title";
|
|
337
|
+
readonly fallbackTitleField: "_id";
|
|
338
|
+
readonly maxFieldsInSummary: number;
|
|
339
|
+
readonly maxEnumValues: number;
|
|
340
|
+
readonly maxDescriptionLength: number;
|
|
341
|
+
readonly maxDocDescriptionLength: number;
|
|
342
|
+
};
|
|
343
|
+
};
|
|
344
|
+
declare function shouldSkipType(typeName: string): boolean;
|
|
345
|
+
/**
|
|
346
|
+
* Generates a compressed text representation of a schema for agent consumption.
|
|
347
|
+
*
|
|
348
|
+
* Takes parsed schema types and returns compact text summarizing document types,
|
|
349
|
+
* fields, references, and optionally document/reference counts.
|
|
350
|
+
*
|
|
351
|
+
* The `filter` option accepts either a GROQ filter `{ read?, write? }` or
|
|
352
|
+
* a pre-resolved `string[]` of document type names.
|
|
353
|
+
*/
|
|
354
|
+
declare function compressedSchema(types: ManifestSchemaType[], options?: CompressedSchemaOptions): Promise<string>;
|
|
355
|
+
export { ARRAY_ITEM_SYSTEM_FIELDS, BUILT_IN_TYPE_FIELDS, type CompressedSchemaOptions, DEFAULT_LINK_ANNOTATION, type DatasetStats, DatasetStatsSchema, type FetchSchemaOptions, type FullSchemaOptions, type ManifestField, type ManifestSchemaType, type ProcessedDocumentType, SCHEMA_CONSTANTS, type SchemaCache, type SchemaFieldDisplayOptions, type SchemaFilter, type SchemaTypes, compressedSchema, fetchDatasetStats, fetchSchemaByDescriptorId, filterToPath, fullSchema, isBuiltInType, isGenericObject, isPrimitiveType, resolveFieldSchema as navigateToFieldSchema, resolveFieldSchema, resolveFieldSchemaAllUnions as navigateToFieldSchemaAllUnions, resolveFieldSchemaAllUnions, processSchema, shouldSkipType, toSchemaPath };
|
|
356
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/fetchDatasetStats.ts","../src/fetchSchemaByDescriptorId.ts","../src/processSchema.ts","../src/navigate/constants.ts","../src/navigate/filterToPath.ts","../src/navigate/navigateAllUnions.ts","../src/navigate/navigateToField.ts","../src/navigate/path.ts","../src/navigate/types.ts","../src/fullSchema.ts","../src/constants.ts","../src/utils.ts","../src/index.ts"],"mappings":"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"}
|