@sanity/assist 5.0.3 → 6.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 (131) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +28 -254
  3. package/dist/index.d.ts +322 -410
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +3182 -2673
  6. package/dist/index.js.map +1 -1
  7. package/package.json +41 -77
  8. package/dist/index.cjs +0 -4264
  9. package/dist/index.cjs.map +0 -1
  10. package/dist/index.d.cts +0 -791
  11. package/sanity.json +0 -8
  12. package/src/_lib/connector/ConnectFromRegion.tsx +0 -25
  13. package/src/_lib/connector/ConnectToRegion.tsx +0 -23
  14. package/src/_lib/connector/ConnectorRegion.tsx +0 -24
  15. package/src/_lib/connector/ConnectorsProvider.tsx +0 -20
  16. package/src/_lib/connector/ConnectorsStore.ts +0 -122
  17. package/src/_lib/connector/ConnectorsStoreContext.ts +0 -5
  18. package/src/_lib/connector/helpers.ts +0 -5
  19. package/src/_lib/connector/index.ts +0 -9
  20. package/src/_lib/connector/mapConnectorToLine.ts +0 -83
  21. package/src/_lib/connector/types.ts +0 -56
  22. package/src/_lib/connector/useConnectorsStore.ts +0 -14
  23. package/src/_lib/connector/useRegionRects.ts +0 -142
  24. package/src/_lib/fixedListenQuery.ts +0 -101
  25. package/src/_lib/form/DocumentForm.tsx +0 -201
  26. package/src/_lib/form/constants.ts +0 -1
  27. package/src/_lib/form/helpers.ts +0 -32
  28. package/src/_lib/form/index.ts +0 -1
  29. package/src/_lib/randomKey.ts +0 -29
  30. package/src/_lib/useListeningQuery.ts +0 -62
  31. package/src/_lib/usePrevious.ts +0 -9
  32. package/src/assistConnectors/AssistConnectorsOverlay.tsx +0 -133
  33. package/src/assistConnectors/ConnectorPath.tsx +0 -63
  34. package/src/assistConnectors/draw/arrowPath.ts +0 -9
  35. package/src/assistConnectors/draw/connectorPath.ts +0 -142
  36. package/src/assistConnectors/index.ts +0 -1
  37. package/src/assistDocument/AssistDocumentContext.tsx +0 -51
  38. package/src/assistDocument/AssistDocumentContextProvider.tsx +0 -17
  39. package/src/assistDocument/AssistDocumentInput.tsx +0 -61
  40. package/src/assistDocument/AssistDocumentLayout.tsx +0 -12
  41. package/src/assistDocument/RequestRunInstructionProvider.tsx +0 -61
  42. package/src/assistDocument/components/AssistDocumentForm.tsx +0 -286
  43. package/src/assistDocument/components/AssistTypeContext.tsx +0 -7
  44. package/src/assistDocument/components/FieldRefPreview.tsx +0 -26
  45. package/src/assistDocument/components/InstructionsArrayField.tsx +0 -8
  46. package/src/assistDocument/components/InstructionsArrayInput.tsx +0 -27
  47. package/src/assistDocument/components/SelectedFieldContext.tsx +0 -10
  48. package/src/assistDocument/components/generic/HiddenFieldTitle.tsx +0 -5
  49. package/src/assistDocument/components/helpers.ts +0 -21
  50. package/src/assistDocument/components/instruction/BackToInstructionsLink.tsx +0 -32
  51. package/src/assistDocument/components/instruction/FieldRefInput.tsx +0 -54
  52. package/src/assistDocument/components/instruction/InstructionInput.tsx +0 -89
  53. package/src/assistDocument/components/instruction/InstructionOutputField.tsx +0 -46
  54. package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +0 -206
  55. package/src/assistDocument/components/instruction/PromptInput.tsx +0 -59
  56. package/src/assistDocument/components/instruction/appearance/IconInput.tsx +0 -46
  57. package/src/assistDocument/components/instruction/appearance/InstructionVisibility.tsx +0 -37
  58. package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +0 -129
  59. package/src/assistDocument/hooks/useDocumentState.ts +0 -6
  60. package/src/assistDocument/hooks/useInstructionToaster.tsx +0 -75
  61. package/src/assistDocument/hooks/useStudioAssistDocument.ts +0 -99
  62. package/src/assistDocument/index.ts +0 -1
  63. package/src/assistFormComponents/AssistField.tsx +0 -63
  64. package/src/assistFormComponents/AssistFormBlock.tsx +0 -31
  65. package/src/assistFormComponents/AssistInlineFormBlock.tsx +0 -13
  66. package/src/assistFormComponents/AssistItem.tsx +0 -21
  67. package/src/assistFormComponents/validation/listItem.tsx +0 -63
  68. package/src/assistFormComponents/validation/validationList.tsx +0 -90
  69. package/src/assistInspector/AssistInspector.tsx +0 -423
  70. package/src/assistInspector/FieldAutocomplete.tsx +0 -146
  71. package/src/assistInspector/InstructionTaskHistoryButton.tsx +0 -262
  72. package/src/assistInspector/constants.ts +0 -1
  73. package/src/assistInspector/helpers.ts +0 -211
  74. package/src/assistInspector/index.ts +0 -27
  75. package/src/assistLayout/AiAssistanceConfigContext.tsx +0 -32
  76. package/src/assistLayout/AiAssistanceConfigProvider.tsx +0 -98
  77. package/src/assistLayout/AssistLayout.tsx +0 -39
  78. package/src/assistLayout/RunInstructionProvider.tsx +0 -278
  79. package/src/assistLayout/fieldRefCache.tsx +0 -34
  80. package/src/assistTypes.ts +0 -83
  81. package/src/components/AssistFeatureBadge.tsx +0 -9
  82. package/src/components/FadeInContent.tsx +0 -40
  83. package/src/components/HideReferenceChangedBannerInput.tsx +0 -25
  84. package/src/components/ImageContext.tsx +0 -85
  85. package/src/components/SafeValueInput.tsx +0 -74
  86. package/src/components/TimeAgo.tsx +0 -18
  87. package/src/constants.ts +0 -20
  88. package/src/fieldActions/PrivateIcon.tsx +0 -20
  89. package/src/fieldActions/assistFieldActions.tsx +0 -320
  90. package/src/fieldActions/customFieldActions.tsx +0 -333
  91. package/src/fieldActions/generateCaptionActions.tsx +0 -77
  92. package/src/fieldActions/generateImageActions.tsx +0 -58
  93. package/src/fieldActions/useUserInput.ts +0 -107
  94. package/src/globals.d.ts +0 -4
  95. package/src/helpers/assistSupported.ts +0 -49
  96. package/src/helpers/conditionalMembers.test.ts +0 -319
  97. package/src/helpers/conditionalMembers.ts +0 -134
  98. package/src/helpers/ids.test.ts +0 -28
  99. package/src/helpers/ids.ts +0 -23
  100. package/src/helpers/misc.ts +0 -25
  101. package/src/helpers/styleguide.ts +0 -24
  102. package/src/helpers/typeUtils.ts +0 -60
  103. package/src/helpers/useAssistSupported.ts +0 -8
  104. package/src/index.ts +0 -26
  105. package/src/onboarding/FirstAssistedPathProvider.tsx +0 -30
  106. package/src/onboarding/InspectorOnboarding.tsx +0 -47
  107. package/src/onboarding/onboardingStore.ts +0 -32
  108. package/src/plugin.tsx +0 -162
  109. package/src/presence/AiFieldPresence.tsx +0 -28
  110. package/src/presence/AssistAvatar.tsx +0 -96
  111. package/src/presence/AssistDocumentPresence.tsx +0 -50
  112. package/src/presence/useAssistPresence.ts +0 -64
  113. package/src/schemas/assistDocumentSchema.tsx +0 -497
  114. package/src/schemas/contextDocumentSchema.tsx +0 -57
  115. package/src/schemas/index.ts +0 -69
  116. package/src/schemas/serialize/SchemTypeTool.tsx +0 -103
  117. package/src/schemas/serialize/schemaUtils.ts +0 -38
  118. package/src/schemas/serialize/serializeSchema.test.ts +0 -819
  119. package/src/schemas/serialize/serializeSchema.ts +0 -224
  120. package/src/schemas/serializedSchemaTypeSchema.ts +0 -60
  121. package/src/schemas/typeDefExtensions.ts +0 -127
  122. package/src/translate/FieldTranslationProvider.tsx +0 -382
  123. package/src/translate/getLanguageParams.ts +0 -26
  124. package/src/translate/languageStore.ts +0 -18
  125. package/src/translate/paths.test.ts +0 -181
  126. package/src/translate/paths.ts +0 -183
  127. package/src/translate/translateActions.tsx +0 -205
  128. package/src/translate/types.ts +0 -197
  129. package/src/types.ts +0 -220
  130. package/src/useApiClient.ts +0 -338
  131. package/v2-incompatible.js +0 -11
