@sanity/assist 3.1.1 → 3.2.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 +47 -2
- package/dist/index.d.mts +71 -51
- package/dist/index.d.ts +71 -51
- package/dist/index.esm.js +3445 -3434
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +3441 -3430
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3445 -3434
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
- package/src/_lib/fixedListenQuery.ts +1 -1
- package/src/assistInspector/AssistInspector.tsx +1 -1
- package/src/helpers/assistSupported.ts +1 -0
- package/src/helpers/conditionalMembers.test.ts +47 -0
- package/src/helpers/conditionalMembers.ts +7 -3
- package/src/index.ts +2 -5
- package/src/plugin.tsx +19 -10
- package/src/schemas/serialize/schemaUtils.ts +1 -0
- package/src/schemas/serialize/serializeSchema.test.ts +59 -0
- package/src/schemas/serialize/serializeSchema.ts +1 -0
- package/src/translate/FieldTranslationProvider.tsx +5 -2
- package/src/translate/paths.test.ts +41 -0
- package/src/translate/paths.ts +11 -4
- package/src/translate/translateActions.tsx +6 -1
- package/src/translate/types.ts +22 -1
- package/src/types.ts +1 -1
- package/src/useApiClient.ts +8 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/assist",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.1",
|
|
4
4
|
"description": "You create the instructions; Sanity AI Assist does the rest.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"@rollup/plugin-image": "^3.0.3",
|
|
66
66
|
"@sanity/pkg-utils": "^6.1.0",
|
|
67
67
|
"@sanity/plugin-kit": "^3.1.10",
|
|
68
|
+
"@sanity/schema": "^3.80.0",
|
|
68
69
|
"@sanity/semantic-release-preset": "^4.1.7",
|
|
69
70
|
"@types/lodash": "^4.17.0",
|
|
70
71
|
"@types/lodash-es": "^4.17.12",
|
|
@@ -75,13 +76,14 @@
|
|
|
75
76
|
"eslint-config-prettier": "^9.1.0",
|
|
76
77
|
"eslint-config-sanity": "^7.1.2",
|
|
77
78
|
"eslint-plugin-prettier": "^5.1.3",
|
|
79
|
+
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
78
80
|
"eslint-plugin-react": "^7.34.1",
|
|
79
81
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
80
82
|
"npm-run-all2": "^5.0.2",
|
|
81
83
|
"react": "^18.2.0",
|
|
82
84
|
"react-dom": "^18.2.0",
|
|
83
85
|
"rimraf": "^5.0.5",
|
|
84
|
-
"sanity": "^3.
|
|
86
|
+
"sanity": "^3.80.0",
|
|
85
87
|
"semantic-release": "^23.0.8",
|
|
86
88
|
"styled-components": "^6.1.8",
|
|
87
89
|
"typescript": "^5.7.2",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {SanityClient} from '@sanity/client'
|
|
1
|
+
import type {SanityClient} from '@sanity/client'
|
|
2
2
|
import {defer, delay, merge, Observable, of, partition, switchMap, throwError} from 'rxjs'
|
|
3
3
|
import {filter, mergeMap, share, take} from 'rxjs/operators'
|
|
4
4
|
import {exhaustMapToWithTrailing} from 'rxjs-exhaustmap-with-trailing'
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import {styled} from 'styled-components'
|
|
16
16
|
|
|
17
17
|
import {DocumentForm} from '../_lib/form'
|
|
18
|
+
import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
|
|
18
19
|
import {AssistTypeContext} from '../assistDocument/components/AssistTypeContext'
|
|
19
20
|
import {useStudioAssistDocument} from '../assistDocument/hooks/useStudioAssistDocument'
|
|
20
21
|
import {useRequestRunInstruction} from '../assistDocument/RequestRunInstructionProvider'
|
|
@@ -34,7 +35,6 @@ import {
|
|
|
34
35
|
useTypePath,
|
|
35
36
|
} from './helpers'
|
|
36
37
|
import {InstructionTaskHistoryButton} from './InstructionTaskHistoryButton'
|
|
37
|
-
import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
|
|
38
38
|
|
|
39
39
|
const CardWithShadowBelow = styled(Card)`
|
|
40
40
|
position: relative;
|
|
@@ -37,6 +37,7 @@ function isUnsupportedType(type: SchemaType) {
|
|
|
37
37
|
type.jsonType === 'number' ||
|
|
38
38
|
type.name === 'sanity.imageCrop' ||
|
|
39
39
|
type.name === 'sanity.imageHotspot' ||
|
|
40
|
+
isType(type, 'globalDocumentReference') ||
|
|
40
41
|
(isType(type, 'reference') &&
|
|
41
42
|
!(type?.options as ReferenceOptions)?.aiAssist?.embeddingsIndex) ||
|
|
42
43
|
isType(type, 'crossDatasetReference') ||
|
|
@@ -226,4 +226,51 @@ describe('conditionalMembers', () => {
|
|
|
226
226
|
},
|
|
227
227
|
])
|
|
228
228
|
})
|
|
229
|
+
|
|
230
|
+
test('should respect max-depth', () => {
|
|
231
|
+
const docSchema: ObjectSchemaType = Schema.compile({
|
|
232
|
+
name: 'test',
|
|
233
|
+
types: [
|
|
234
|
+
defineType({
|
|
235
|
+
type: 'document',
|
|
236
|
+
name: 'article',
|
|
237
|
+
fields: [
|
|
238
|
+
{type: 'string', name: 'title', readOnly: () => false},
|
|
239
|
+
{
|
|
240
|
+
type: 'object',
|
|
241
|
+
name: 'object',
|
|
242
|
+
fields: [{type: 'string', name: 'title', readOnly: () => false}],
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
}),
|
|
246
|
+
],
|
|
247
|
+
}).get('article')
|
|
248
|
+
|
|
249
|
+
const docState = {
|
|
250
|
+
path: [],
|
|
251
|
+
schemaType: docSchema,
|
|
252
|
+
members: [
|
|
253
|
+
{
|
|
254
|
+
kind: 'field',
|
|
255
|
+
field: {path: [docSchema.fields[0].name], schemaType: docSchema.fields[0].type},
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
kind: 'field',
|
|
259
|
+
field: {
|
|
260
|
+
path: [docSchema.fields[1].name],
|
|
261
|
+
schemaType: docSchema.fields[1].type,
|
|
262
|
+
members: [
|
|
263
|
+
{
|
|
264
|
+
kind: 'field',
|
|
265
|
+
field: {path: ['object', 'title'], schemaType: docSchema.fields[0].type},
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
],
|
|
271
|
+
} as any
|
|
272
|
+
const conditionalMembers = getConditionalMembers(docState, 1)
|
|
273
|
+
|
|
274
|
+
expect(conditionalMembers).toEqual([{path: 'title', hidden: false, readOnly: false}])
|
|
275
|
+
})
|
|
229
276
|
})
|
|
@@ -12,7 +12,8 @@ import {
|
|
|
12
12
|
type SchemaType,
|
|
13
13
|
} from 'sanity'
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const DEFAULT_MAX_DEPTH = 8
|
|
16
|
+
const ABSOLUTE_MAX_DEPTH = 50
|
|
16
17
|
|
|
17
18
|
export interface ConditionalMemberState {
|
|
18
19
|
path: string
|
|
@@ -37,7 +38,10 @@ interface ConditionalMemberInnerState extends ConditionalMemberState {
|
|
|
37
38
|
* * If a parent path is readOnly, no child paths are included
|
|
38
39
|
* * If a path is hidden, it is not included; only conditionally visible paths will be returned, with hidden: false
|
|
39
40
|
*/
|
|
40
|
-
export function getConditionalMembers(
|
|
41
|
+
export function getConditionalMembers(
|
|
42
|
+
docState: DocumentFormNode,
|
|
43
|
+
maxDepth = DEFAULT_MAX_DEPTH,
|
|
44
|
+
): ConditionalMemberState[] {
|
|
41
45
|
const doc: ConditionalMemberInnerState = {
|
|
42
46
|
path: '',
|
|
43
47
|
hidden: false,
|
|
@@ -45,7 +49,7 @@ export function getConditionalMembers(docState: DocumentFormNode): ConditionalMe
|
|
|
45
49
|
conditional: isConditional(docState.schemaType),
|
|
46
50
|
}
|
|
47
51
|
return (
|
|
48
|
-
[doc, ...extractConditionalPaths(docState,
|
|
52
|
+
[doc, ...extractConditionalPaths(docState, Math.min(maxDepth, ABSOLUTE_MAX_DEPTH))]
|
|
49
53
|
.filter((v) => v.conditional)
|
|
50
54
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
51
55
|
.map(({conditional, ...state}) => ({...state}))
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
export
|
|
1
|
+
export {assist} from './plugin'
|
|
2
2
|
export * from './schemas/serialize/SchemTypeTool'
|
|
3
|
-
|
|
3
|
+
export * from './schemas/typeDefExtensions'
|
|
4
4
|
export {defaultLanguageOutputs} from './translate/paths'
|
|
5
5
|
export * from './translate/types'
|
|
6
|
-
|
|
7
6
|
export {contextDocumentTypeName} from './types'
|
|
8
|
-
|
|
9
|
-
export {assist} from './plugin'
|
package/src/plugin.tsx
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
|
+
import type {SanityClient} from '@sanity/client'
|
|
1
2
|
import {definePlugin, isObjectSchemaType} from 'sanity'
|
|
2
|
-
|
|
3
|
+
|
|
4
|
+
import {AssistDocumentInputWrapper} from './assistDocument/AssistDocumentInput'
|
|
5
|
+
import {AssistDocumentLayout} from './assistDocument/AssistDocumentLayout'
|
|
3
6
|
import {AssistFieldWrapper} from './assistFormComponents/AssistField'
|
|
4
|
-
import {AssistLayout} from './assistLayout/AssistLayout'
|
|
5
7
|
import {AssistFormBlock} from './assistFormComponents/AssistFormBlock'
|
|
8
|
+
import {AssistInlineFormBlock} from './assistFormComponents/AssistInlineFormBlock'
|
|
6
9
|
import {AssistItem} from './assistFormComponents/AssistItem'
|
|
7
|
-
import {
|
|
10
|
+
import {assistInspector} from './assistInspector'
|
|
11
|
+
import {AssistLayout} from './assistLayout/AssistLayout'
|
|
12
|
+
import {ImageContextProvider} from './components/ImageContext'
|
|
8
13
|
import {SafeValueInput} from './components/SafeValueInput'
|
|
9
|
-
import {schemaTypes} from './schemas'
|
|
10
|
-
import {AssistInlineFormBlock} from './assistFormComponents/AssistInlineFormBlock'
|
|
11
|
-
import {assistFieldActions} from './fieldActions/assistFieldActions'
|
|
12
14
|
import {packageName} from './constants'
|
|
13
|
-
import {
|
|
14
|
-
import {createAssistDocumentPresence} from './presence/AssistDocumentPresence'
|
|
15
|
+
import {assistFieldActions} from './fieldActions/assistFieldActions'
|
|
15
16
|
import {isSchemaAssistEnabled} from './helpers/assistSupported'
|
|
16
17
|
import {isImage} from './helpers/typeUtils'
|
|
17
|
-
import {
|
|
18
|
+
import {createAssistDocumentPresence} from './presence/AssistDocumentPresence'
|
|
19
|
+
import {schemaTypes} from './schemas'
|
|
18
20
|
import {TranslationConfig} from './translate/types'
|
|
19
21
|
import {assistDocumentTypeName, AssistPreset} from './types'
|
|
20
|
-
import {AssistDocumentLayout} from './assistDocument/AssistDocumentLayout'
|
|
21
22
|
|
|
22
23
|
export interface AssistPluginConfig {
|
|
23
24
|
translate?: TranslationConfig
|
|
@@ -35,6 +36,14 @@ export interface AssistPluginConfig {
|
|
|
35
36
|
|
|
36
37
|
export const assist = definePlugin<AssistPluginConfig | void>((config) => {
|
|
37
38
|
const configWithDefaults = config ?? {}
|
|
39
|
+
const styleguide = configWithDefaults.translate?.styleguide || ''
|
|
40
|
+
|
|
41
|
+
if (styleguide.length > 2000) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`[${packageName}]: \`translate.styleguide\` value is too long. It must be 2000 characters or less, was ${styleguide.length} characters`,
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
return {
|
|
39
48
|
name: packageName,
|
|
40
49
|
|
|
@@ -741,4 +741,63 @@ describe('serializeSchema', () => {
|
|
|
741
741
|
},
|
|
742
742
|
])
|
|
743
743
|
})
|
|
744
|
+
|
|
745
|
+
test('should no serialize global document reference types (for now)', () => {
|
|
746
|
+
const schema = Schema.compile({
|
|
747
|
+
name: 'test',
|
|
748
|
+
types: [
|
|
749
|
+
defineType({
|
|
750
|
+
type: 'object',
|
|
751
|
+
name: 'author',
|
|
752
|
+
fields: [
|
|
753
|
+
defineField({
|
|
754
|
+
type: 'string',
|
|
755
|
+
name: 'name',
|
|
756
|
+
}),
|
|
757
|
+
defineField({
|
|
758
|
+
type: 'globalDocumentReference',
|
|
759
|
+
name: 'person',
|
|
760
|
+
title: 'Person',
|
|
761
|
+
resourceType: 'dataset',
|
|
762
|
+
resourceId: 'exx11uqh.blog',
|
|
763
|
+
to: [
|
|
764
|
+
{
|
|
765
|
+
type: 'person',
|
|
766
|
+
preview: {
|
|
767
|
+
select: {
|
|
768
|
+
title: 'title',
|
|
769
|
+
media: 'coverImage',
|
|
770
|
+
},
|
|
771
|
+
prepare(val: any) {
|
|
772
|
+
return {
|
|
773
|
+
title: val.title,
|
|
774
|
+
media: val.coverImage,
|
|
775
|
+
}
|
|
776
|
+
},
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
],
|
|
780
|
+
}),
|
|
781
|
+
],
|
|
782
|
+
}),
|
|
783
|
+
],
|
|
784
|
+
})
|
|
785
|
+
|
|
786
|
+
const serializedTypes = serializeSchema(schema, {leanFormat: true})
|
|
787
|
+
|
|
788
|
+
expect(serializedTypes).toEqual([
|
|
789
|
+
{
|
|
790
|
+
fields: [
|
|
791
|
+
{
|
|
792
|
+
name: 'name',
|
|
793
|
+
title: 'Name',
|
|
794
|
+
type: 'string',
|
|
795
|
+
},
|
|
796
|
+
],
|
|
797
|
+
name: 'author',
|
|
798
|
+
title: 'Author',
|
|
799
|
+
type: 'object',
|
|
800
|
+
},
|
|
801
|
+
])
|
|
802
|
+
})
|
|
744
803
|
})
|
|
@@ -58,6 +58,7 @@ function getSchemaStub(
|
|
|
58
58
|
options?: Options,
|
|
59
59
|
): SerializedSchemaType {
|
|
60
60
|
if (!schemaType.type?.name) {
|
|
61
|
+
// eslint-disable-next-line no-console -- log error
|
|
61
62
|
console.error('Missing type name', schemaType.type)
|
|
62
63
|
throw new Error('Type is missing name!')
|
|
63
64
|
}
|
|
@@ -68,6 +68,7 @@ function hasValuesToTranslate(
|
|
|
68
68
|
export function FieldTranslationProvider(props: PropsWithChildren<{}>) {
|
|
69
69
|
const {config: assistConfig} = useAiAssistanceConfig()
|
|
70
70
|
const apiClient = useApiClient(assistConfig.__customApiClient)
|
|
71
|
+
const styleguide = assistConfig.translate?.styleguide
|
|
71
72
|
const config = assistConfig.translate?.field
|
|
72
73
|
const {translate: runTranslate} = useTranslate(apiClient)
|
|
73
74
|
|
|
@@ -112,7 +113,7 @@ export function FieldTranslationProvider(props: PropsWithChildren<{}>) {
|
|
|
112
113
|
setToLanguages(filteredToLanguages)
|
|
113
114
|
const fromId = from?.id
|
|
114
115
|
const allToIds = allToLanguages?.map((l) => l.id) ?? []
|
|
115
|
-
const docMembers = getDocumentMembersFlat(document, documentSchema)
|
|
116
|
+
const docMembers = getDocumentMembersFlat(document, documentSchema, config?.maxPathDepth)
|
|
116
117
|
if (fromId && allToIds?.length) {
|
|
117
118
|
const transMap = getFieldLanguageMap(
|
|
118
119
|
documentSchema,
|
|
@@ -193,7 +194,8 @@ export function FieldTranslationProvider(props: PropsWithChildren<{}>) {
|
|
|
193
194
|
if (fieldLanguageMaps && documentId && translatePath) {
|
|
194
195
|
runTranslate({
|
|
195
196
|
documentId,
|
|
196
|
-
translatePath
|
|
197
|
+
translatePath,
|
|
198
|
+
styleguide,
|
|
197
199
|
fieldLanguageMap: fieldLanguageMaps.map((map) => ({
|
|
198
200
|
...map,
|
|
199
201
|
// eslint-disable-next-line max-nested-callbacks
|
|
@@ -207,6 +209,7 @@ export function FieldTranslationProvider(props: PropsWithChildren<{}>) {
|
|
|
207
209
|
fieldLanguageMaps,
|
|
208
210
|
documentId,
|
|
209
211
|
runTranslate,
|
|
212
|
+
styleguide,
|
|
210
213
|
close,
|
|
211
214
|
toLanguages,
|
|
212
215
|
fieldTranslationParams?.translatePath,
|
|
@@ -137,4 +137,45 @@ describe('paths', () => {
|
|
|
137
137
|
'translations[_key=="en"].value',
|
|
138
138
|
])
|
|
139
139
|
})
|
|
140
|
+
|
|
141
|
+
test('should limit depth to 1 when specified', () => {
|
|
142
|
+
const docSchema: ObjectSchemaType = Schema.compile({
|
|
143
|
+
name: 'test',
|
|
144
|
+
types: [
|
|
145
|
+
defineType({
|
|
146
|
+
type: 'document',
|
|
147
|
+
name: 'article',
|
|
148
|
+
fields: [
|
|
149
|
+
{
|
|
150
|
+
type: 'array',
|
|
151
|
+
name: 'translations',
|
|
152
|
+
of: [
|
|
153
|
+
{
|
|
154
|
+
type: 'object',
|
|
155
|
+
name: 'internationalizedArrayString',
|
|
156
|
+
fields: [{type: 'string', name: 'value'}],
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
}),
|
|
162
|
+
],
|
|
163
|
+
}).get('article')
|
|
164
|
+
|
|
165
|
+
const doc: SanityDocumentLike = {
|
|
166
|
+
_id: 'na',
|
|
167
|
+
_type: 'article',
|
|
168
|
+
translations: [
|
|
169
|
+
{
|
|
170
|
+
//assume type is missing in the data for some reason
|
|
171
|
+
//_type: 'internationalizedArrayString',
|
|
172
|
+
_key: 'en',
|
|
173
|
+
value: 'some string',
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const members = getDocumentMembersFlat(doc, docSchema, 1)
|
|
179
|
+
expect(members.map((p) => pathToString(p.path))).toEqual(['translations'])
|
|
180
|
+
})
|
|
140
181
|
})
|
package/src/translate/paths.ts
CHANGED
|
@@ -16,15 +16,20 @@ export interface FieldLanguageMap {
|
|
|
16
16
|
outputs: TranslationOutput[]
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const
|
|
19
|
+
const DEFAULT_MAX_DEPTH = 6
|
|
20
|
+
const ABSOLUTE_MAX_DEPTH = 50
|
|
20
21
|
|
|
21
|
-
export function getDocumentMembersFlat(
|
|
22
|
+
export function getDocumentMembersFlat(
|
|
23
|
+
doc: SanityDocumentLike,
|
|
24
|
+
schemaType: ObjectSchemaType,
|
|
25
|
+
maxDepth = DEFAULT_MAX_DEPTH,
|
|
26
|
+
) {
|
|
22
27
|
if (!isDocumentSchemaType(schemaType)) {
|
|
23
28
|
console.error(`Schema type is not a document`)
|
|
24
29
|
return []
|
|
25
30
|
}
|
|
26
31
|
|
|
27
|
-
return extractPaths(doc, schemaType, [],
|
|
32
|
+
return extractPaths(doc, schemaType, [], Math.min(maxDepth, ABSOLUTE_MAX_DEPTH))
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
function extractPaths(
|
|
@@ -59,7 +64,9 @@ function extractPaths(
|
|
|
59
64
|
} else if (
|
|
60
65
|
fieldSchema.jsonType === 'array' &&
|
|
61
66
|
fieldSchema.of.length &&
|
|
62
|
-
fieldSchema.of.some((item) => 'fields' in item)
|
|
67
|
+
fieldSchema.of.some((item) => 'fields' in item) &&
|
|
68
|
+
// no reason to drill into arrays if the item fields will be culled by maxDepth, ie we need 1 extra path headroom
|
|
69
|
+
path.length + 1 < maxDepth
|
|
63
70
|
) {
|
|
64
71
|
const {value: arrayValue} = extractWithPath(pathToString(fieldPath), doc)[0] ?? {}
|
|
65
72
|
|
|
@@ -73,6 +73,7 @@ export const translateActions: DocumentFieldAction = {
|
|
|
73
73
|
task: translationApi.translate,
|
|
74
74
|
})
|
|
75
75
|
|
|
76
|
+
const styleguide = config.translate?.styleguide
|
|
76
77
|
const languagePath = config.translate?.document?.languageField
|
|
77
78
|
|
|
78
79
|
// if this is true, it is stable, and not breaking rules of hooks
|
|
@@ -98,6 +99,7 @@ export const translateActions: DocumentFieldAction = {
|
|
|
98
99
|
translate({
|
|
99
100
|
languagePath,
|
|
100
101
|
translatePath: path,
|
|
102
|
+
styleguide,
|
|
101
103
|
documentId: documentId ?? '',
|
|
102
104
|
conditionalMembers: formStateRef.current
|
|
103
105
|
? getConditionalMembers(formStateRef.current)
|
|
@@ -110,6 +112,7 @@ export const translateActions: DocumentFieldAction = {
|
|
|
110
112
|
}, [
|
|
111
113
|
languagePath,
|
|
112
114
|
translate,
|
|
115
|
+
styleguide,
|
|
113
116
|
documentId,
|
|
114
117
|
translationApi.loading,
|
|
115
118
|
documentTranslationEnabled,
|
|
@@ -123,6 +126,7 @@ export const translateActions: DocumentFieldAction = {
|
|
|
123
126
|
task: fieldTranslate.openFieldTranslation,
|
|
124
127
|
})
|
|
125
128
|
|
|
129
|
+
const maxDepth = config.translate?.field?.maxPathDepth
|
|
126
130
|
const translateFieldsAction = useMemo(
|
|
127
131
|
() =>
|
|
128
132
|
fieldTransEnabled
|
|
@@ -148,7 +152,7 @@ export const translateActions: DocumentFieldAction = {
|
|
|
148
152
|
documentSchema: documentSchemaType,
|
|
149
153
|
translatePath: path,
|
|
150
154
|
conditionalMembers: formStateRef.current
|
|
151
|
-
? getConditionalMembers(formStateRef.current)
|
|
155
|
+
? getConditionalMembers(formStateRef.current, maxDepth)
|
|
152
156
|
: [],
|
|
153
157
|
})
|
|
154
158
|
},
|
|
@@ -164,6 +168,7 @@ export const translateActions: DocumentFieldAction = {
|
|
|
164
168
|
fieldTransEnabled,
|
|
165
169
|
path,
|
|
166
170
|
readOnly,
|
|
171
|
+
maxDepth,
|
|
167
172
|
],
|
|
168
173
|
)
|
|
169
174
|
|
package/src/translate/types.ts
CHANGED
|
@@ -76,7 +76,6 @@ export interface FieldTranslationConfig {
|
|
|
76
76
|
*
|
|
77
77
|
* It determines the relationships between document paths: Given a document path and a language, into which
|
|
78
78
|
* sibling paths should translations be output.
|
|
79
|
-
|
|
80
79
|
*
|
|
81
80
|
* `translationOutputs` is invoked once per path in the document (limited to a depth of 6), with the following:
|
|
82
81
|
*
|
|
@@ -121,8 +120,24 @@ export interface FieldTranslationConfig {
|
|
|
121
120
|
* return undefined
|
|
122
121
|
* }
|
|
123
122
|
* ```
|
|
123
|
+
*
|
|
124
|
+
* @see #maxPathDepth
|
|
124
125
|
**/
|
|
125
126
|
translationOutputs?: TranslationOutputsFunction
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The max depth for document paths AI Assist will translate.
|
|
130
|
+
*
|
|
131
|
+
* Depth is based on field path segments:
|
|
132
|
+
* - `title` has depth 1
|
|
133
|
+
* - `array[_key="no"].title` has depth 3
|
|
134
|
+
*
|
|
135
|
+
* Be careful not to set this too high in studios with recursive document schemas, as it could have
|
|
136
|
+
* negative impact on performance.
|
|
137
|
+
*
|
|
138
|
+
* Default: 6
|
|
139
|
+
*/
|
|
140
|
+
maxPathDepth?: number
|
|
126
141
|
}
|
|
127
142
|
|
|
128
143
|
export interface DocumentTranslationConfig {
|
|
@@ -157,4 +172,10 @@ export interface TranslationConfig {
|
|
|
157
172
|
* Config for document types with a single language field that determines the language for the whole document.
|
|
158
173
|
*/
|
|
159
174
|
document?: DocumentTranslationConfig
|
|
175
|
+
/**
|
|
176
|
+
* A "style guide" that can be used to provide guidance on how to translate content.
|
|
177
|
+
* Will be passed to the LLM - ergo this is only a guide and the model _may_ not
|
|
178
|
+
* always follow it to the letter.
|
|
179
|
+
*/
|
|
180
|
+
styleguide?: string
|
|
160
181
|
}
|
package/src/types.ts
CHANGED
package/src/useApiClient.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {SanityClient} from '@sanity/client'
|
|
2
|
+
import {useToast} from '@sanity/ui'
|
|
2
3
|
import {useCallback, useMemo, useState} from 'react'
|
|
4
|
+
import {Path, pathToString, useClient, useCurrentUser, useSchema} from 'sanity'
|
|
5
|
+
|
|
6
|
+
import {ConditionalMemberState} from './helpers/conditionalMembers'
|
|
3
7
|
import {serializeSchema} from './schemas/serialize/serializeSchema'
|
|
4
|
-
import {useToast} from '@sanity/ui'
|
|
5
|
-
import {SanityClient} from '@sanity/client'
|
|
6
8
|
import {FieldLanguageMap} from './translate/paths'
|
|
7
9
|
import {documentRootKey} from './types'
|
|
8
|
-
import {ConditionalMemberState} from './helpers/conditionalMembers'
|
|
9
10
|
|
|
10
11
|
export interface UserTextInstance {
|
|
11
12
|
blockKey: string
|
|
@@ -33,6 +34,7 @@ export interface TranslateRequest {
|
|
|
33
34
|
documentId: string
|
|
34
35
|
translatePath: Path
|
|
35
36
|
languagePath?: string
|
|
37
|
+
styleguide?: string
|
|
36
38
|
fieldLanguageMap?: FieldLanguageMap[]
|
|
37
39
|
conditionalMembers?: ConditionalMemberState[]
|
|
38
40
|
}
|
|
@@ -62,6 +64,7 @@ export function useTranslate(apiClient: SanityClient) {
|
|
|
62
64
|
({
|
|
63
65
|
documentId,
|
|
64
66
|
languagePath,
|
|
67
|
+
styleguide,
|
|
65
68
|
translatePath,
|
|
66
69
|
fieldLanguageMap,
|
|
67
70
|
conditionalMembers,
|
|
@@ -78,6 +81,7 @@ export function useTranslate(apiClient: SanityClient) {
|
|
|
78
81
|
documentId,
|
|
79
82
|
types,
|
|
80
83
|
languagePath,
|
|
84
|
+
userStyleguide: styleguide,
|
|
81
85
|
fieldLanguageMap,
|
|
82
86
|
conditionalMembers,
|
|
83
87
|
translatePath:
|