@sanity/assist 1.2.16 → 2.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/LICENSE +1 -1
- package/README.md +551 -30
- package/dist/index.cjs.mjs +1 -0
- package/dist/index.d.ts +333 -9
- package/dist/index.esm.js +2463 -390
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +2457 -383
- package/dist/index.js.map +1 -1
- package/package.json +12 -11
- package/src/_lib/form/DocumentForm.tsx +2 -1
- package/src/_lib/form/constants.ts +1 -0
- package/src/assistDocument/AssistDocumentInput.tsx +24 -4
- package/src/assistDocument/RequestRunInstructionProvider.tsx +37 -21
- package/src/assistDocument/components/AssistDocumentForm.tsx +65 -21
- package/src/assistDocument/components/instruction/InstructionInput.tsx +5 -4
- package/src/assistDocument/components/instruction/InstructionOutputField.tsx +45 -0
- package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +205 -0
- package/src/assistDocument/hooks/useStudioAssistDocument.ts +5 -32
- package/src/assistFormComponents/AssistField.tsx +11 -5
- package/src/assistFormComponents/AssistFormBlock.tsx +2 -3
- package/src/assistFormComponents/validation/listItem.tsx +2 -2
- package/src/assistInspector/AssistInspector.tsx +6 -0
- package/src/assistInspector/FieldAutocomplete.tsx +1 -0
- package/src/assistInspector/helpers.ts +9 -11
- package/src/assistLayout/AssistLayout.tsx +9 -9
- package/src/components/ImageContext.tsx +30 -13
- package/src/components/SafeValueInput.tsx +4 -1
- package/src/fieldActions/assistFieldActions.tsx +42 -13
- package/src/fieldActions/generateCaptionActions.tsx +17 -6
- package/src/fieldActions/generateImageActions.tsx +57 -0
- package/src/helpers/assistSupported.ts +10 -16
- package/src/helpers/conditionalMembers.test.ts +200 -0
- package/src/helpers/conditionalMembers.ts +127 -0
- package/src/helpers/misc.ts +8 -4
- package/src/helpers/typeUtils.ts +19 -5
- package/src/index.ts +3 -0
- package/src/plugin.tsx +18 -4
- package/src/schemas/assistDocumentSchema.tsx +40 -1
- package/src/schemas/serialize/serializeSchema.test.ts +239 -8
- package/src/schemas/serialize/serializeSchema.ts +77 -10
- package/src/schemas/typeDefExtensions.ts +89 -5
- package/src/translate/FieldTranslationProvider.tsx +360 -0
- package/src/translate/getLanguageParams.ts +26 -0
- package/src/translate/languageStore.ts +18 -0
- package/src/translate/paths.test.ts +133 -0
- package/src/translate/paths.ts +175 -0
- package/src/translate/translateActions.tsx +188 -0
- package/src/translate/types.ts +160 -0
- package/src/types.ts +67 -15
- package/src/useApiClient.ts +134 -2
- package/src/assistLayout/AlphaMigration.tsx +0 -310
- package/src/legacy-types.ts +0 -72
|
@@ -1,41 +1,34 @@
|
|
|
1
|
-
import {SchemaType} from 'sanity'
|
|
1
|
+
import {ReferenceOptions, SchemaType} from 'sanity'
|
|
2
2
|
import {AssistOptions} from '../schemas/typeDefExtensions'
|
|
3
3
|
import {isType} from './typeUtils'
|
|
4
4
|
|
|
5
5
|
export function isSchemaAssistEnabled(type: SchemaType) {
|
|
6
|
-
return !(type.options as AssistOptions | undefined)?.
|
|
6
|
+
return !(type.options as AssistOptions | undefined)?.aiAssist?.exclude
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export function isAssistSupported(type: SchemaType
|
|
9
|
+
export function isAssistSupported(type: SchemaType) {
|
|
10
10
|
if (!isSchemaAssistEnabled(type)) {
|
|
11
11
|
return false
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
if (isDisabled(type
|
|
14
|
+
if (isDisabled(type)) {
|
|
15
15
|
return false
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
if (type.jsonType === 'array') {
|
|
19
|
-
const unsupportedArray = type.of.every((t) => isDisabled(t
|
|
19
|
+
const unsupportedArray = type.of.every((t) => isDisabled(t))
|
|
20
20
|
return !unsupportedArray
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
if (type.jsonType === 'object') {
|
|
24
|
-
const unsupportedObject = type.fields.every((field) =>
|
|
25
|
-
isDisabled(field.type, allowReadonlyHidden)
|
|
26
|
-
)
|
|
24
|
+
const unsupportedObject = type.fields.every((field) => isDisabled(field.type))
|
|
27
25
|
return !unsupportedObject
|
|
28
26
|
}
|
|
29
27
|
return true
|
|
30
28
|
}
|
|
31
29
|
|
|
32
|
-
function isDisabled(type: SchemaType
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
!isSchemaAssistEnabled(type) ||
|
|
36
|
-
isUnsupportedType(type) ||
|
|
37
|
-
(!allowReadonlyHidden && readonlyHidden)
|
|
38
|
-
)
|
|
30
|
+
function isDisabled(type: SchemaType) {
|
|
31
|
+
return !isSchemaAssistEnabled(type) || isUnsupportedType(type)
|
|
39
32
|
}
|
|
40
33
|
|
|
41
34
|
function isUnsupportedType(type: SchemaType) {
|
|
@@ -43,7 +36,8 @@ function isUnsupportedType(type: SchemaType) {
|
|
|
43
36
|
type.jsonType === 'number' ||
|
|
44
37
|
type.name === 'sanity.imageCrop' ||
|
|
45
38
|
type.name === 'sanity.imageHotspot' ||
|
|
46
|
-
isType(type, 'reference')
|
|
39
|
+
(isType(type, 'reference') &&
|
|
40
|
+
!(type?.options as ReferenceOptions)?.aiAssist?.embeddingsIndex) ||
|
|
47
41
|
isType(type, 'crossDatasetReference') ||
|
|
48
42
|
isType(type, 'slug') ||
|
|
49
43
|
isType(type, 'url') ||
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import {describe, expect, test} from 'vitest'
|
|
2
|
+
import {Schema} from '@sanity/schema'
|
|
3
|
+
import {ArraySchemaType, defineField, defineType, ObjectSchemaType} from 'sanity'
|
|
4
|
+
import {getConditionalMembers} from './conditionalMembers'
|
|
5
|
+
|
|
6
|
+
describe('conditionalMembers', () => {
|
|
7
|
+
test('should not include paths without conditional hidden/readonly', () => {
|
|
8
|
+
const docSchema: ObjectSchemaType = Schema.compile({
|
|
9
|
+
name: 'test',
|
|
10
|
+
types: [
|
|
11
|
+
defineType({
|
|
12
|
+
type: 'document',
|
|
13
|
+
name: 'article',
|
|
14
|
+
fields: [{type: 'string', name: 'title'}],
|
|
15
|
+
}),
|
|
16
|
+
],
|
|
17
|
+
}).get('article')
|
|
18
|
+
|
|
19
|
+
const docState = {
|
|
20
|
+
path: [],
|
|
21
|
+
schemaType: docSchema,
|
|
22
|
+
members: [
|
|
23
|
+
{
|
|
24
|
+
kind: 'field',
|
|
25
|
+
field: {path: [docSchema.fields[0].name], schemaType: docSchema.fields[0].type},
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
} as any
|
|
29
|
+
const conditionalMembers = getConditionalMembers(docState)
|
|
30
|
+
|
|
31
|
+
expect(conditionalMembers).toEqual([])
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('should include path with conditional readonly', () => {
|
|
35
|
+
const docSchema: ObjectSchemaType = Schema.compile({
|
|
36
|
+
name: 'test',
|
|
37
|
+
types: [
|
|
38
|
+
defineType({
|
|
39
|
+
type: 'document',
|
|
40
|
+
name: 'article',
|
|
41
|
+
fields: [{type: 'string', name: 'title', readOnly: () => false}],
|
|
42
|
+
}),
|
|
43
|
+
],
|
|
44
|
+
}).get('article')
|
|
45
|
+
|
|
46
|
+
const docState = {
|
|
47
|
+
path: [],
|
|
48
|
+
schemaType: docSchema,
|
|
49
|
+
members: [
|
|
50
|
+
{
|
|
51
|
+
kind: 'field',
|
|
52
|
+
field: {path: [docSchema.fields[0].name], schemaType: docSchema.fields[0].type},
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
} as any
|
|
56
|
+
const conditionalMembers = getConditionalMembers(docState)
|
|
57
|
+
|
|
58
|
+
expect(conditionalMembers).toEqual([{path: 'title', hidden: false, readOnly: false}])
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
test('should include array item path with conditional readonly', () => {
|
|
62
|
+
const docSchema: ObjectSchemaType = Schema.compile({
|
|
63
|
+
name: 'test',
|
|
64
|
+
types: [
|
|
65
|
+
defineType({
|
|
66
|
+
type: 'document',
|
|
67
|
+
name: 'article',
|
|
68
|
+
fields: [{type: 'array', name: 'array', of: [{type: 'string', readOnly: () => true}]}],
|
|
69
|
+
}),
|
|
70
|
+
],
|
|
71
|
+
}).get('article')
|
|
72
|
+
|
|
73
|
+
const docState = {
|
|
74
|
+
path: [],
|
|
75
|
+
schemaType: docSchema,
|
|
76
|
+
members: [
|
|
77
|
+
{
|
|
78
|
+
kind: 'field',
|
|
79
|
+
field: {
|
|
80
|
+
path: [docSchema.fields[0].name],
|
|
81
|
+
schemaType: docSchema.fields[0].type,
|
|
82
|
+
members: [
|
|
83
|
+
{
|
|
84
|
+
kind: 'item',
|
|
85
|
+
item: {
|
|
86
|
+
path: [docSchema.fields[0].name, 0],
|
|
87
|
+
schemaType: (docSchema.fields[0].type as ArraySchemaType).of[0],
|
|
88
|
+
readOnly: true,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
} as any
|
|
96
|
+
const conditionalMembers = getConditionalMembers(docState)
|
|
97
|
+
|
|
98
|
+
expect(conditionalMembers).toEqual([
|
|
99
|
+
{
|
|
100
|
+
path: 'array[0]',
|
|
101
|
+
hidden: false,
|
|
102
|
+
readOnly: true,
|
|
103
|
+
},
|
|
104
|
+
])
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
test('should include object path with conditional hidden', () => {
|
|
108
|
+
const docSchema: ObjectSchemaType = Schema.compile({
|
|
109
|
+
name: 'test',
|
|
110
|
+
types: [
|
|
111
|
+
defineType({
|
|
112
|
+
type: 'document',
|
|
113
|
+
name: 'article',
|
|
114
|
+
fields: [
|
|
115
|
+
defineField({
|
|
116
|
+
type: 'object',
|
|
117
|
+
name: 'object',
|
|
118
|
+
fields: [{type: 'string', name: 'title', hidden: () => false}],
|
|
119
|
+
}),
|
|
120
|
+
],
|
|
121
|
+
}),
|
|
122
|
+
],
|
|
123
|
+
}).get('article')
|
|
124
|
+
|
|
125
|
+
const docState = {
|
|
126
|
+
path: [],
|
|
127
|
+
schemaType: docSchema,
|
|
128
|
+
members: [
|
|
129
|
+
{
|
|
130
|
+
kind: 'field',
|
|
131
|
+
field: {
|
|
132
|
+
path: [docSchema.fields[0].name],
|
|
133
|
+
schemaType: docSchema.fields[0].type,
|
|
134
|
+
members: [
|
|
135
|
+
{
|
|
136
|
+
kind: 'field',
|
|
137
|
+
field: {
|
|
138
|
+
path: [docSchema.fields[0].name, 'title'],
|
|
139
|
+
schemaType: (docSchema.fields[0].type as ObjectSchemaType).fields[0].type,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
} as any
|
|
147
|
+
const conditionalMembers = getConditionalMembers(docState)
|
|
148
|
+
|
|
149
|
+
expect(conditionalMembers).toEqual([
|
|
150
|
+
{
|
|
151
|
+
path: 'object.title',
|
|
152
|
+
hidden: false,
|
|
153
|
+
readOnly: false,
|
|
154
|
+
},
|
|
155
|
+
])
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
test('should include path with fieldset with conditional state', () => {
|
|
159
|
+
const docSchema: ObjectSchemaType = Schema.compile({
|
|
160
|
+
name: 'test',
|
|
161
|
+
types: [
|
|
162
|
+
defineType({
|
|
163
|
+
type: 'document',
|
|
164
|
+
name: 'article',
|
|
165
|
+
fieldsets: [{name: 'set', hidden: () => false}],
|
|
166
|
+
fields: [{type: 'string', fieldset: 'set', name: 'title'}],
|
|
167
|
+
}),
|
|
168
|
+
],
|
|
169
|
+
}).get('article')
|
|
170
|
+
|
|
171
|
+
const docState = {
|
|
172
|
+
path: [],
|
|
173
|
+
schemaType: docSchema,
|
|
174
|
+
members: [
|
|
175
|
+
{
|
|
176
|
+
kind: 'fieldSet',
|
|
177
|
+
fieldSet: {
|
|
178
|
+
name: 'set',
|
|
179
|
+
path: ['set'],
|
|
180
|
+
members: [
|
|
181
|
+
{
|
|
182
|
+
kind: 'field',
|
|
183
|
+
field: {path: [docSchema.fields[0].name], schemaType: docSchema.fields[0].type},
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
} as any
|
|
190
|
+
const conditionalMembers = getConditionalMembers(docState)
|
|
191
|
+
|
|
192
|
+
expect(conditionalMembers).toEqual([
|
|
193
|
+
{
|
|
194
|
+
path: 'title',
|
|
195
|
+
hidden: false,
|
|
196
|
+
readOnly: false,
|
|
197
|
+
},
|
|
198
|
+
])
|
|
199
|
+
})
|
|
200
|
+
})
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/* eslint-disable max-depth */
|
|
2
|
+
import {
|
|
3
|
+
ArrayOfObjectsFormNode,
|
|
4
|
+
ArrayOfObjectsItemMember,
|
|
5
|
+
ArrayOfPrimitivesFormNode,
|
|
6
|
+
DocumentFormNode,
|
|
7
|
+
FieldsetState,
|
|
8
|
+
isObjectSchemaType,
|
|
9
|
+
ObjectFormNode,
|
|
10
|
+
Path,
|
|
11
|
+
pathToString,
|
|
12
|
+
SchemaType,
|
|
13
|
+
} from 'sanity'
|
|
14
|
+
|
|
15
|
+
const MAX_DEPTH = 8
|
|
16
|
+
|
|
17
|
+
export interface ConditionalMemberState {
|
|
18
|
+
path: string
|
|
19
|
+
hidden: boolean
|
|
20
|
+
readOnly: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface ConditionalMemberInnerState extends ConditionalMemberState {
|
|
24
|
+
conditional: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* This is used to statically determine the state of the functions on the server-side.
|
|
29
|
+
* Paths which has a schema with conditional config should be considered hidden: true and/or readOnly: true
|
|
30
|
+
* Only conditional paths are included, as static props can be determined from schema.
|
|
31
|
+
*
|
|
32
|
+
* Returns paths that has conditional hidden or readOnly schema config (function) and that.
|
|
33
|
+
* Form-state does not contain hidden members.
|
|
34
|
+
*
|
|
35
|
+
* Note:
|
|
36
|
+
* * If a parent path is hidden, no child paths are included
|
|
37
|
+
* * If a parent path is readOnly, no child paths are included
|
|
38
|
+
* * If a path is hidden, it is not included; only conditionally visible paths will be returned, with hidden: false
|
|
39
|
+
*/
|
|
40
|
+
export function getConditionalMembers(docState: DocumentFormNode): ConditionalMemberState[] {
|
|
41
|
+
const doc: ConditionalMemberInnerState = {
|
|
42
|
+
path: '',
|
|
43
|
+
hidden: false,
|
|
44
|
+
readOnly: !!docState.readOnly,
|
|
45
|
+
conditional: typeof docState.schemaType.hidden === 'function',
|
|
46
|
+
}
|
|
47
|
+
return [doc, ...extractConditionalPaths(docState, MAX_DEPTH)]
|
|
48
|
+
.filter((v) => v.conditional)
|
|
49
|
+
.map(({conditional, ...state}) => ({...state}))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function isConditional(schemaType: SchemaType) {
|
|
53
|
+
return typeof schemaType.hidden === 'function' || typeof schemaType.readOnly === 'function'
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function conditionalState(memberState: {
|
|
57
|
+
path: Path
|
|
58
|
+
schemaType: SchemaType
|
|
59
|
+
readOnly?: boolean
|
|
60
|
+
}): ConditionalMemberInnerState {
|
|
61
|
+
return {
|
|
62
|
+
path: pathToString(memberState.path),
|
|
63
|
+
readOnly: !!memberState.readOnly,
|
|
64
|
+
hidden: false, // if its in members, its not hidden
|
|
65
|
+
conditional: isConditional(memberState.schemaType),
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function extractConditionalPaths(
|
|
70
|
+
node: ObjectFormNode | FieldsetState,
|
|
71
|
+
maxDepth: number
|
|
72
|
+
): ConditionalMemberInnerState[] {
|
|
73
|
+
if (node.path.length >= maxDepth) {
|
|
74
|
+
return []
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return node.members.reduce<ConditionalMemberInnerState[]>((acc, member) => {
|
|
78
|
+
if (member.kind === 'error') {
|
|
79
|
+
return acc
|
|
80
|
+
}
|
|
81
|
+
if (member.kind === 'field') {
|
|
82
|
+
const schemaType = member.field.schemaType
|
|
83
|
+
if (schemaType.jsonType === 'object') {
|
|
84
|
+
const innerFields = member.field.readOnly
|
|
85
|
+
? []
|
|
86
|
+
: extractConditionalPaths(member.field as ObjectFormNode, maxDepth)
|
|
87
|
+
return [...acc, conditionalState(member.field), ...innerFields]
|
|
88
|
+
} else if (schemaType.jsonType === 'array') {
|
|
89
|
+
const array = member.field as ArrayOfObjectsFormNode | ArrayOfPrimitivesFormNode
|
|
90
|
+
|
|
91
|
+
let arrayPaths: ConditionalMemberInnerState[] = []
|
|
92
|
+
const isObjectsArray = array.members.some(
|
|
93
|
+
(m) => m.kind === 'item' && isObjectSchemaType(m.item.schemaType)
|
|
94
|
+
)
|
|
95
|
+
if (!array.readOnly) {
|
|
96
|
+
for (const arrayMember of array.members) {
|
|
97
|
+
if (arrayMember.kind === 'error') {
|
|
98
|
+
continue
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const innerFields =
|
|
102
|
+
isObjectsArray && !arrayMember.item.readOnly
|
|
103
|
+
? extractConditionalPaths((arrayMember as ArrayOfObjectsItemMember).item, maxDepth)
|
|
104
|
+
: []
|
|
105
|
+
|
|
106
|
+
arrayPaths = [...arrayPaths, conditionalState(arrayMember.item), ...innerFields]
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return [...acc, conditionalState(array), ...arrayPaths]
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return [...acc, conditionalState(member.field)]
|
|
113
|
+
} else if (member.kind === 'fieldSet') {
|
|
114
|
+
const conditionalFieldset = !!(node as ObjectFormNode).schemaType?.fieldsets?.some(
|
|
115
|
+
(f) => !f.single && f.name === member.fieldSet.name && typeof f.hidden === 'function'
|
|
116
|
+
)
|
|
117
|
+
const innerFields = extractConditionalPaths(member.fieldSet, maxDepth).map((f) => ({
|
|
118
|
+
...f,
|
|
119
|
+
// if fieldset is conditional, visible fields must also be considered conditional
|
|
120
|
+
conditional: conditionalFieldset ?? f.conditional,
|
|
121
|
+
}))
|
|
122
|
+
return [...acc, ...innerFields]
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return acc
|
|
126
|
+
}, [])
|
|
127
|
+
}
|
package/src/helpers/misc.ts
CHANGED
|
@@ -4,13 +4,17 @@ import {useMemo} from 'react'
|
|
|
4
4
|
|
|
5
5
|
export function usePathKey(path: Path | string) {
|
|
6
6
|
return useMemo(() => {
|
|
7
|
-
|
|
8
|
-
return Array.isArray(path) ? pathToString(path) : path
|
|
9
|
-
}
|
|
10
|
-
return documentRootKey
|
|
7
|
+
return getPathKey(path)
|
|
11
8
|
}, [path])
|
|
12
9
|
}
|
|
13
10
|
|
|
11
|
+
export function getPathKey(path: Path | string) {
|
|
12
|
+
if (path.length) {
|
|
13
|
+
return Array.isArray(path) ? pathToString(path) : path
|
|
14
|
+
}
|
|
15
|
+
return documentRootKey
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
export function getInstructionTitle(instruction?: StudioInstruction) {
|
|
15
19
|
return instruction?.title ?? 'Untitled'
|
|
16
20
|
}
|
package/src/helpers/typeUtils.ts
CHANGED
|
@@ -18,13 +18,27 @@ export function isImage(schemaType: SchemaType) {
|
|
|
18
18
|
return isType(schemaType, 'image')
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export function
|
|
21
|
+
export function getDescriptionFieldOption(schemaType: SchemaType | undefined): string | undefined {
|
|
22
22
|
if (!schemaType) {
|
|
23
23
|
return undefined
|
|
24
24
|
}
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
return
|
|
25
|
+
const descriptionField = (schemaType.options as ImageOptions)?.aiAssist?.imageDescriptionField
|
|
26
|
+
if (descriptionField) {
|
|
27
|
+
return descriptionField
|
|
28
28
|
}
|
|
29
|
-
return
|
|
29
|
+
return getDescriptionFieldOption(schemaType.type)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getImageInstructionFieldOption(
|
|
33
|
+
schemaType: SchemaType | undefined
|
|
34
|
+
): string | undefined {
|
|
35
|
+
if (!schemaType) {
|
|
36
|
+
return undefined
|
|
37
|
+
}
|
|
38
|
+
const imageInstructionField = (schemaType.options as ImageOptions)?.aiAssist
|
|
39
|
+
?.imageInstructionField
|
|
40
|
+
if (imageInstructionField) {
|
|
41
|
+
return imageInstructionField
|
|
42
|
+
}
|
|
43
|
+
return getImageInstructionFieldOption(schemaType.type)
|
|
30
44
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export * from './schemas/typeDefExtensions'
|
|
2
2
|
export * from './schemas/serialize/SchemTypeTool'
|
|
3
3
|
|
|
4
|
+
export {defaultLanguageOutputs} from './translate/paths'
|
|
5
|
+
export * from './translate/types'
|
|
6
|
+
|
|
4
7
|
export {contextDocumentTypeName} from './types'
|
|
5
8
|
|
|
6
9
|
export {assist} from './plugin'
|
package/src/plugin.tsx
CHANGED
|
@@ -15,17 +15,21 @@ import {createAssistDocumentPresence} from './presence/AssistDocumentPresence'
|
|
|
15
15
|
import {isSchemaAssistEnabled} from './helpers/assistSupported'
|
|
16
16
|
import {isImage} from './helpers/typeUtils'
|
|
17
17
|
import {ImageContextProvider} from './components/ImageContext'
|
|
18
|
+
import {TranslationConfig} from './translate/types'
|
|
19
|
+
import {assistDocumentTypeName, AssistPreset} from './types'
|
|
18
20
|
|
|
19
21
|
export interface AssistPluginConfig {
|
|
22
|
+
translate?: TranslationConfig
|
|
23
|
+
|
|
20
24
|
/**
|
|
21
|
-
*
|
|
25
|
+
* @internal
|
|
22
26
|
*/
|
|
23
|
-
|
|
27
|
+
__customApiClient?: (defaultClient: SanityClient) => SanityClient
|
|
24
28
|
|
|
25
29
|
/**
|
|
26
30
|
* @internal
|
|
27
31
|
*/
|
|
28
|
-
|
|
32
|
+
__presets?: Record<string, AssistPreset>
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
export const assist = definePlugin<AssistPluginConfig | void>((config) => {
|
|
@@ -36,16 +40,23 @@ export const assist = definePlugin<AssistPluginConfig | void>((config) => {
|
|
|
36
40
|
schema: {
|
|
37
41
|
types: schemaTypes,
|
|
38
42
|
},
|
|
43
|
+
i18n: {
|
|
44
|
+
bundles: [{}],
|
|
45
|
+
},
|
|
39
46
|
|
|
40
47
|
document: {
|
|
41
48
|
inspectors: (prev, context) => {
|
|
42
|
-
const
|
|
49
|
+
const documentType = context.documentType
|
|
50
|
+
const docSchema = context.schema.get(documentType)
|
|
43
51
|
if (docSchema && isSchemaAssistEnabled(docSchema)) {
|
|
44
52
|
return [...prev, assistInspector]
|
|
45
53
|
}
|
|
46
54
|
return prev
|
|
47
55
|
},
|
|
48
56
|
unstable_fieldActions: (prev, {documentType, schema}) => {
|
|
57
|
+
if (documentType === assistDocumentTypeName) {
|
|
58
|
+
return []
|
|
59
|
+
}
|
|
49
60
|
const docSchema = schema.get(documentType)
|
|
50
61
|
if (docSchema && isSchemaAssistEnabled(docSchema)) {
|
|
51
62
|
return [...prev, assistFieldActions]
|
|
@@ -53,6 +64,9 @@ export const assist = definePlugin<AssistPluginConfig | void>((config) => {
|
|
|
53
64
|
return prev
|
|
54
65
|
},
|
|
55
66
|
unstable_languageFilter: (prev, {documentId, schema, schemaType}) => {
|
|
67
|
+
if (schemaType === assistDocumentTypeName) {
|
|
68
|
+
return []
|
|
69
|
+
}
|
|
56
70
|
const docSchema = schema.get(schemaType)
|
|
57
71
|
if (docSchema && isObjectSchemaType(docSchema) && isSchemaAssistEnabled(docSchema)) {
|
|
58
72
|
return [...prev, createAssistDocumentPresence(documentId, docSchema)]
|
|
@@ -18,6 +18,8 @@ import {
|
|
|
18
18
|
instructionContextTypeName,
|
|
19
19
|
instructionTaskTypeName,
|
|
20
20
|
instructionTypeName,
|
|
21
|
+
outputFieldTypeName,
|
|
22
|
+
outputTypeTypeName,
|
|
21
23
|
promptTypeName,
|
|
22
24
|
userInputTypeName,
|
|
23
25
|
} from '../types'
|
|
@@ -37,11 +39,13 @@ import {PromptInput} from '../assistDocument/components/instruction/PromptInput'
|
|
|
37
39
|
import {instructionGuideUrl} from '../constants'
|
|
38
40
|
import {InstructionsArrayField} from '../assistDocument/components/InstructionsArrayField'
|
|
39
41
|
import {getFieldRefsWithDocument} from '../assistInspector/helpers'
|
|
42
|
+
import {InstructionOutputField} from '../assistDocument/components/instruction/InstructionOutputField'
|
|
43
|
+
import {InstructionOutputInput} from '../assistDocument/components/instruction/InstructionOutputInput'
|
|
40
44
|
|
|
41
45
|
export const fieldReference = defineType({
|
|
42
46
|
type: 'object',
|
|
43
47
|
name: fieldReferenceTypeName,
|
|
44
|
-
title: '
|
|
48
|
+
title: 'Field',
|
|
45
49
|
icon: ThListIcon,
|
|
46
50
|
|
|
47
51
|
fields: [
|
|
@@ -329,6 +333,41 @@ export const instruction = defineType({
|
|
|
329
333
|
return context.currentUser?.id ?? ''
|
|
330
334
|
},
|
|
331
335
|
}),
|
|
336
|
+
defineField({
|
|
337
|
+
type: 'array',
|
|
338
|
+
name: 'output',
|
|
339
|
+
title: 'Output filter',
|
|
340
|
+
components: {
|
|
341
|
+
input: InstructionOutputInput,
|
|
342
|
+
field: InstructionOutputField,
|
|
343
|
+
},
|
|
344
|
+
of: [
|
|
345
|
+
defineArrayMember({
|
|
346
|
+
type: 'object' as const,
|
|
347
|
+
name: outputFieldTypeName,
|
|
348
|
+
title: 'Output field',
|
|
349
|
+
fields: [
|
|
350
|
+
{
|
|
351
|
+
type: 'string',
|
|
352
|
+
name: 'path',
|
|
353
|
+
title: 'Path',
|
|
354
|
+
},
|
|
355
|
+
],
|
|
356
|
+
}),
|
|
357
|
+
defineArrayMember({
|
|
358
|
+
type: 'object' as const,
|
|
359
|
+
name: outputTypeTypeName,
|
|
360
|
+
title: 'Output type',
|
|
361
|
+
fields: [
|
|
362
|
+
{
|
|
363
|
+
type: 'string',
|
|
364
|
+
name: 'type',
|
|
365
|
+
title: 'Type',
|
|
366
|
+
},
|
|
367
|
+
],
|
|
368
|
+
}),
|
|
369
|
+
],
|
|
370
|
+
}),
|
|
332
371
|
],
|
|
333
372
|
})
|
|
334
373
|
|