@@ -1,382 +0,0 @@
1
- import {PlayIcon} from '@sanity/icons'
2
- import {Box, Button, Checkbox, Dialog, Flex, Radio, Spinner, Stack, Text, Tooltip} from '@sanity/ui'
3
- import {
4
- createContext,
5
- type PropsWithChildren,
6
- useCallback,
7
- useContext,
8
- useId,
9
- useMemo,
10
- useState,
11
- } from 'react'
12
- import {
13
- type ObjectSchemaType,
14
- type Path,
15
- pathToString,
16
- type SanityDocumentLike,
17
- useClient,
18
- } from 'sanity'
19
-
20
- import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
21
- import type {ConditionalMemberState} from '../helpers/conditionalMembers'
22
- import {createStyleGuideResolver} from '../helpers/styleguide'
23
- import {API_VERSION_WITH_EXTENDED_TYPES, useApiClient, useTranslate} from '../useApiClient'
24
- import {getLanguageParams} from './getLanguageParams'
25
- import {getPreferredToFieldLanguages, setPreferredToFieldLanguages} from './languageStore'
26
- import {
27
- defaultLanguageOutputs,
28
- type FieldLanguageMap,
29
- getDocumentMembersFlat,
30
- getFieldLanguageMap,
31
- } from './paths'
32
- import type {Language} from './types'
33
-
34
- interface FieldTranslationParams {
35
- document: SanityDocumentLike
36
- documentSchema: ObjectSchemaType
37
- translatePath: Path
38
- conditionalMembers: ConditionalMemberState[]
39
- }
40
-
41
- export interface FieldTranslationContextValue {
42
- openFieldTranslation: (args: FieldTranslationParams) => void
43
- translationLoading: boolean
44
- }
45
-
46
- export const FieldTranslationContext = createContext<FieldTranslationContextValue>({
47
- openFieldTranslation: () => {},
48
- translationLoading: false,
49
- })
50
-
51
- export function useFieldTranslation() {
52
- return useContext(FieldTranslationContext)
53
- }
54
-
55
- function hasValuesToTranslate(
56
- fieldLanguageMaps: FieldLanguageMap[] | undefined,
57
- fromLanguage: Language | undefined,
58
- basePath: Path,
59
- ) {
60
- return fieldLanguageMaps?.some(
61
- (map) =>
62
- map.inputLanguageId === fromLanguage?.id &&
63
- map.inputPath &&
64
- pathToString(map.inputPath).startsWith(pathToString(basePath)),
65
- )
66
- }
67
-
68
- // eslint-disable-next-line @typescript-eslint/ban-types
69
- export function FieldTranslationProvider(props: PropsWithChildren<{}>) {
70
- const {config: assistConfig} = useAiAssistanceConfig()
71
-
72
- const apiClient = useApiClient(assistConfig.__customApiClient)
73
- const styleguide = assistConfig.translate?.styleguide
74
- const config = assistConfig.translate?.field
75
- const {translate: runTranslate} = useTranslate(apiClient)
76
-
77
- const [dialogOpen, setDialogOpen] = useState(false)
78
-
79
- const [fieldTranslationParams, setFieldTranslationParams] = useState<
80
- FieldTranslationParams | undefined
81
- >()
82
- const [languages, setLanguages] = useState<Language[] | undefined>()
83
- const [fromLanguage, setFromLanguage] = useState<Language | undefined>(undefined)
84
- const [toLanguages, setToLanguages] = useState<Language[] | undefined>(undefined)
85
- const [fieldLanguageMaps, setFieldLanguageMaps] = useState<FieldLanguageMap[] | undefined>()
86
-
87
- const close = useCallback(() => {
88
- setDialogOpen(false)
89
- setLanguages(undefined)
90
- setFieldTranslationParams(undefined)
91
- }, [])
92
- const languageClient = useClient({
93
- apiVersion: config?.apiVersion ?? API_VERSION_WITH_EXTENDED_TYPES,
94
- })
95
- const documentId = fieldTranslationParams?.document?._id
96
- const id = useId()
97
-
98
- const selectFromLanguage = useCallback(
99
- (
100
- from: Language,
101
- languages: Language[] | undefined,
102
- params: FieldTranslationParams | undefined,
103
- ) => {
104
- const {document, documentSchema} = params ?? {}
105
- setFromLanguage(from)
106
- if (!document || !documentSchema || !params || !languages) {
107
- setFieldLanguageMaps(undefined)
108
- return
109
- }
110
-
111
- const preferred = getPreferredToFieldLanguages(from.id)
112
- const allToLanguages = languages.filter((l) => l.id !== from?.id)
113
- const filteredToLanguages = allToLanguages.filter(
114
- (l) => !preferred.length || preferred.includes(l.id),
115
- )
116
-
117
- setToLanguages(filteredToLanguages)
118
- const fromId = from?.id
119
- const allToIds = allToLanguages?.map((l) => l.id) ?? []
120
- const docMembers = getDocumentMembersFlat(document, documentSchema, config?.maxPathDepth)
121
- if (fromId && allToIds?.length) {
122
- const transMap = getFieldLanguageMap(
123
- documentSchema,
124
- docMembers,
125
- fromId,
126
- allToIds.filter((toId) => fromId !== toId),
127
- config?.translationOutputs ?? defaultLanguageOutputs,
128
- )
129
- setFieldLanguageMaps(transMap)
130
- } else {
131
- setFieldLanguageMaps(undefined)
132
- }
133
- },
134
- [config],
135
- )
136
-
137
- const toggleToLanguage = useCallback(
138
- (
139
- toggledLang: Language,
140
- toLanguages: Language[] | undefined,
141
- languages: Language[] | undefined,
142
- ) => {
143
- if (!languages || !fromLanguage) {
144
- return
145
- }
146
- const wasSelected = !!toLanguages?.find((l) => l.id === toggledLang.id)
147
- const newToLangs = languages.filter(
148
- (anyLang) =>
149
- !!toLanguages?.find(
150
- (selectedLang) => toggledLang.id !== selectedLang.id && selectedLang.id === anyLang.id,
151
- ) ||
152
- (toggledLang.id === anyLang.id && !wasSelected),
153
- )
154
- setToLanguages(newToLangs)
155
- setPreferredToFieldLanguages(
156
- fromLanguage.id,
157
- newToLangs.map((l) => l.id),
158
- )
159
- },
160
- [fromLanguage],
161
- )
162
-
163
- const openFieldTranslation = useCallback(
164
- async (params: FieldTranslationParams) => {
165
- setDialogOpen(true)
166
- const languageParams = getLanguageParams(config?.selectLanguageParams, params.document)
167
- const languages: Language[] | undefined = await (typeof config?.languages === 'function'
168
- ? config?.languages(languageClient, languageParams)
169
- : Promise.resolve(config?.languages))
170
- setLanguages(languages)
171
- setFieldTranslationParams(params)
172
- const fromLanguage = languages?.[0]
173
- if (fromLanguage) {
174
- selectFromLanguage(fromLanguage, languages, params)
175
- } else {
176
- console.error('No languages available for selected language params', languageParams)
177
- }
178
- },
179
- [selectFromLanguage, config, languageClient],
180
- )
181
-
182
- const contextValue: FieldTranslationContextValue = useMemo(() => {
183
- return {
184
- openFieldTranslation,
185
- translationLoading: false,
186
- }
187
- }, [openFieldTranslation])
188
-
189
- const runDisabled =
190
- !fromLanguage ||
191
- !toLanguages?.length ||
192
- !fieldLanguageMaps?.length ||
193
- !documentId ||
194
- !hasValuesToTranslate(fieldLanguageMaps, fromLanguage, fieldTranslationParams.translatePath)
195
-
196
- const onRunTranslation = useCallback(() => {
197
- const translatePath = fieldTranslationParams?.translatePath
198
- if (fieldLanguageMaps && documentId && translatePath) {
199
- runTranslate({
200
- documentId,
201
- translatePath,
202
- styleguide: createStyleGuideResolver(styleguide, {
203
- client: languageClient,
204
- documentId,
205
- schemaType: fieldTranslationParams?.documentSchema,
206
- translatePath,
207
- }),
208
- fieldLanguageMap: fieldLanguageMaps.map((map) => ({
209
- ...map,
210
- // eslint-disable-next-line max-nested-callbacks
211
- outputs: map.outputs.filter((out) => !!toLanguages?.find((l) => l.id === out.id)),
212
- })),
213
- conditionalMembers: fieldTranslationParams?.conditionalMembers,
214
- })
215
- }
216
- close()
217
- }, [
218
- fieldLanguageMaps,
219
- documentId,
220
- runTranslate,
221
- styleguide,
222
- close,
223
- toLanguages,
224
- fieldTranslationParams?.translatePath,
225
- fieldTranslationParams?.conditionalMembers,
226
- fieldTranslationParams?.documentSchema,
227
- languageClient,
228
- ])
229
-
230
- const runButton = (
231
- <Button
232
- text={`Translate`}
233
- tone="primary"
234
- icon={PlayIcon}
235
- style={{width: '100%'}}
236
- disabled={runDisabled}
237
- onClick={onRunTranslation}
238
- />
239
- )
240
-
241
- return (
242
- <FieldTranslationContext.Provider value={contextValue}>
243
- {dialogOpen ? (
244
- <Dialog
245
- id={id}
246
- width={1}
247
- open={dialogOpen}
248
- onClose={close}
249
- header="Translate fields"
250
- footer={
251
- <Flex justify="space-between" padding={2} flex={1}>
252
- {runDisabled ? (
253
- <Tooltip
254
- content={
255
- <Flex padding={2}>
256
- <Text>There is nothing to translate in the selected from-language.</Text>
257
- </Flex>
258
- }
259
- placement="top"
260
- >
261
- <Flex flex={1}>{runButton}</Flex>
262
- </Tooltip>
263
- ) : (
264
- runButton
265
- )}
266
- </Flex>
267
- }
268
- >
269
- {languages ? (
270
- <Flex padding={4} gap={5} align="flex-start" justify="center">
271
- <Stack space={2}>
272
- <Box marginBottom={2}>
273
- <Text weight="semibold">From</Text>
274
- </Box>
275
- {languages?.map((radioLanguage) => (
276
- <FromLanguageRadio
277
- key={radioLanguage.id}
278
- {...{
279
- radioLanguage,
280
- fromLanguage,
281
- selectFromLanguage,
282
- languages,
283
- fieldTranslationParams,
284
- }}
285
- />
286
- ))}
287
- </Stack>
288
-
289
- <Stack space={2}>
290
- <Box marginBottom={2}>
291
- <Text weight="semibold">To</Text>
292
- </Box>
293
- {languages.map((checkboxLanguage) => (
294
- <ToLanguageCheckbox
295
- key={checkboxLanguage.id}
296
- {...{checkboxLanguage, fromLanguage, toLanguages, toggleToLanguage, languages}}
297
- />
298
- ))}
299
- </Stack>
300
- </Flex>
301
- ) : (
302
- <Flex padding={4} gap={2} align="flex-start" justify="center">
303
- <Box>
304
- <Spinner />
305
- </Box>
306
- <Text>Loading languages...</Text>
307
- </Flex>
308
- )}
309
- </Dialog>
310
- ) : null}
311
- {props.children}
312
- </FieldTranslationContext.Provider>
313
- )
314
- }
315
-
316
- function ToLanguageCheckbox(props: {
317
- checkboxLanguage: Language
318
- fromLanguage: Language | undefined
319
- toLanguages: Language[] | undefined
320
- toggleToLanguage: (
321
- toggledLang: Language,
322
- toLanguages: Language[] | undefined,
323
- languages: Language[] | undefined,
324
- ) => void
325
- languages: Language[]
326
- }) {
327
- const {checkboxLanguage, fromLanguage, toLanguages, toggleToLanguage, languages} = props
328
- const langId = checkboxLanguage.id
329
- const onChange = useCallback(
330
- () => toggleToLanguage(checkboxLanguage, toLanguages, languages),
331
- [toggleToLanguage, checkboxLanguage, toLanguages, languages],
332
- )
333
- return (
334
- <Flex
335
- key={langId}
336
- gap={3}
337
- align="center"
338
- as={'label'}
339
- style={langId === fromLanguage?.id ? {opacity: 0.5} : undefined}
340
- >
341
- <Checkbox
342
- name="toLang"
343
- value={langId}
344
- checked={langId !== fromLanguage?.id && !!toLanguages?.find((tl) => tl.id === langId)}
345
- onChange={onChange}
346
- disabled={langId === fromLanguage?.id}
347
- />
348
- <Text muted={langId === fromLanguage?.id}>{checkboxLanguage.title ?? langId}</Text>
349
- </Flex>
350
- )
351
- }
352
-
353
- function FromLanguageRadio(props: {
354
- radioLanguage: Language
355
- fromLanguage: Language | undefined
356
- selectFromLanguage: (
357
- from: Language,
358
- languages: Language[] | undefined,
359
- params: FieldTranslationParams | undefined,
360
- ) => void
361
- languages: Language[] | undefined
362
- fieldTranslationParams: FieldTranslationParams | undefined
363
- }) {
364
- const {languages, radioLanguage, selectFromLanguage, fromLanguage, fieldTranslationParams} = props
365
- const langId = radioLanguage.id
366
-
367
- const onChange = useCallback(
368
- () => selectFromLanguage(radioLanguage, languages, fieldTranslationParams),
369
- [selectFromLanguage, radioLanguage, languages, fieldTranslationParams],
370
- )
371
- return (
372
- <Flex key={langId} gap={3} align="center" as={'label'}>
373
- <Radio
374
- name="fromLang"
375
- value={langId}
376
- checked={langId === fromLanguage?.id}
377
- onChange={onChange}
378
- />
379
- <Text>{radioLanguage.title ?? radioLanguage.id}</Text>
380
- </Flex>
381
- )
382
- }
@@ -1,26 +0,0 @@
1
- import {get} from 'lodash'
2
- import type {SanityDocumentLike} from 'sanity'
3
-
4
- export const getLanguageParams = (
5
- select: Record<string, string> | undefined,
6
- document: SanityDocumentLike | undefined,
7
- ): Record<string, unknown> => {
8
- if (!select || !document) {
9
- return {}
10
- }
11
-
12
- const selection: Record<string, string> = select || {}
13
- const selectedValue: Record<string, unknown> = {}
14
- for (const [key, path] of Object.entries(selection)) {
15
- let value = get(document, path)
16
- if (Array.isArray(value)) {
17
- // If there are references in the array, ensure they have `_ref` set, otherwise they are considered empty and can safely be ignored
18
- value = value.filter((item) =>
19
- typeof item === 'object' ? item?._type !== 'reference' || '_ref' in item : true,
20
- )
21
- }
22
- selectedValue[key] = value
23
- }
24
-
25
- return selectedValue
26
- }
@@ -1,18 +0,0 @@
1
- export const toFieldLanguagesKeyPrefix = 'sanityStudio:assist:field-languages:from:'
2
-
3
- export function getPreferredToFieldLanguages(fromLanguageId: string): string[] {
4
- if (typeof localStorage === 'undefined') {
5
- return []
6
- }
7
-
8
- const value = localStorage.getItem(`${toFieldLanguagesKeyPrefix}${fromLanguageId}`)
9
- return value ? (JSON.parse(value) as string[]) : []
10
- }
11
-
12
- export function setPreferredToFieldLanguages(fromLanguageId: string, languageIds: string[]) {
13
- if (typeof localStorage === 'undefined') {
14
- return
15
- }
16
-
17
- localStorage.setItem(`${toFieldLanguagesKeyPrefix}${fromLanguageId}`, JSON.stringify(languageIds))
18
- }
@@ -1,181 +0,0 @@
1
- import {Schema} from '@sanity/schema'
2
- import {
3
- defineType,
4
- type ObjectSchemaType,
5
- pathToString,
6
- type SanityDocumentLike,
7
- typed,
8
- } from 'sanity'
9
- import {describe, expect, test} from 'vitest'
10
-
11
- import {
12
- defaultLanguageOutputs,
13
- type FieldLanguageMap,
14
- getDocumentMembersFlat,
15
- getFieldLanguageMap,
16
- } from './paths'
17
-
18
- describe('paths', () => {
19
- test('should return internationalizedArrayString paths and find translation mappings', () => {
20
- const docSchema: ObjectSchemaType = Schema.compile({
21
- name: 'test',
22
- types: [
23
- defineType({
24
- type: 'document',
25
- name: 'article',
26
- fields: [
27
- {type: 'string', name: 'title'},
28
- {
29
- type: 'object',
30
- name: 'localeTitle',
31
- fields: [
32
- {type: 'string', name: 'en'},
33
- {type: 'string', name: 'no'},
34
- ],
35
- },
36
- {
37
- type: 'array',
38
- name: 'translations',
39
- of: [
40
- {
41
- type: 'object',
42
- name: 'internationalizedArrayString',
43
- fields: [{type: 'string', name: 'value'}],
44
- },
45
- ],
46
- },
47
- ],
48
- }),
49
- ],
50
- }).get('article')
51
-
52
- const doc: SanityDocumentLike = {
53
- _id: 'na',
54
- _type: 'article',
55
- title: 'some title',
56
- localeTitle: {
57
- en: 'en string',
58
- },
59
- translations: [
60
- {
61
- _type: 'internationalizedArrayString',
62
- _key: 'en',
63
- value: 'some string',
64
- },
65
- ],
66
- }
67
-
68
- const members = getDocumentMembersFlat(doc, docSchema)
69
- expect(members.map((p) => pathToString(p.path))).toEqual([
70
- 'title',
71
- 'localeTitle',
72
- 'localeTitle.en',
73
- // this path has no value in the document, so are not included
74
- //'localeTitle.no',
75
- 'translations',
76
- 'translations[_key=="en"]',
77
- 'translations[_key=="en"].value',
78
- // these path has no value in the document, so are not included
79
- //'translations[_key=="nb"]',
80
- //'translations[_key=="nb"].value',
81
- ])
82
-
83
- const transMap = getFieldLanguageMap(docSchema, members, 'en', ['nb'], defaultLanguageOutputs)
84
-
85
- expect(transMap).toEqual(
86
- typed<FieldLanguageMap[]>([
87
- {
88
- inputLanguageId: 'en',
89
- inputPath: ['translations', {_key: 'en'}],
90
- outputs: [{id: 'nb', outputPath: ['translations', {_key: 'nb'}]}],
91
- },
92
- ]),
93
- )
94
- })
95
-
96
- test('should use first type in array when array item is missing _type', () => {
97
- const docSchema: ObjectSchemaType = Schema.compile({
98
- name: 'test',
99
- types: [
100
- defineType({
101
- type: 'document',
102
- name: 'article',
103
- fields: [
104
- {
105
- type: 'array',
106
- name: 'translations',
107
- of: [
108
- {
109
- type: 'object',
110
- name: 'internationalizedArrayString',
111
- fields: [{type: 'string', name: 'value'}],
112
- },
113
- ],
114
- },
115
- ],
116
- }),
117
- ],
118
- }).get('article')
119
-
120
- const doc: SanityDocumentLike = {
121
- _id: 'na',
122
- _type: 'article',
123
- translations: [
124
- {
125
- //assume type is missing in the data for some reason
126
- //_type: 'internationalizedArrayString',
127
- _key: 'en',
128
- value: 'some string',
129
- },
130
- ],
131
- }
132
-
133
- const members = getDocumentMembersFlat(doc, docSchema)
134
- expect(members.map((p) => pathToString(p.path))).toEqual([
135
- 'translations',
136
- 'translations[_key=="en"]',
137
- 'translations[_key=="en"].value',
138
- ])
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
- })
181
- })