@sanity/assist 1.0.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.
Files changed (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +205 -0
  3. package/dist/index.d.ts +52 -0
  4. package/dist/index.esm.js +2341 -0
  5. package/dist/index.esm.js.map +1 -0
  6. package/dist/index.js +2341 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +98 -0
  9. package/sanity.json +8 -0
  10. package/src/_lib/connector/ConnectFromRegion.tsx +24 -0
  11. package/src/_lib/connector/ConnectToRegion.tsx +22 -0
  12. package/src/_lib/connector/ConnectorRegion.tsx +23 -0
  13. package/src/_lib/connector/ConnectorsProvider.tsx +19 -0
  14. package/src/_lib/connector/ConnectorsStore.ts +122 -0
  15. package/src/_lib/connector/ConnectorsStoreContext.ts +4 -0
  16. package/src/_lib/connector/helpers.ts +5 -0
  17. package/src/_lib/connector/index.ts +9 -0
  18. package/src/_lib/connector/mapConnectorToLine.ts +83 -0
  19. package/src/_lib/connector/types.ts +56 -0
  20. package/src/_lib/connector/useConnectorsStore.ts +13 -0
  21. package/src/_lib/connector/useRegionRects.ts +141 -0
  22. package/src/_lib/fixedListenQuery.ts +101 -0
  23. package/src/_lib/form/DocumentForm.tsx +197 -0
  24. package/src/_lib/form/helpers.ts +31 -0
  25. package/src/_lib/form/index.ts +1 -0
  26. package/src/_lib/randomKey.ts +29 -0
  27. package/src/_lib/useListeningQuery.ts +61 -0
  28. package/src/_lib/usePrevious.ts +9 -0
  29. package/src/assistConnectors/AssistConnectorsOverlay.tsx +132 -0
  30. package/src/assistConnectors/ConnectorPath.tsx +62 -0
  31. package/src/assistConnectors/draw/arrowPath.ts +9 -0
  32. package/src/assistConnectors/draw/connectorPath.ts +142 -0
  33. package/src/assistConnectors/index.ts +1 -0
  34. package/src/assistDocument/AssistDocumentContext.tsx +31 -0
  35. package/src/assistDocument/AssistDocumentContextProvider.tsx +17 -0
  36. package/src/assistDocument/AssistDocumentInput.tsx +46 -0
  37. package/src/assistDocument/RequestRunInstructionProvider.tsx +50 -0
  38. package/src/assistDocument/components/AssistDocumentForm.tsx +188 -0
  39. package/src/assistDocument/components/FieldRefPreview.tsx +27 -0
  40. package/src/assistDocument/components/InstructionsArrayField.tsx +8 -0
  41. package/src/assistDocument/components/InstructionsArrayInput.tsx +26 -0
  42. package/src/assistDocument/components/SelectedFieldContext.tsx +10 -0
  43. package/src/assistDocument/components/generic/HiddenFieldTitle.tsx +5 -0
  44. package/src/assistDocument/components/helpers.ts +21 -0
  45. package/src/assistDocument/components/instruction/BackToInstructionsLink.tsx +31 -0
  46. package/src/assistDocument/components/instruction/FieldRefInput.tsx +33 -0
  47. package/src/assistDocument/components/instruction/InstructionInput.tsx +87 -0
  48. package/src/assistDocument/components/instruction/PromptInput.tsx +52 -0
  49. package/src/assistDocument/components/instruction/appearance/IconInput.tsx +46 -0
  50. package/src/assistDocument/components/instruction/appearance/InstructionVisibility.tsx +37 -0
  51. package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +68 -0
  52. package/src/assistDocument/hooks/useDocumentState.ts +6 -0
  53. package/src/assistDocument/hooks/useInstructionToaster.tsx +74 -0
  54. package/src/assistDocument/hooks/useStudioAssistDocument.ts +119 -0
  55. package/src/assistDocument/index.ts +1 -0
  56. package/src/assistFormComponents/AssistField.tsx +51 -0
  57. package/src/assistFormComponents/AssistFormBlock.tsx +31 -0
  58. package/src/assistFormComponents/AssistInlineFormBlock.tsx +14 -0
  59. package/src/assistFormComponents/AssistItem.tsx +20 -0
  60. package/src/assistFormComponents/validation/listItem.tsx +63 -0
  61. package/src/assistFormComponents/validation/validationList.tsx +89 -0
  62. package/src/assistInspector/AssistInspector.tsx +379 -0
  63. package/src/assistInspector/FieldAutocomplete.tsx +119 -0
  64. package/src/assistInspector/InstructionTaskHistoryButton.tsx +261 -0
  65. package/src/assistInspector/constants.ts +1 -0
  66. package/src/assistInspector/helpers.ts +125 -0
  67. package/src/assistInspector/index.ts +26 -0
  68. package/src/assistLayout/AiAssistanceConfigContext.tsx +81 -0
  69. package/src/assistLayout/AlphaMigration.tsx +311 -0
  70. package/src/assistLayout/AssistLayout.tsx +38 -0
  71. package/src/assistLayout/RunInstructionProvider.tsx +222 -0
  72. package/src/components/AssistFeatureBadge.tsx +9 -0
  73. package/src/components/Delay.tsx +25 -0
  74. package/src/components/HideReferenceChangedBannerInput.tsx +25 -0
  75. package/src/components/SafeValueInput.tsx +73 -0
  76. package/src/components/TimeAgo.tsx +18 -0
  77. package/src/constants.ts +20 -0
  78. package/src/fieldActions/PrivateIcon.tsx +20 -0
  79. package/src/fieldActions/assistFieldActions.tsx +230 -0
  80. package/src/globals.d.ts +4 -0
  81. package/src/helpers/assistSupported.ts +44 -0
  82. package/src/helpers/ids.ts +19 -0
  83. package/src/helpers/misc.ts +16 -0
  84. package/src/helpers/typeUtils.ts +15 -0
  85. package/src/helpers/useAssistSupported.ts +10 -0
  86. package/src/index.ts +6 -0
  87. package/src/legacy-types.ts +72 -0
  88. package/src/onboarding/FieldActionsOnboarding.tsx +90 -0
  89. package/src/onboarding/FirstAssistedPathProvider.tsx +29 -0
  90. package/src/onboarding/InspectorOnboarding.tsx +46 -0
  91. package/src/onboarding/onboardingStore.ts +33 -0
  92. package/src/plugin.tsx +80 -0
  93. package/src/presence/AiFieldPresence.tsx +28 -0
  94. package/src/presence/AssistAvatar.tsx +96 -0
  95. package/src/presence/AssistDocumentPresence.tsx +58 -0
  96. package/src/presence/useAssistPresence.ts +61 -0
  97. package/src/schemas/assistDocumentSchema.tsx +450 -0
  98. package/src/schemas/contextDocumentSchema.tsx +56 -0
  99. package/src/schemas/index.ts +25 -0
  100. package/src/schemas/serialize/SchemTypeTool.tsx +102 -0
  101. package/src/schemas/serialize/schemaUtils.ts +37 -0
  102. package/src/schemas/serialize/serializeSchema.test.ts +382 -0
  103. package/src/schemas/serialize/serializeSchema.ts +162 -0
  104. package/src/schemas/serializedSchemaTypeSchema.ts +59 -0
  105. package/src/schemas/typeDefExtensions.ts +30 -0
  106. package/src/types.ts +167 -0
  107. package/src/useApiClient.ts +140 -0
  108. package/src/vite.config.ts +9 -0
  109. package/v2-incompatible.js +11 -0
@@ -0,0 +1,382 @@
1
+ import {describe, expect, test} from 'vitest'
2
+ import {Schema} from '@sanity/schema'
3
+ import {serializeSchema} from './serializeSchema'
4
+ import {defineArrayMember, defineField, defineType} from 'sanity'
5
+ import {AssistOptions} from '../typeDefExtensions'
6
+
7
+ const mockStudioTypes = [
8
+ defineField({
9
+ type: 'object',
10
+ name: 'slug',
11
+ fields: [{type: 'string', name: '_ref'}],
12
+ }),
13
+ defineField({
14
+ type: 'object',
15
+ name: 'sanity.imageHotspot',
16
+ fields: [{type: 'string', name: 'whatever'}],
17
+ }),
18
+ defineField({
19
+ type: 'object',
20
+ name: 'sanity.imageCrop',
21
+ fields: [{type: 'string', name: 'whatever'}],
22
+ }),
23
+ ]
24
+
25
+ describe('serializeSchema', () => {
26
+ test('should serialize simple schema', () => {
27
+ const schema = Schema.compile({
28
+ name: 'test',
29
+ types: [
30
+ {
31
+ type: 'document',
32
+ name: 'article',
33
+ fields: [
34
+ {type: 'string', name: 'title'},
35
+ {type: 'some', name: 'some'},
36
+ {
37
+ name: 'array',
38
+ of: [{type: 'some'}],
39
+ type: 'array',
40
+ },
41
+ ],
42
+ },
43
+ {
44
+ type: 'object',
45
+ name: 'some',
46
+ fields: [{type: 'string', name: 'title'}],
47
+ },
48
+ ],
49
+ })
50
+
51
+ const serializedTypes = serializeSchema(schema, {leanFormat: true})
52
+
53
+ expect(serializedTypes).toEqual([
54
+ {
55
+ fields: [
56
+ {name: 'title', title: 'Title', type: 'string'},
57
+ {name: 'some', title: 'Some', type: 'some'},
58
+ {
59
+ name: 'array',
60
+ of: [{name: 'some', title: 'Some', type: 'some'}],
61
+ title: 'Array',
62
+ type: 'array',
63
+ },
64
+ ],
65
+ name: 'article',
66
+ title: 'Article',
67
+ type: 'document',
68
+ },
69
+ {
70
+ fields: [{name: 'title', title: 'Title', type: 'string'}],
71
+ name: 'some',
72
+ title: 'Some',
73
+ type: 'object',
74
+ },
75
+ ])
76
+ })
77
+
78
+ test('should not serialize excluded fields or types or types with every member excluded', () => {
79
+ const options: AssistOptions = {aiWritingAssistance: {exclude: true}}
80
+
81
+ const schema = Schema.compile({
82
+ name: 'test',
83
+ types: [
84
+ {
85
+ type: 'document',
86
+ name: 'allFieldsExcluded',
87
+ fields: [
88
+ defineField({type: 'string', name: 'title', options}),
89
+ defineField({
90
+ type: 'object',
91
+ name: 'excludedObject',
92
+ // all fields excluded should exclude field
93
+ fields: [{type: 'string', name: 'title', options}],
94
+ options: {aiWritingAssistance: {exclude: true}},
95
+ }),
96
+ defineField({
97
+ type: 'array',
98
+ name: 'excludedArray',
99
+ // all items excluded should exclude field
100
+ of: [{type: 'object', name: 'remove', options}, {type: 'excluded'}],
101
+ options: {aiWritingAssistance: {exclude: true}},
102
+ }),
103
+ //image without extra fields should be excluded
104
+ defineField({type: 'image', name: 'image'}),
105
+ // unsupported types
106
+ defineField({type: 'number', name: 'number'}),
107
+ defineField({type: 'slug', name: 'slug'}),
108
+ defineField({type: 'url', name: 'url'}),
109
+ defineField({type: 'datetime', name: 'datetime'}),
110
+ defineField({type: 'file', name: 'file'}),
111
+ defineField({type: 'reference', name: 'reference', to: [{type: 'excluded'}]}),
112
+ defineField({
113
+ type: 'crossDatasetReference',
114
+ name: 'crossDatasetReference',
115
+ to: [{type: 'excluded'}],
116
+ dataset: 'x',
117
+ projectId: 'y',
118
+ }),
119
+ ],
120
+ },
121
+ defineField({
122
+ type: 'object',
123
+ name: 'excluded',
124
+ fields: [{type: 'string', name: 'title', options}],
125
+ options: {aiWritingAssistance: {exclude: true}},
126
+ }),
127
+ ...mockStudioTypes,
128
+ ],
129
+ })
130
+
131
+ const serializedTypes = serializeSchema(schema, {leanFormat: true})
132
+
133
+ //everything excluded directly or indirectly
134
+ expect(serializedTypes).toEqual([])
135
+ })
136
+
137
+ test('should serialize opt-in inline object using custom typeName', () => {
138
+ const schema = Schema.compile({
139
+ name: 'test',
140
+ types: [
141
+ {
142
+ type: 'document',
143
+ name: 'article',
144
+ fields: [
145
+ {type: 'string', name: 'title'},
146
+ defineField({
147
+ type: 'object',
148
+ name: 'some',
149
+ fields: [{type: 'string', name: 'title'}],
150
+ }),
151
+ defineField({
152
+ type: 'array',
153
+ name: 'array',
154
+ of: [
155
+ defineArrayMember({
156
+ type: 'object',
157
+ name: 'inlineArrayMember',
158
+ fields: [{type: 'string', name: 'title'}],
159
+ }),
160
+ ],
161
+ }),
162
+ ],
163
+ },
164
+ ],
165
+ })
166
+
167
+ const serializedTypes = serializeSchema(schema, {leanFormat: true})
168
+
169
+ expect(serializedTypes).toEqual([
170
+ {
171
+ fields: [
172
+ {name: 'title', title: 'Title', type: 'string'},
173
+ {
174
+ name: 'some',
175
+ title: 'Some',
176
+ type: 'object',
177
+ fields: [{name: 'title', title: 'Title', type: 'string'}],
178
+ },
179
+ {
180
+ name: 'array',
181
+ of: [
182
+ {
183
+ type: 'object',
184
+ name: 'inlineArrayMember',
185
+ title: 'Inline Array Member',
186
+ fields: [{name: 'title', title: 'Title', type: 'string'}],
187
+ },
188
+ ],
189
+ title: 'Array',
190
+ type: 'array',
191
+ },
192
+ ],
193
+ name: 'article',
194
+ title: 'Article',
195
+ type: 'document',
196
+ },
197
+ ])
198
+ })
199
+
200
+ test('should serialize inline object', () => {
201
+ const schema = Schema.compile({
202
+ name: 'test',
203
+ types: [
204
+ {
205
+ type: 'document',
206
+ name: 'article',
207
+ fields: [
208
+ {type: 'string', name: 'title'},
209
+ defineField({
210
+ type: 'object',
211
+ name: 'someObject',
212
+ fields: [{type: 'string', name: 'title'}],
213
+ }),
214
+ defineField({
215
+ type: 'file',
216
+ name: 'someFile',
217
+ fields: [{type: 'string', name: 'title'}],
218
+ }),
219
+ defineField({
220
+ type: 'image',
221
+ name: 'someImage',
222
+ fields: [{type: 'string', name: 'title'}],
223
+ }),
224
+ ],
225
+ },
226
+ ...mockStudioTypes,
227
+ ],
228
+ })
229
+
230
+ const serializedTypes = serializeSchema(schema, {leanFormat: true})
231
+
232
+ expect(serializedTypes).toEqual([
233
+ {
234
+ fields: [
235
+ {name: 'title', title: 'Title', type: 'string'},
236
+ {
237
+ name: 'someObject',
238
+ title: 'Some Object',
239
+ type: 'object',
240
+ fields: [{name: 'title', title: 'Title', type: 'string'}],
241
+ },
242
+ {
243
+ name: 'someImage',
244
+ title: 'Some Image',
245
+ type: 'image',
246
+ fields: [{name: 'title', title: 'Title', type: 'string'}],
247
+ },
248
+ ],
249
+ name: 'article',
250
+ title: 'Article',
251
+ type: 'document',
252
+ },
253
+ ])
254
+ })
255
+
256
+ test('should serialize inline, anonymous array object type', () => {
257
+ const schema = Schema.compile({
258
+ name: 'test',
259
+ types: [
260
+ {
261
+ type: 'document',
262
+ name: 'article',
263
+ fields: [
264
+ {type: 'string', name: 'title'},
265
+ defineField({
266
+ type: 'array',
267
+ name: 'array',
268
+ of: [
269
+ defineArrayMember({
270
+ type: 'object',
271
+ title: 'Nameless item',
272
+ fields: [{type: 'string', name: 'title'}],
273
+ }),
274
+ ],
275
+ }),
276
+ ],
277
+ },
278
+ {
279
+ fields: [{name: 'title', title: 'Title', type: 'string'}],
280
+ name: 'item',
281
+ title: 'Item',
282
+ type: 'object',
283
+ },
284
+ ],
285
+ })
286
+
287
+ const serializedTypes = serializeSchema(schema, {leanFormat: true})
288
+
289
+ expect(serializedTypes).toEqual([
290
+ {
291
+ fields: [
292
+ {name: 'title', title: 'Title', type: 'string'},
293
+ {
294
+ name: 'array',
295
+ of: [
296
+ {
297
+ name: 'object',
298
+ title: 'Nameless item',
299
+ type: 'object',
300
+ fields: [{name: 'title', title: 'Title', type: 'string'}],
301
+ },
302
+ ],
303
+ title: 'Array',
304
+ type: 'array',
305
+ },
306
+ ],
307
+ name: 'article',
308
+ title: 'Article',
309
+ type: 'document',
310
+ },
311
+ {
312
+ fields: [{name: 'title', title: 'Title', type: 'string'}],
313
+ name: 'item',
314
+ title: 'Item',
315
+ type: 'object',
316
+ },
317
+ ])
318
+ })
319
+
320
+ test('should serialize nested inline objects', () => {
321
+ const schema = Schema.compile({
322
+ name: 'test',
323
+ types: [
324
+ {
325
+ type: 'document',
326
+ name: 'article',
327
+ fields: [
328
+ defineField({
329
+ type: 'object',
330
+ name: 'outer',
331
+ fields: [
332
+ defineField({
333
+ type: 'object',
334
+ name: 'inner',
335
+ fields: [{type: 'string', name: 'title'}],
336
+ }),
337
+ ],
338
+ }),
339
+ ],
340
+ },
341
+ ],
342
+ })
343
+
344
+ const serializedTypes = serializeSchema(schema, {leanFormat: true})
345
+
346
+ expect(serializedTypes).toEqual([
347
+ {
348
+ name: 'article',
349
+ title: 'Article',
350
+ type: 'document',
351
+ fields: [
352
+ {
353
+ fields: [
354
+ {
355
+ type: 'object',
356
+ name: 'inner',
357
+ title: 'Inner',
358
+ fields: [{name: 'title', title: 'Title', type: 'string'}],
359
+ },
360
+ ],
361
+ type: 'object',
362
+ name: 'outer',
363
+ title: 'Outer',
364
+ },
365
+ ],
366
+ },
367
+ ])
368
+ })
369
+
370
+ test('should serialize list values', () => {
371
+ const schema = Schema.compile({
372
+ name: 'test',
373
+ types: [defineType({type: 'string', name: 'list', options: {list: ['a', 'b']}})],
374
+ })
375
+
376
+ const serializedTypes = serializeSchema(schema, {leanFormat: true})
377
+
378
+ expect(serializedTypes).toEqual([
379
+ {name: 'list', title: 'String', type: 'string', values: ['a', 'b']},
380
+ ])
381
+ })
382
+ })
@@ -0,0 +1,162 @@
1
+ import {
2
+ ArraySchemaType,
3
+ ImageOptions,
4
+ ObjectSchemaType,
5
+ ReferenceSchemaType,
6
+ Schema,
7
+ SchemaType,
8
+ typed,
9
+ } from 'sanity'
10
+ import {
11
+ assistSerializedFieldTypeName,
12
+ assistSerializedTypeName,
13
+ SerializedSchemaMember,
14
+ SerializedSchemaType,
15
+ assistSchemaIdPrefix,
16
+ } from '../../types'
17
+ import {hiddenTypes} from './schemaUtils'
18
+ import {isAssistSupported} from '../../helpers/assistSupported'
19
+
20
+ interface Options {
21
+ leanFormat?: boolean
22
+ }
23
+
24
+ const inlineTypes = ['document', 'object', 'image', 'file']
25
+
26
+ export function serializeSchema(schema: Schema, options?: Options): SerializedSchemaType[] {
27
+ const list = schema
28
+ .getTypeNames()
29
+ .filter((t) => !(hiddenTypes.includes(t) || t.startsWith('sanity.')))
30
+ .map((t) => schema.get(t))
31
+ .filter((t): t is SchemaType => !!t)
32
+ .map((t) => getSchemaStub(t, schema, options))
33
+ .filter((t) => {
34
+ if ('to' in t && t.to && !t.to.length) {
35
+ return false
36
+ }
37
+ if ('of' in t && t.of && !t.of.length) {
38
+ return false
39
+ }
40
+ if ('fields' in t && t.fields && !t.fields.length) {
41
+ return false
42
+ }
43
+ return true
44
+ })
45
+ list.sort((a, b) => (a?.name ?? '').localeCompare(b?.name ?? ''))
46
+ return list
47
+ }
48
+
49
+ function getSchemaStub(
50
+ schemaType: SchemaType,
51
+ schema: Schema,
52
+ options?: Options
53
+ ): SerializedSchemaType {
54
+ if (!schemaType.type?.name) {
55
+ console.error('Missing type name', schemaType.type)
56
+ throw new Error('Type is missing name!')
57
+ }
58
+ const baseSchema: SerializedSchemaType = {
59
+ // we dont need type or id when we send using POST, so leave these out to save bandwidth
60
+ ...(options?.leanFormat
61
+ ? {}
62
+ : {_id: `${assistSchemaIdPrefix}${schemaType.name}`, _type: assistSerializedTypeName}),
63
+ name: schemaType.name,
64
+ title: schemaType.title,
65
+ type: schemaType.type.name,
66
+ ...getBaseFields(schema, schemaType, schemaType.type.name, options),
67
+ }
68
+
69
+ return removeUndef(baseSchema)
70
+ }
71
+
72
+ function getBaseFields(
73
+ schema: Schema,
74
+ type: SchemaType,
75
+ typeName: string,
76
+ options: Options | undefined
77
+ ) {
78
+ const imagePromptField = (type.options as ImageOptions)?.imagePromptField
79
+ return removeUndef({
80
+ options: imagePromptField
81
+ ? {
82
+ imagePromptField: imagePromptField,
83
+ }
84
+ : undefined,
85
+ values:
86
+ type.jsonType === 'string' && type?.options?.list
87
+ ? type?.options?.list.map((v) => (typeof v === 'string' ? v : v.value ?? `${v.title}`))
88
+ : undefined,
89
+ of: 'of' in type && typeName === 'array' ? arrayOf(type, schema, options) : undefined,
90
+ to:
91
+ 'to' in type && typeName === 'reference'
92
+ ? refToTypeNames(type as ReferenceSchemaType)
93
+ : undefined,
94
+ fields:
95
+ 'fields' in type && inlineTypes.includes(typeName)
96
+ ? serializeFields(schema, type, options)
97
+ : undefined,
98
+ })
99
+ }
100
+
101
+ function serializeFields(
102
+ schema: Schema,
103
+ schemaType: ObjectSchemaType,
104
+ options: Options | undefined
105
+ ) {
106
+ return schemaType.fields
107
+ .filter((f) => !['sanity.imageHotspot', 'sanity.imageCrop'].includes(f.type?.name ?? ''))
108
+ .filter((f) => isAssistSupported(f.type))
109
+ .map((field) => serializeMember(schema, field.type, field.name, options))
110
+ }
111
+
112
+ function serializeMember(
113
+ schema: Schema,
114
+ type: SchemaType,
115
+ name: string,
116
+ options: Options | undefined
117
+ ): SerializedSchemaMember {
118
+ const typeNameExists = !!schema.get(type?.name)
119
+ const typeName = typeNameExists ? type.name : type.type?.name ?? ''
120
+ return removeUndef({
121
+ ...(options?.leanFormat ? {} : {_type: assistSerializedFieldTypeName}),
122
+ name: name,
123
+ type: typeName,
124
+ title: type.title,
125
+ values:
126
+ type.jsonType === 'string' && type?.options?.list
127
+ ? type?.options?.list.map((v) => (typeof v === 'string' ? v : v.value ?? `${v.title}`))
128
+ : undefined,
129
+ of: 'of' in type && type.name === 'array' ? arrayOf(type, schema, options) : undefined,
130
+ to:
131
+ 'to' in type && type.name === 'reference'
132
+ ? refToTypeNames(type as ReferenceSchemaType)
133
+ : undefined,
134
+ fields:
135
+ 'fields' in type && inlineTypes.includes(typeName)
136
+ ? serializeFields(schema, type, options)
137
+ : undefined,
138
+ })
139
+ }
140
+
141
+ function arrayOf(
142
+ arrayType: ArraySchemaType,
143
+ schema: Schema,
144
+ options: Options | undefined
145
+ ): SerializedSchemaMember[] {
146
+ return arrayType.of
147
+ .filter((type) => isAssistSupported(type))
148
+ .map((t) => {
149
+ return serializeMember(schema, t, t.name, options)
150
+ })
151
+ }
152
+
153
+ function refToTypeNames(type: ReferenceSchemaType) {
154
+ return type.to.map((t) => ({
155
+ type: typed<string>(t.name),
156
+ }))
157
+ }
158
+
159
+ function removeUndef<T extends Record<string, any>>(obj: T): T {
160
+ Object.keys(obj).forEach((key) => (obj[key] === undefined ? delete obj[key] : {}))
161
+ return obj
162
+ }
@@ -0,0 +1,59 @@
1
+ import {defineField, defineType} from 'sanity'
2
+ import {assistSerializedFieldTypeName, assistSerializedTypeName} from '../types'
3
+ import {CodeIcon, StarIcon} from '@sanity/icons'
4
+
5
+ export const serializedSchemaField = defineType({
6
+ type: 'object',
7
+ name: assistSerializedFieldTypeName,
8
+ title: 'Field',
9
+ icon: CodeIcon,
10
+ fields: [
11
+ defineField({
12
+ name: 'name',
13
+ title: 'Name',
14
+ type: 'string',
15
+ }),
16
+ defineField({
17
+ name: 'type',
18
+ title: 'Type',
19
+ type: 'string',
20
+ }),
21
+ ],
22
+ preview: {
23
+ select: {
24
+ title: 'title',
25
+ subtitle: 'type',
26
+ },
27
+ prepare: ({title, subtitle}) => {
28
+ return {
29
+ title,
30
+ subtitle,
31
+ media: CodeIcon,
32
+ }
33
+ },
34
+ },
35
+ })
36
+
37
+ export const serializedSchemaType = defineType({
38
+ name: assistSerializedTypeName,
39
+ type: 'document',
40
+ title: 'Meta schema',
41
+ icon: StarIcon,
42
+ fields: [
43
+ defineField({
44
+ name: 'name',
45
+ title: 'Name',
46
+ type: 'string',
47
+ }),
48
+ defineField({
49
+ name: 'type',
50
+ title: 'Type',
51
+ type: 'string',
52
+ }),
53
+ defineField({
54
+ name: 'fields',
55
+ type: 'array',
56
+ of: [{type: serializedSchemaField.name}],
57
+ }),
58
+ ],
59
+ })
@@ -0,0 +1,30 @@
1
+ /* eslint-disable no-unused-vars */
2
+ export interface AssistOptions {
3
+ aiWritingAssistance?: {
4
+ /** Set to true to disable assistance for this field or type */
5
+ exclude?: boolean
6
+ }
7
+ }
8
+
9
+ declare module 'sanity' {
10
+ interface ArrayOptions extends AssistOptions {}
11
+ interface BlockOptions extends AssistOptions {}
12
+ interface BooleanOptions extends AssistOptions {}
13
+ interface CrossDatasetReferenceOptions extends AssistOptions {}
14
+ interface DateOptions extends AssistOptions {}
15
+ interface DatetimeOptions extends AssistOptions {}
16
+ interface DocumentOptions extends AssistOptions {}
17
+ interface FileOptions extends AssistOptions {}
18
+ interface GeopointOptions extends AssistOptions {}
19
+ interface ImageOptions extends AssistOptions {
20
+ imagePromptField?: string
21
+ }
22
+ interface NumberOptions extends AssistOptions {}
23
+ interface ObjectOptions extends AssistOptions {}
24
+ interface ReferenceBaseOptions extends AssistOptions {}
25
+ interface SlugOptions extends AssistOptions {}
26
+ interface StringOptions extends AssistOptions {}
27
+ interface TextOptions extends AssistOptions {}
28
+ interface UrlOptions extends AssistOptions {}
29
+ interface EmailOptions extends AssistOptions {}
30
+ }