@sanity/assist 3.0.5 → 3.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/assist",
3
- "version": "3.0.5",
3
+ "version": "3.0.6",
4
4
  "description": "You create the instructions; Sanity AI Assist does the rest.",
5
5
  "keywords": [
6
6
  "sanity",
@@ -1,5 +1,5 @@
1
1
  import {Card, Stack, Text} from '@sanity/ui'
2
- import {createContext, useContext, useEffect, useMemo, useRef} from 'react'
2
+ import {useContext, useEffect, useMemo, useRef} from 'react'
3
3
  import {
4
4
  FormCallbacksProvider,
5
5
  FormCallbacksValue,
@@ -21,7 +21,6 @@ import {
21
21
 
22
22
  import {useAiPaneRouter} from '../../assistInspector/helpers'
23
23
  import {useAiAssistanceConfig} from '../../assistLayout/AiAssistanceConfigContext'
24
- import {documentTypeFromAiDocumentId} from '../../helpers/ids'
25
24
  import {
26
25
  AssistDocument,
27
26
  AssistField,
@@ -32,13 +31,12 @@ import {
32
31
  instructionParam,
33
32
  StudioInstruction,
34
33
  } from '../../types'
34
+ import {AssistTypeContext} from './AssistTypeContext'
35
35
  import {BackToInstructionListLink} from './instruction/BackToInstructionsLink'
36
36
  import {SelectedFieldContextProvider, SelectedFieldContextValue} from './SelectedFieldContext'
37
37
 
38
38
  const EMPTY_FIELDS: AssistField[] = []
39
39
 
40
- export const TypePathContext = createContext<string | undefined>(undefined)
41
-
42
40
  export function AssistDocumentForm(props: ObjectInputProps) {
43
41
  if (props.readOnly) {
44
42
  return (
@@ -55,16 +53,9 @@ function AssistDocumentFormEditable(props: ObjectInputProps) {
55
53
  const id = value?._id
56
54
  const fields = value?.fields
57
55
 
58
- const targetDocumentType = useMemo(() => {
59
- if (!id) {
60
- return undefined
61
- }
62
- return documentTypeFromAiDocumentId(id)
63
- }, [id])
64
-
65
56
  const {params, setParams} = useAiPaneRouter()
66
57
  const pathKey = params[fieldPathParam]
67
- const typePath = useContext(TypePathContext)
58
+ const {typePath, documentType: targetDocumentType} = useContext(AssistTypeContext)
68
59
  const instruction = params[instructionParam]
69
60
 
70
61
  const activeKey = useMemo(() => {
@@ -0,0 +1,7 @@
1
+ import {createContext} from 'react'
2
+
3
+ export interface AssistTypeContextValue {
4
+ typePath?: string
5
+ documentType?: string
6
+ }
7
+ export const AssistTypeContext = createContext<AssistTypeContextValue>({})
@@ -4,12 +4,12 @@ import {set, StringInputProps} from 'sanity'
4
4
 
5
5
  import {FieldAutocomplete} from '../../../assistInspector/FieldAutocomplete'
6
6
  import {FieldRef} from '../../../assistInspector/helpers'
7
- import {TypePathContext} from '../AssistDocumentForm'
7
+ import {AssistTypeContext} from '../AssistTypeContext'
8
8
  import {SelectedFieldContext} from '../SelectedFieldContext'
9
9
 
10
10
  export function FieldRefPathInput(props: StringInputProps) {
11
11
  const documentSchema = useContext(SelectedFieldContext)?.documentSchema
12
- const typePath = useContext(TypePathContext)
12
+ const {typePath} = useContext(AssistTypeContext)
13
13
  const ref = useRef<HTMLDivElement>(null)
14
14
  const id = useId()
15
15
  const {onChange} = props
@@ -168,7 +168,7 @@ function ArrayOutputInput({
168
168
  <Flex key={itemType.name}>
169
169
  <Selectable
170
170
  value={itemType.name}
171
- title={isType(itemType, 'block') ? 'Text' : itemType.title ?? itemType.name}
171
+ title={isType(itemType, 'block') ? 'Text' : (itemType.title ?? itemType.name)}
172
172
  arrayValue={value as OutputTypeItem[] | undefined}
173
173
  onChange={onSelectChange}
174
174
  />
@@ -8,7 +8,7 @@ export function InstructionVisibility(props: StringInputProps) {
8
8
  const user = useCurrentUser()
9
9
 
10
10
  const handleChange = useCallback(() => {
11
- const newValue = value ? '' : user?.id ?? ''
11
+ const newValue = value ? '' : (user?.id ?? '')
12
12
  onChange(newValue ? set(newValue) : unset())
13
13
  }, [onChange, user, value])
14
14
 
@@ -16,7 +16,7 @@ import {
16
16
  import {styled} from 'styled-components'
17
17
 
18
18
  import {DocumentForm} from '../_lib/form'
19
- import {TypePathContext} from '../assistDocument/components/AssistDocumentForm'
19
+ import {AssistTypeContext} from '../assistDocument/components/AssistTypeContext'
20
20
  import {useStudioAssistDocument} from '../assistDocument/hooks/useStudioAssistDocument'
21
21
  import {
22
22
  getAssistableDocId,
@@ -290,6 +290,8 @@ export function AssistInspector(props: DocumentInspectorProps) {
290
290
  return <div {..._props} style={{height: '100%', flex: 1, overflow: 'auto'}} />
291
291
  }, [])
292
292
 
293
+ const assistTypeContext = useMemo(() => ({typePath, documentType}), [typePath, documentType])
294
+
293
295
  if (!documentId || !schemaType || schemaType.jsonType !== 'object') {
294
296
  return (
295
297
  <Card flex={1} padding={4}>
@@ -319,7 +321,7 @@ export function AssistInspector(props: DocumentInspectorProps) {
319
321
  <PresenceOverlay>
320
322
  <Box padding={4}>
321
323
  {selectedField && (
322
- <TypePathContext.Provider value={typePath}>
324
+ <AssistTypeContext.Provider value={assistTypeContext}>
323
325
  <VirtualizerScrollInstanceProvider
324
326
  scrollElement={boundary.current}
325
327
  containerElement={boundary}
@@ -333,7 +335,7 @@ export function AssistInspector(props: DocumentInspectorProps) {
333
335
  <DocumentForm />
334
336
  </DocumentPaneProvider>
335
337
  </VirtualizerScrollInstanceProvider>
336
- </TypePathContext.Provider>
338
+ </AssistTypeContext.Provider>
337
339
  )}
338
340
  </Box>
339
341
  </PresenceOverlay>
@@ -112,7 +112,7 @@ export function InstructionTaskHistoryButton(props: InstructionTaskHistoryButton
112
112
  const instruction = instructions?.find((i) => i._key === task.instructionKey)
113
113
  return {
114
114
  ...task,
115
- title: showTitles ? task.title ?? getInstructionTitle(instruction) : undefined,
115
+ title: showTitles ? (task.title ?? getInstructionTitle(instruction)) : undefined,
116
116
  cancel: () => cancelRun(task._key),
117
117
  }
118
118
  }) ?? []
@@ -187,6 +187,7 @@ const TaskStatusButton = forwardRef(function TaskStatusButton(
187
187
  return (
188
188
  <StatusButton
189
189
  label={`${pluginTitle} status`}
190
+ aria-label={`${pluginTitle} status`}
190
191
  icon={isRunning ? SyncSpinningIcon : hasErrors ? ErrorOutlineIcon : CheckmarkCircleIcon}
191
192
  mode="bleed"
192
193
  onClick={onClick}
@@ -0,0 +1,17 @@
1
+ import {describe, expect, test} from 'vitest'
2
+
3
+ import {assistDocumentId} from './ids'
4
+
5
+ describe('ids', () => {
6
+ test('assistDocumentId should replace illegal id chars with _', () => {
7
+ const testCases = [
8
+ {schemaType: 'test', assistId: 'sanity.assist.schemaType.test'},
9
+ {schemaType: 'test-type', assistId: 'sanity.assist.schemaType.test-type'},
10
+ {schemaType: 'test/type', assistId: 'sanity.assist.schemaType.test_type'},
11
+ {schemaType: '%broken©™£€∞', assistId: 'sanity.assist.schemaType._broken_____'},
12
+ ]
13
+ const outputs = testCases.map((testCase) => assistDocumentId(testCase.schemaType))
14
+ const expected = testCases.map((testCase) => testCase.assistId)
15
+ expect(outputs).toEqual(expected)
16
+ })
17
+ })
@@ -1,17 +1,13 @@
1
1
  import {assistDocumentIdPrefix, assistDocumentStatusIdPrefix} from '../types'
2
2
 
3
- const aiDocPrefixPattern = new RegExp(`^${assistDocumentIdPrefix}`)
3
+ const illegalIdChars = /[^a-zA-Z0-9._-]/g
4
4
 
5
5
  export function publicId(id: string) {
6
6
  return id.replace('drafts.', '')
7
7
  }
8
8
 
9
9
  export function assistDocumentId(documentType: string) {
10
- return `${assistDocumentIdPrefix}${documentType}`
11
- }
12
-
13
- export function documentTypeFromAiDocumentId(id: string) {
14
- return id.replace(aiDocPrefixPattern, '')
10
+ return `${assistDocumentIdPrefix}${documentType}`.replace(illegalIdChars, '_')
15
11
  }
16
12
 
17
13
  export function assistTasksStatusId(documentId: string) {
@@ -170,7 +170,7 @@ export const promptContext = defineType({
170
170
  },
171
171
  prepare(select) {
172
172
  return select.ref
173
- ? contextDocumentSchema?.preview?.prepare?.(select) ?? select
173
+ ? (contextDocumentSchema?.preview?.prepare?.(select) ?? select)
174
174
  : {title: 'No reference selected', media: contextDocumentSchema.icon}
175
175
  },
176
176
  },
@@ -89,7 +89,7 @@ function getBaseFields(
89
89
  options: Object.keys(schemaOptions).length ? schemaOptions : undefined,
90
90
  values: Array.isArray(type?.options?.list)
91
91
  ? type?.options?.list.map((v: string | {value: string; title: string}) =>
92
- typeof v === 'string' ? v : v.value ?? `${v.title}`,
92
+ typeof v === 'string' ? v : (v.value ?? `${v.title}`),
93
93
  )
94
94
  : undefined,
95
95
  of: 'of' in type && typeName === 'array' ? arrayOf(type, schema, options) : undefined,
@@ -156,7 +156,7 @@ function serializeMember(
156
156
  options: Options | undefined,
157
157
  ): SerializedSchemaMember {
158
158
  const typeNameExists = !!schema.get(type?.name)
159
- const typeName = typeNameExists ? type.name : type.type?.name ?? ''
159
+ const typeName = typeNameExists ? type.name : (type.type?.name ?? '')
160
160
  return removeUndef({
161
161
  ...(options?.leanFormat ? {} : {_type: assistSerializedFieldTypeName}),
162
162
  name: name,