@sanity/sdk-react 2.5.0 → 2.7.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.
- package/README.md +164 -19
- package/dist/index.d.ts +571 -26
- package/dist/index.js +149 -78
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/_exports/sdk-react.ts +2 -0
- package/src/components/SDKProvider.tsx +8 -3
- package/src/components/SanityApp.test.tsx +72 -2
- package/src/components/SanityApp.tsx +53 -10
- package/src/components/auth/AuthBoundary.tsx +5 -5
- package/src/context/ComlinkTokenRefresh.test.tsx +2 -2
- package/src/context/ComlinkTokenRefresh.tsx +3 -2
- package/src/context/SDKStudioContext.test.tsx +126 -0
- package/src/context/SDKStudioContext.ts +65 -0
- package/src/context/SourcesContext.tsx +7 -0
- package/src/context/renderSanityApp.test.tsx +355 -0
- package/src/context/renderSanityApp.tsx +48 -0
- package/src/hooks/agent/agentActions.ts +436 -21
- package/src/hooks/dashboard/useDispatchIntent.test.ts +26 -20
- package/src/hooks/dashboard/useDispatchIntent.ts +10 -11
- package/src/hooks/dashboard/utils/{getResourceIdFromDocumentHandle.test.ts → useResourceIdFromDocumentHandle.test.ts} +33 -60
- package/src/hooks/dashboard/utils/useResourceIdFromDocumentHandle.ts +46 -0
- package/src/hooks/document/useEditDocument.ts +3 -0
- package/src/hooks/documents/useDocuments.ts +3 -2
- package/src/hooks/helpers/useNormalizedSourceOptions.ts +85 -0
- package/src/hooks/paginatedDocuments/usePaginatedDocuments.ts +1 -0
- package/src/hooks/projection/useDocumentProjection.ts +15 -4
- package/src/hooks/query/useQuery.ts +30 -11
- package/src/hooks/dashboard/types.ts +0 -12
- package/src/hooks/dashboard/utils/getResourceIdFromDocumentHandle.ts +0 -53
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {ApplyDocumentActionsOptions} from '@sanity/sdk'
|
|
|
10
10
|
import {AuthState} from '@sanity/sdk'
|
|
11
11
|
import {CanvasResource} from '@sanity/message-protocol'
|
|
12
12
|
import {ClientOptions} from '@sanity/sdk'
|
|
13
|
+
import {Context} from 'react'
|
|
13
14
|
import {CurrentUser} from '@sanity/sdk'
|
|
14
15
|
import {DatasetHandle} from '@sanity/sdk'
|
|
15
16
|
import {DatasetsResponse} from '@sanity/client'
|
|
@@ -49,6 +50,7 @@ import {SanityQueryResult} from 'groq'
|
|
|
49
50
|
import {SanityUser} from '@sanity/sdk'
|
|
50
51
|
import {SortOrderingItem} from '@sanity/types'
|
|
51
52
|
import {StudioResource} from '@sanity/message-protocol'
|
|
53
|
+
import {TokenSource} from '@sanity/sdk'
|
|
52
54
|
import {UserPresence} from '@sanity/sdk'
|
|
53
55
|
import {WindowMessage} from '@sanity/sdk'
|
|
54
56
|
|
|
@@ -176,18 +178,6 @@ declare interface DispatchIntent {
|
|
|
176
178
|
dispatchIntent: () => void
|
|
177
179
|
}
|
|
178
180
|
|
|
179
|
-
/**
|
|
180
|
-
* Document handle that optionally includes a source (e.g., media library source)
|
|
181
|
-
* or projectId and dataset for traditional dataset sources
|
|
182
|
-
* (but now marked optional since it's valid to just use a source)
|
|
183
|
-
* @beta
|
|
184
|
-
*/
|
|
185
|
-
declare interface DocumentHandleWithSource extends Omit<DocumentHandle, 'projectId' | 'dataset'> {
|
|
186
|
-
source?: DocumentSource
|
|
187
|
-
projectId?: string
|
|
188
|
-
dataset?: string
|
|
189
|
-
}
|
|
190
|
-
|
|
191
181
|
declare interface DocumentInteractionHistory {
|
|
192
182
|
recordEvent: (eventType: 'viewed' | 'edited' | 'created' | 'deleted') => void
|
|
193
183
|
}
|
|
@@ -218,6 +208,7 @@ export declare interface DocumentsOptions<
|
|
|
218
208
|
batchSize?: number
|
|
219
209
|
/**
|
|
220
210
|
* Sorting configuration for the results
|
|
211
|
+
* @beta
|
|
221
212
|
*/
|
|
222
213
|
orderings?: SortOrderingItem[]
|
|
223
214
|
/**
|
|
@@ -307,6 +298,13 @@ export declare type MessageHandler<TWindowMessage extends WindowMessage> = (
|
|
|
307
298
|
event: TWindowMessage['data'],
|
|
308
299
|
) => TWindowMessage['response'] | Promise<TWindowMessage['response']>
|
|
309
300
|
|
|
301
|
+
/** In-flight CLI PR is using named sources since it's aspirational.
|
|
302
|
+
* We can transform the shape in this function until it's finalized.
|
|
303
|
+
*/
|
|
304
|
+
declare interface NamedSources {
|
|
305
|
+
[key: string]: SanityConfig
|
|
306
|
+
}
|
|
307
|
+
|
|
310
308
|
/**
|
|
311
309
|
* @public
|
|
312
310
|
* @category Types
|
|
@@ -343,6 +341,7 @@ export declare interface PaginatedDocumentsOptions<
|
|
|
343
341
|
pageSize?: number
|
|
344
342
|
/**
|
|
345
343
|
* Sorting configuration for the results
|
|
344
|
+
* @beta
|
|
346
345
|
*/
|
|
347
346
|
orderings?: SortOrderingItem[]
|
|
348
347
|
/**
|
|
@@ -446,6 +445,18 @@ export declare type ProjectWithoutMembers = Omit<SanityProject_2, 'members'>
|
|
|
446
445
|
*/
|
|
447
446
|
export declare const REACT_SDK_VERSION: {}
|
|
448
447
|
|
|
448
|
+
/** @internal */
|
|
449
|
+
export declare function renderSanityApp(
|
|
450
|
+
rootElement: HTMLElement | null,
|
|
451
|
+
namedSources: NamedSources,
|
|
452
|
+
options: RenderSanitySDKAppOptions,
|
|
453
|
+
children: React.ReactNode,
|
|
454
|
+
): () => void
|
|
455
|
+
|
|
456
|
+
declare interface RenderSanitySDKAppOptions {
|
|
457
|
+
reactStrictMode?: boolean
|
|
458
|
+
}
|
|
459
|
+
|
|
449
460
|
/**
|
|
450
461
|
* Provides a Sanity instance to child components through React Context
|
|
451
462
|
*
|
|
@@ -518,12 +529,18 @@ export declare interface ResourceProviderProps extends SanityConfig {
|
|
|
518
529
|
* must be wrapped with the SanityApp component to function properly.
|
|
519
530
|
*
|
|
520
531
|
* The `config` prop on the SanityApp component accepts either a single {@link SanityConfig} object, or an array of them.
|
|
521
|
-
* This allows your app to work with one or more of your organization
|
|
532
|
+
* This allows your app to work with one or more of your organization's datasets.
|
|
533
|
+
*
|
|
534
|
+
* When rendered inside a Sanity Studio that provides `SDKStudioContext`, the `config` prop is
|
|
535
|
+
* optional — `SanityApp` will automatically derive `projectId`, `dataset`, and auth from the
|
|
536
|
+
* Studio workspace.
|
|
522
537
|
*
|
|
523
538
|
* @remarks
|
|
524
539
|
* When passing multiple SanityConfig objects to the `config` prop, the first configuration in the array becomes the default
|
|
525
540
|
* configuration used by the App SDK Hooks.
|
|
526
541
|
*
|
|
542
|
+
* When both `config` and `SDKStudioContext` are available, the explicit `config` takes precedence.
|
|
543
|
+
*
|
|
527
544
|
* @category Components
|
|
528
545
|
* @param props - Your Sanity configuration and the React children to render
|
|
529
546
|
* @returns Your Sanity application, integrated with your Sanity configuration and application context
|
|
@@ -571,7 +588,7 @@ export declare interface ResourceProviderProps extends SanityConfig {
|
|
|
571
588
|
export declare function SanityApp({
|
|
572
589
|
children,
|
|
573
590
|
fallback,
|
|
574
|
-
config,
|
|
591
|
+
config: configProp,
|
|
575
592
|
...props
|
|
576
593
|
}: SanityAppProps): ReactElement
|
|
577
594
|
|
|
@@ -580,9 +597,16 @@ export declare function SanityApp({
|
|
|
580
597
|
* @category Types
|
|
581
598
|
*/
|
|
582
599
|
export declare interface SanityAppProps {
|
|
583
|
-
|
|
600
|
+
/**
|
|
601
|
+
* One or more SanityConfig objects providing a project ID and dataset name.
|
|
602
|
+
* Optional when `SanityApp` is rendered inside an `SDKStudioContext` provider
|
|
603
|
+
* (e.g. inside Sanity Studio) — the config is derived from the workspace
|
|
604
|
+
* automatically.
|
|
605
|
+
*/
|
|
606
|
+
config?: SanityConfig | SanityConfig[]
|
|
584
607
|
/** @deprecated use the `config` prop instead. */
|
|
585
608
|
sanityConfigs?: SanityConfig[]
|
|
609
|
+
sources?: Record<string, DocumentSource>
|
|
586
610
|
children: React.ReactNode
|
|
587
611
|
fallback: React.ReactNode
|
|
588
612
|
}
|
|
@@ -612,10 +636,73 @@ export declare interface SDKProviderProps extends AuthBoundaryProps {
|
|
|
612
636
|
children: ReactNode
|
|
613
637
|
config: SanityConfig | SanityConfig[]
|
|
614
638
|
fallback: ReactNode
|
|
639
|
+
sources?: Record<string, DocumentSource>
|
|
615
640
|
}
|
|
616
641
|
|
|
642
|
+
/**
|
|
643
|
+
* React context that allows the SDK to auto-detect when it is running
|
|
644
|
+
* inside a Sanity Studio. The Studio provides a workspace handle via this
|
|
645
|
+
* context, and `SanityApp` reads it to derive `projectId`, `dataset`, and
|
|
646
|
+
* a reactive auth token — eliminating the need for manual configuration.
|
|
647
|
+
*
|
|
648
|
+
* @remarks
|
|
649
|
+
* This context is defined in `@sanity/sdk-react` and provided by the Studio.
|
|
650
|
+
* The Studio imports it from this package and wraps its component tree:
|
|
651
|
+
*
|
|
652
|
+
* ```tsx
|
|
653
|
+
* import {SDKStudioContext} from '@sanity/sdk-react'
|
|
654
|
+
*
|
|
655
|
+
* function StudioRoot({children}) {
|
|
656
|
+
* const workspace = useWorkspace()
|
|
657
|
+
* return (
|
|
658
|
+
* <SDKStudioContext.Provider value={workspace}>
|
|
659
|
+
* {children}
|
|
660
|
+
* </SDKStudioContext.Provider>
|
|
661
|
+
* )
|
|
662
|
+
* }
|
|
663
|
+
* ```
|
|
664
|
+
*
|
|
665
|
+
* When `SanityApp` is rendered inside this provider, it auto-configures
|
|
666
|
+
* without any `config` prop:
|
|
667
|
+
*
|
|
668
|
+
* ```tsx
|
|
669
|
+
* <SanityApp fallback={<Loading />}>
|
|
670
|
+
* <MyComponent />
|
|
671
|
+
* </SanityApp>
|
|
672
|
+
* ```
|
|
673
|
+
*
|
|
674
|
+
* @public
|
|
675
|
+
*/
|
|
676
|
+
export declare const SDKStudioContext: Context<StudioWorkspaceHandle | null>
|
|
677
|
+
|
|
617
678
|
export {SortOrderingItem}
|
|
618
679
|
|
|
680
|
+
/**
|
|
681
|
+
* Minimal duck-typed interface representing a Sanity Studio workspace.
|
|
682
|
+
* The Studio's `Workspace` type satisfies this naturally — no import
|
|
683
|
+
* dependency on the `sanity` package is required.
|
|
684
|
+
*
|
|
685
|
+
* @public
|
|
686
|
+
*/
|
|
687
|
+
export declare interface StudioWorkspaceHandle {
|
|
688
|
+
/** The Sanity project ID for this workspace. */
|
|
689
|
+
projectId: string
|
|
690
|
+
/** The dataset name for this workspace. */
|
|
691
|
+
dataset: string
|
|
692
|
+
/** Authentication state for this workspace. */
|
|
693
|
+
auth: {
|
|
694
|
+
/**
|
|
695
|
+
* Reactive token source from the Studio's auth store.
|
|
696
|
+
* When present, the SDK subscribes for ongoing token sync — the Studio
|
|
697
|
+
* is the single authority for auth and handles token refresh.
|
|
698
|
+
*
|
|
699
|
+
* Optional because Studios before Aug 2022 may not expose it. When
|
|
700
|
+
* absent, the SDK falls back to localStorage/cookie discovery.
|
|
701
|
+
*/
|
|
702
|
+
token?: TokenSource
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
619
706
|
declare interface StudioWorkspacesResult {
|
|
620
707
|
workspacesByProjectIdAndDataset: WorkspacesByProjectIdDataset
|
|
621
708
|
error: string | null
|
|
@@ -663,11 +750,69 @@ export declare const useActiveReleases: UseActiveReleases
|
|
|
663
750
|
/**
|
|
664
751
|
* @alpha
|
|
665
752
|
* Generates content for a document (or specific fields) via Sanity Agent Actions.
|
|
753
|
+
*
|
|
754
|
+
* @remarks
|
|
755
|
+
* This hook provides a stable callback to trigger AI-powered content generation for documents.
|
|
756
|
+
*
|
|
757
|
+
* Features:
|
|
666
758
|
* - Uses instruction templates with `$variables` and supports `instructionParams` (constants, fields, documents, GROQ queries).
|
|
667
759
|
* - Can target specific paths/fields; supports image generation when targeting image fields.
|
|
668
760
|
* - Supports optional `temperature`, `async`, `noWrite`, and `conditionalPaths`.
|
|
761
|
+
* - Returns a Subscribable stream for tracking generation progress.
|
|
762
|
+
*
|
|
763
|
+
* @returns A stable callback that triggers the action and yields a Subscribable stream.
|
|
669
764
|
*
|
|
670
|
-
*
|
|
765
|
+
* @example Basic content generation
|
|
766
|
+
* ```tsx
|
|
767
|
+
* import {useAgentGenerate} from '@sanity/sdk-react'
|
|
768
|
+
*
|
|
769
|
+
* function GenerateDescription({documentId}: {documentId: string}) {
|
|
770
|
+
* const generate = useAgentGenerate()
|
|
771
|
+
*
|
|
772
|
+
* const handleGenerate = () => {
|
|
773
|
+
* generate({
|
|
774
|
+
* documentId,
|
|
775
|
+
* instruction: 'Write a compelling product description based on the title: $title',
|
|
776
|
+
* instructionParams: {
|
|
777
|
+
* title: {type: 'field', path: 'title'},
|
|
778
|
+
* },
|
|
779
|
+
* targetPaths: ['description'],
|
|
780
|
+
* }).subscribe({
|
|
781
|
+
* next: (result) => console.log('Generation progress:', result),
|
|
782
|
+
* complete: () => console.log('Generation complete'),
|
|
783
|
+
* error: (err) => console.error('Generation failed:', err),
|
|
784
|
+
* })
|
|
785
|
+
* }
|
|
786
|
+
*
|
|
787
|
+
* return <button onClick={handleGenerate}>Generate Description</button>
|
|
788
|
+
* }
|
|
789
|
+
* ```
|
|
790
|
+
*
|
|
791
|
+
* @example Image generation
|
|
792
|
+
* ```tsx
|
|
793
|
+
* import {useAgentGenerate} from '@sanity/sdk-react'
|
|
794
|
+
*
|
|
795
|
+
* function GenerateProductImage({documentId}: {documentId: string}) {
|
|
796
|
+
* const generate = useAgentGenerate()
|
|
797
|
+
*
|
|
798
|
+
* const handleGenerateImage = () => {
|
|
799
|
+
* generate({
|
|
800
|
+
* documentId,
|
|
801
|
+
* instruction: 'Generate a product photo for: $productName',
|
|
802
|
+
* instructionParams: {
|
|
803
|
+
* productName: {type: 'field', path: 'name'},
|
|
804
|
+
* },
|
|
805
|
+
* targetPaths: ['mainImage'],
|
|
806
|
+
* }).subscribe({
|
|
807
|
+
* complete: () => console.log('Image generated'),
|
|
808
|
+
* })
|
|
809
|
+
* }
|
|
810
|
+
*
|
|
811
|
+
* return <button onClick={handleGenerateImage}>Generate Image</button>
|
|
812
|
+
* }
|
|
813
|
+
* ```
|
|
814
|
+
*
|
|
815
|
+
* @category Agent Actions
|
|
671
816
|
*/
|
|
672
817
|
export declare const useAgentGenerate: () => (
|
|
673
818
|
options: AgentGenerateOptions,
|
|
@@ -676,22 +821,247 @@ export declare const useAgentGenerate: () => (
|
|
|
676
821
|
/**
|
|
677
822
|
* @alpha
|
|
678
823
|
* Schema-aware patching with Sanity Agent Actions.
|
|
824
|
+
*
|
|
825
|
+
* @remarks
|
|
826
|
+
* This hook provides a stable callback to apply schema-validated patches to documents.
|
|
827
|
+
* Unlike {@link useEditDocument}, this uses the Agent Actions API which provides
|
|
828
|
+
* additional schema validation and safe merging capabilities.
|
|
829
|
+
*
|
|
830
|
+
* Features:
|
|
679
831
|
* - Validates provided paths/values against the document schema and merges object values safely.
|
|
680
832
|
* - Prevents duplicate keys and supports array appends (including after a specific keyed item).
|
|
681
833
|
* - Accepts `documentId` or `targetDocument` (mutually exclusive).
|
|
834
|
+
* - Requires `schemaId` (e.g., `'_.schemas.default'`) and `target` to specify patch operations.
|
|
682
835
|
* - Optional `async`, `noWrite`, `conditionalPaths`.
|
|
683
836
|
*
|
|
684
|
-
*
|
|
837
|
+
* Each entry in `target` specifies a `path`, an `operation` (`'set'`, `'append'`, `'mixed'`, or `'unset'`),
|
|
838
|
+
* and a `value` (required for all operations except `'unset'`).
|
|
839
|
+
*
|
|
840
|
+
* @returns A stable callback that triggers the action and resolves a Promise with the patch result.
|
|
841
|
+
*
|
|
842
|
+
* @example Basic field update
|
|
843
|
+
* ```tsx
|
|
844
|
+
* import {useAgentPatch} from '@sanity/sdk-react'
|
|
845
|
+
*
|
|
846
|
+
* function UpdateTitle({documentId}: {documentId: string}) {
|
|
847
|
+
* const patch = useAgentPatch()
|
|
848
|
+
*
|
|
849
|
+
* const handleUpdate = async () => {
|
|
850
|
+
* const result = await patch({
|
|
851
|
+
* documentId,
|
|
852
|
+
* schemaId: '_.schemas.default',
|
|
853
|
+
* target: [
|
|
854
|
+
* {
|
|
855
|
+
* path: 'title',
|
|
856
|
+
* operation: 'set',
|
|
857
|
+
* value: 'Updated Title',
|
|
858
|
+
* },
|
|
859
|
+
* {
|
|
860
|
+
* path: 'lastModified',
|
|
861
|
+
* operation: 'set',
|
|
862
|
+
* value: new Date().toISOString(),
|
|
863
|
+
* },
|
|
864
|
+
* ],
|
|
865
|
+
* })
|
|
866
|
+
* console.log('Patch result:', result)
|
|
867
|
+
* }
|
|
868
|
+
*
|
|
869
|
+
* return <button onClick={handleUpdate}>Update Title</button>
|
|
870
|
+
* }
|
|
871
|
+
* ```
|
|
872
|
+
*
|
|
873
|
+
* @example Append items to an array
|
|
874
|
+
* ```tsx
|
|
875
|
+
* import {useAgentPatch} from '@sanity/sdk-react'
|
|
876
|
+
*
|
|
877
|
+
* function AddTag({documentId}: {documentId: string}) {
|
|
878
|
+
* const patch = useAgentPatch()
|
|
879
|
+
*
|
|
880
|
+
* const handleAddTag = async (newTag: string) => {
|
|
881
|
+
* await patch({
|
|
882
|
+
* documentId,
|
|
883
|
+
* schemaId: '_.schemas.default',
|
|
884
|
+
* target: {
|
|
885
|
+
* path: 'tags',
|
|
886
|
+
* operation: 'append',
|
|
887
|
+
* value: [newTag],
|
|
888
|
+
* },
|
|
889
|
+
* })
|
|
890
|
+
* }
|
|
891
|
+
*
|
|
892
|
+
* return (
|
|
893
|
+
* <button onClick={() => handleAddTag('featured')}>
|
|
894
|
+
* Add Featured Tag
|
|
895
|
+
* </button>
|
|
896
|
+
* )
|
|
897
|
+
* }
|
|
898
|
+
* ```
|
|
899
|
+
*
|
|
900
|
+
* @example Insert array item after a specific key
|
|
901
|
+
* ```tsx
|
|
902
|
+
* import {useAgentPatch} from '@sanity/sdk-react'
|
|
903
|
+
*
|
|
904
|
+
* function InsertContentBlock({
|
|
905
|
+
* documentId,
|
|
906
|
+
* afterKey,
|
|
907
|
+
* }: {
|
|
908
|
+
* documentId: string
|
|
909
|
+
* afterKey: string
|
|
910
|
+
* }) {
|
|
911
|
+
* const patch = useAgentPatch()
|
|
912
|
+
*
|
|
913
|
+
* const handleInsert = async () => {
|
|
914
|
+
* await patch({
|
|
915
|
+
* documentId,
|
|
916
|
+
* schemaId: '_.schemas.default',
|
|
917
|
+
* target: {
|
|
918
|
+
* path: ['content', {_key: afterKey}],
|
|
919
|
+
* operation: 'append',
|
|
920
|
+
* value: [{_type: 'block', text: 'New paragraph inserted here.'}],
|
|
921
|
+
* },
|
|
922
|
+
* })
|
|
923
|
+
* }
|
|
924
|
+
*
|
|
925
|
+
* return <button onClick={handleInsert}>Insert Block</button>
|
|
926
|
+
* }
|
|
927
|
+
* ```
|
|
928
|
+
*
|
|
929
|
+
* @example Create a new document with targetDocument
|
|
930
|
+
* ```tsx
|
|
931
|
+
* import {useAgentPatch} from '@sanity/sdk-react'
|
|
932
|
+
*
|
|
933
|
+
* function CreateProduct() {
|
|
934
|
+
* const patch = useAgentPatch()
|
|
935
|
+
*
|
|
936
|
+
* const handleCreate = async () => {
|
|
937
|
+
* const result = await patch({
|
|
938
|
+
* targetDocument: {
|
|
939
|
+
* operation: 'create',
|
|
940
|
+
* _type: 'product',
|
|
941
|
+
* },
|
|
942
|
+
* schemaId: '_.schemas.default',
|
|
943
|
+
* target: [
|
|
944
|
+
* {
|
|
945
|
+
* path: 'title',
|
|
946
|
+
* operation: 'set',
|
|
947
|
+
* value: 'New Product',
|
|
948
|
+
* },
|
|
949
|
+
* {
|
|
950
|
+
* path: 'price',
|
|
951
|
+
* operation: 'set',
|
|
952
|
+
* value: 29.99,
|
|
953
|
+
* },
|
|
954
|
+
* {
|
|
955
|
+
* path: 'inStock',
|
|
956
|
+
* operation: 'set',
|
|
957
|
+
* value: true,
|
|
958
|
+
* },
|
|
959
|
+
* ],
|
|
960
|
+
* })
|
|
961
|
+
* console.log('Created document:', result.documentId)
|
|
962
|
+
* }
|
|
963
|
+
*
|
|
964
|
+
* return <button onClick={handleCreate}>Create Product</button>
|
|
965
|
+
* }
|
|
966
|
+
* ```
|
|
967
|
+
*
|
|
968
|
+
* @category Agent Actions
|
|
685
969
|
*/
|
|
686
970
|
export declare const useAgentPatch: () => (options: AgentPatchOptions) => Promise<AgentPatchResult>
|
|
687
971
|
|
|
688
972
|
/**
|
|
689
973
|
* @alpha
|
|
690
|
-
* Prompts the
|
|
974
|
+
* Prompts the Content Agent using the same instruction template format as other agent actions.
|
|
975
|
+
*
|
|
976
|
+
* @remarks
|
|
977
|
+
* This hook provides a stable callback to send prompts to the Content Agent and receive responses.
|
|
978
|
+
* Unlike the other agent action hooks, this one does not modify documents—it simply
|
|
979
|
+
* returns the AI's response.
|
|
980
|
+
*
|
|
981
|
+
* Features:
|
|
982
|
+
* - Uses the same instruction template format with `$variables` as other actions.
|
|
691
983
|
* - `format`: 'string' or 'json' (instruction must contain the word "json" for JSON responses).
|
|
692
|
-
* -
|
|
984
|
+
* - Supports `instructionParams` for dynamic content (constants, fields, documents, GROQ queries).
|
|
985
|
+
* - Optional `temperature` for controlling response creativity.
|
|
986
|
+
*
|
|
987
|
+
* @returns A stable callback that triggers the action and resolves a Promise with the prompt result.
|
|
693
988
|
*
|
|
694
|
-
*
|
|
989
|
+
* @example Basic string prompt
|
|
990
|
+
* ```tsx
|
|
991
|
+
* import {useState} from 'react'
|
|
992
|
+
* import {useAgentPrompt} from '@sanity/sdk-react'
|
|
993
|
+
*
|
|
994
|
+
* function AskQuestion() {
|
|
995
|
+
* const prompt = useAgentPrompt()
|
|
996
|
+
* const [answer, setAnswer] = useState<string>('')
|
|
997
|
+
*
|
|
998
|
+
* const handleAsk = async () => {
|
|
999
|
+
* const result = await prompt({
|
|
1000
|
+
* instruction: 'What are the top 3 benefits of content modeling?',
|
|
1001
|
+
* format: 'string',
|
|
1002
|
+
* })
|
|
1003
|
+
* setAnswer(result.output)
|
|
1004
|
+
* }
|
|
1005
|
+
*
|
|
1006
|
+
* return (
|
|
1007
|
+
* <div>
|
|
1008
|
+
* <button onClick={handleAsk}>Ask AI</button>
|
|
1009
|
+
* {answer && <p>{answer}</p>}
|
|
1010
|
+
* </div>
|
|
1011
|
+
* )
|
|
1012
|
+
* }
|
|
1013
|
+
* ```
|
|
1014
|
+
*
|
|
1015
|
+
* @example JSON response with instruction params
|
|
1016
|
+
* ```tsx
|
|
1017
|
+
* import {useState} from 'react'
|
|
1018
|
+
* import {useAgentPrompt} from '@sanity/sdk-react'
|
|
1019
|
+
*
|
|
1020
|
+
* interface TagSuggestions {
|
|
1021
|
+
* tags: string[]
|
|
1022
|
+
* reasoning: string
|
|
1023
|
+
* }
|
|
1024
|
+
*
|
|
1025
|
+
* function SuggestTags({documentId}: {documentId: string}) {
|
|
1026
|
+
* const prompt = useAgentPrompt()
|
|
1027
|
+
* const [suggestions, setSuggestions] = useState<TagSuggestions | null>(null)
|
|
1028
|
+
*
|
|
1029
|
+
* const handleSuggest = async () => {
|
|
1030
|
+
* const result = await prompt({
|
|
1031
|
+
* instruction: `
|
|
1032
|
+
* Based on the following article title and content, suggest relevant tags.
|
|
1033
|
+
* Return as json with "tags" (array of strings) and "reasoning" (string).
|
|
1034
|
+
* Title: $title
|
|
1035
|
+
* Content: $body
|
|
1036
|
+
* `,
|
|
1037
|
+
* instructionParams: {
|
|
1038
|
+
* title: {type: 'field', path: 'title', documentId},
|
|
1039
|
+
* body: {type: 'field', path: 'body', documentId},
|
|
1040
|
+
* },
|
|
1041
|
+
* format: 'json',
|
|
1042
|
+
* })
|
|
1043
|
+
* setSuggestions(result.output as TagSuggestions)
|
|
1044
|
+
* }
|
|
1045
|
+
*
|
|
1046
|
+
* return (
|
|
1047
|
+
* <div>
|
|
1048
|
+
* <button onClick={handleSuggest}>Suggest Tags</button>
|
|
1049
|
+
* {suggestions && (
|
|
1050
|
+
* <div>
|
|
1051
|
+
* <p>Reasoning: {suggestions.reasoning}</p>
|
|
1052
|
+
* <ul>
|
|
1053
|
+
* {suggestions.tags.map((tag) => (
|
|
1054
|
+
* <li key={tag}>{tag}</li>
|
|
1055
|
+
* ))}
|
|
1056
|
+
* </ul>
|
|
1057
|
+
* </div>
|
|
1058
|
+
* )}
|
|
1059
|
+
* </div>
|
|
1060
|
+
* )
|
|
1061
|
+
* }
|
|
1062
|
+
* ```
|
|
1063
|
+
*
|
|
1064
|
+
* @category Agent Actions
|
|
695
1065
|
*/
|
|
696
1066
|
export declare const useAgentPrompt: () => (
|
|
697
1067
|
options: AgentPromptOptions,
|
|
@@ -732,12 +1102,73 @@ export declare function useAgentResourceContext(options: AgentResourceContextOpt
|
|
|
732
1102
|
/**
|
|
733
1103
|
* @alpha
|
|
734
1104
|
* Transforms an existing document or selected fields using Sanity Agent Actions.
|
|
1105
|
+
*
|
|
1106
|
+
* @remarks
|
|
1107
|
+
* This hook provides a stable callback to apply AI-powered transformations to document content.
|
|
1108
|
+
*
|
|
1109
|
+
* Features:
|
|
735
1110
|
* - Accepts `instruction` and `instructionParams` (constants, fields, documents, GROQ queries).
|
|
736
1111
|
* - Can write to the same or a different `targetDocument` (create/edit), and target specific paths.
|
|
737
1112
|
* - Supports per-path image transform instructions and image description operations.
|
|
738
1113
|
* - Optional `temperature`, `async`, `noWrite`, `conditionalPaths`.
|
|
739
1114
|
*
|
|
740
|
-
*
|
|
1115
|
+
* @returns A stable callback that triggers the action and yields a Subscribable stream.
|
|
1116
|
+
*
|
|
1117
|
+
* @example Transform text content
|
|
1118
|
+
* ```tsx
|
|
1119
|
+
* import {useAgentTransform} from '@sanity/sdk-react'
|
|
1120
|
+
*
|
|
1121
|
+
* function SummarizeArticle({documentId}: {documentId: string}) {
|
|
1122
|
+
* const transform = useAgentTransform()
|
|
1123
|
+
*
|
|
1124
|
+
* const handleSummarize = () => {
|
|
1125
|
+
* transform({
|
|
1126
|
+
* documentId,
|
|
1127
|
+
* instruction: 'Summarize the following content into 2-3 sentences: $body',
|
|
1128
|
+
* instructionParams: {
|
|
1129
|
+
* body: {type: 'field', path: 'body'},
|
|
1130
|
+
* },
|
|
1131
|
+
* targetPaths: ['summary'],
|
|
1132
|
+
* }).subscribe({
|
|
1133
|
+
* complete: () => console.log('Summary generated'),
|
|
1134
|
+
* error: (err) => console.error('Transform failed:', err),
|
|
1135
|
+
* })
|
|
1136
|
+
* }
|
|
1137
|
+
*
|
|
1138
|
+
* return <button onClick={handleSummarize}>Generate Summary</button>
|
|
1139
|
+
* }
|
|
1140
|
+
* ```
|
|
1141
|
+
*
|
|
1142
|
+
* @example Transform and write to a different document
|
|
1143
|
+
* ```tsx
|
|
1144
|
+
* import {useAgentTransform} from '@sanity/sdk-react'
|
|
1145
|
+
*
|
|
1146
|
+
* function CreateVariant({sourceDocumentId}: {sourceDocumentId: string}) {
|
|
1147
|
+
* const transform = useAgentTransform()
|
|
1148
|
+
*
|
|
1149
|
+
* const handleCreateVariant = () => {
|
|
1150
|
+
* transform({
|
|
1151
|
+
* documentId: sourceDocumentId,
|
|
1152
|
+
* instruction: 'Rewrite this product description for a younger audience: $description',
|
|
1153
|
+
* instructionParams: {
|
|
1154
|
+
* description: {type: 'field', path: 'description'},
|
|
1155
|
+
* },
|
|
1156
|
+
* targetDocument: {
|
|
1157
|
+
* operation: 'create',
|
|
1158
|
+
* _type: 'product',
|
|
1159
|
+
* },
|
|
1160
|
+
* targetPaths: ['description'],
|
|
1161
|
+
* }).subscribe({
|
|
1162
|
+
* next: (result) => console.log('New document:', result),
|
|
1163
|
+
* complete: () => console.log('Variant created'),
|
|
1164
|
+
* })
|
|
1165
|
+
* }
|
|
1166
|
+
*
|
|
1167
|
+
* return <button onClick={handleCreateVariant}>Create Youth Variant</button>
|
|
1168
|
+
* }
|
|
1169
|
+
* ```
|
|
1170
|
+
*
|
|
1171
|
+
* @category Agent Actions
|
|
741
1172
|
*/
|
|
742
1173
|
export declare const useAgentTransform: () => (
|
|
743
1174
|
options: AgentTransformOptions,
|
|
@@ -746,11 +1177,92 @@ export declare const useAgentTransform: () => (
|
|
|
746
1177
|
/**
|
|
747
1178
|
* @alpha
|
|
748
1179
|
* Translates documents or fields using Sanity Agent Actions.
|
|
1180
|
+
*
|
|
1181
|
+
* @remarks
|
|
1182
|
+
* This hook provides a stable callback to translate document content between languages using AI.
|
|
1183
|
+
*
|
|
1184
|
+
* Features:
|
|
749
1185
|
* - Configure `fromLanguage`/`toLanguage`, optional `styleGuide`, and `protectedPhrases`.
|
|
750
1186
|
* - Can write into a different `targetDocument`, and/or store language in a field.
|
|
751
1187
|
* - Optional `temperature`, `async`, `noWrite`, `conditionalPaths`.
|
|
752
1188
|
*
|
|
753
|
-
*
|
|
1189
|
+
* @returns A stable callback that triggers the action and yields a Subscribable stream.
|
|
1190
|
+
*
|
|
1191
|
+
* @example Basic translation
|
|
1192
|
+
* ```tsx
|
|
1193
|
+
* import {useAgentTranslate} from '@sanity/sdk-react'
|
|
1194
|
+
*
|
|
1195
|
+
* function TranslateArticle({documentId}: {documentId: string}) {
|
|
1196
|
+
* const translate = useAgentTranslate()
|
|
1197
|
+
*
|
|
1198
|
+
* const handleTranslate = () => {
|
|
1199
|
+
* translate({
|
|
1200
|
+
* documentId,
|
|
1201
|
+
* fromLanguage: 'en',
|
|
1202
|
+
* toLanguage: 'es',
|
|
1203
|
+
* targetPaths: ['title', 'body'],
|
|
1204
|
+
* }).subscribe({
|
|
1205
|
+
* complete: () => console.log('Translation complete'),
|
|
1206
|
+
* error: (err) => console.error('Translation failed:', err),
|
|
1207
|
+
* })
|
|
1208
|
+
* }
|
|
1209
|
+
*
|
|
1210
|
+
* return <button onClick={handleTranslate}>Translate to Spanish</button>
|
|
1211
|
+
* }
|
|
1212
|
+
* ```
|
|
1213
|
+
*
|
|
1214
|
+
* @example Translation with style guide and protected phrases
|
|
1215
|
+
* ```tsx
|
|
1216
|
+
* import {useAgentTranslate} from '@sanity/sdk-react'
|
|
1217
|
+
*
|
|
1218
|
+
* function TranslateWithBrandTerms({documentId}: {documentId: string}) {
|
|
1219
|
+
* const translate = useAgentTranslate()
|
|
1220
|
+
*
|
|
1221
|
+
* const handleTranslate = () => {
|
|
1222
|
+
* translate({
|
|
1223
|
+
* documentId,
|
|
1224
|
+
* fromLanguage: 'en',
|
|
1225
|
+
* toLanguage: 'fr',
|
|
1226
|
+
* styleGuide: 'Use formal French appropriate for business communication.',
|
|
1227
|
+
* protectedPhrases: ['Acme Corp', 'PowerWidget Pro'],
|
|
1228
|
+
* targetPaths: ['title', 'description'],
|
|
1229
|
+
* }).subscribe({
|
|
1230
|
+
* complete: () => console.log('Translation complete'),
|
|
1231
|
+
* })
|
|
1232
|
+
* }
|
|
1233
|
+
*
|
|
1234
|
+
* return <button onClick={handleTranslate}>Translate to French</button>
|
|
1235
|
+
* }
|
|
1236
|
+
* ```
|
|
1237
|
+
*
|
|
1238
|
+
* @example Translate to a new document
|
|
1239
|
+
* ```tsx
|
|
1240
|
+
* import {useAgentTranslate} from '@sanity/sdk-react'
|
|
1241
|
+
*
|
|
1242
|
+
* function CreateTranslatedCopy({documentId}: {documentId: string}) {
|
|
1243
|
+
* const translate = useAgentTranslate()
|
|
1244
|
+
*
|
|
1245
|
+
* const handleCreateTranslation = () => {
|
|
1246
|
+
* translate({
|
|
1247
|
+
* documentId,
|
|
1248
|
+
* fromLanguage: 'en',
|
|
1249
|
+
* toLanguage: 'de',
|
|
1250
|
+
* targetDocument: {
|
|
1251
|
+
* operation: 'create',
|
|
1252
|
+
* _type: 'article',
|
|
1253
|
+
* },
|
|
1254
|
+
* languageFieldPath: 'language',
|
|
1255
|
+
* }).subscribe({
|
|
1256
|
+
* next: (result) => console.log('New translated document:', result),
|
|
1257
|
+
* complete: () => console.log('Translated copy created'),
|
|
1258
|
+
* })
|
|
1259
|
+
* }
|
|
1260
|
+
*
|
|
1261
|
+
* return <button onClick={handleCreateTranslation}>Create German Copy</button>
|
|
1262
|
+
* }
|
|
1263
|
+
* ```
|
|
1264
|
+
*
|
|
1265
|
+
* @category Agent Actions
|
|
754
1266
|
*/
|
|
755
1267
|
export declare const useAgentTranslate: () => (
|
|
756
1268
|
options: AgentTranslateOptions,
|
|
@@ -1146,7 +1658,7 @@ export declare function useDispatchIntent(params: UseDispatchIntentParams): Disp
|
|
|
1146
1658
|
declare interface UseDispatchIntentParams {
|
|
1147
1659
|
action?: 'edit'
|
|
1148
1660
|
intentId?: string
|
|
1149
|
-
documentHandle:
|
|
1661
|
+
documentHandle: WithSourceNameSupport<DocumentHandle>
|
|
1150
1662
|
parameters?: Record<string, unknown>
|
|
1151
1663
|
}
|
|
1152
1664
|
|
|
@@ -1729,7 +2241,7 @@ export declare interface useDocumentProjectionOptions<
|
|
|
1729
2241
|
TDocumentType extends string = string,
|
|
1730
2242
|
TDataset extends string = string,
|
|
1731
2243
|
TProjectId extends string = string,
|
|
1732
|
-
> extends DocumentHandle<TDocumentType, TDataset, TProjectId
|
|
2244
|
+
> extends WithSourceNameSupport<DocumentHandle<TDocumentType, TDataset, TProjectId>> {
|
|
1733
2245
|
/** The GROQ projection string */
|
|
1734
2246
|
projection: TProjection
|
|
1735
2247
|
/** Optional parameters for the projection query */
|
|
@@ -2459,7 +2971,7 @@ export declare function useQuery<
|
|
|
2459
2971
|
TDataset extends string = string,
|
|
2460
2972
|
TProjectId extends string = string,
|
|
2461
2973
|
>(
|
|
2462
|
-
options:
|
|
2974
|
+
options: UseQueryOptions<TQuery, TDataset, TProjectId>,
|
|
2463
2975
|
): {
|
|
2464
2976
|
/** The query result, typed based on the GROQ query string */
|
|
2465
2977
|
data: SanityQueryResult<TQuery, `${TProjectId}.${TDataset}`>
|
|
@@ -2495,13 +3007,23 @@ export declare function useQuery<
|
|
|
2495
3007
|
* }
|
|
2496
3008
|
* ```
|
|
2497
3009
|
*/
|
|
2498
|
-
export declare function useQuery<TData>(options: QueryOptions): {
|
|
3010
|
+
export declare function useQuery<TData>(options: WithSourceNameSupport<QueryOptions>): {
|
|
2499
3011
|
/** The query result, cast to the provided type TData */
|
|
2500
3012
|
data: TData
|
|
2501
3013
|
/** True if another query is resolving in the background (suspense handles the initial loading state) */
|
|
2502
3014
|
isPending: boolean
|
|
2503
3015
|
}
|
|
2504
3016
|
|
|
3017
|
+
/**
|
|
3018
|
+
* Hook options for useQuery, supporting both direct source and sourceName.
|
|
3019
|
+
* @beta
|
|
3020
|
+
*/
|
|
3021
|
+
declare type UseQueryOptions<
|
|
3022
|
+
TQuery extends string = string,
|
|
3023
|
+
TDataset extends string = string,
|
|
3024
|
+
TProjectId extends string = string,
|
|
3025
|
+
> = WithSourceNameSupport<QueryOptions<TQuery, TDataset, TProjectId>>
|
|
3026
|
+
|
|
2505
3027
|
/**
|
|
2506
3028
|
* @internal
|
|
2507
3029
|
* Hook for managing document interaction history in Sanity Studio.
|
|
@@ -2845,6 +3367,29 @@ export declare type WindowMessageHandler<TFrameMessage extends FrameMessage> = (
|
|
|
2845
3367
|
event: TFrameMessage['data'],
|
|
2846
3368
|
) => TFrameMessage['response']
|
|
2847
3369
|
|
|
3370
|
+
/**
|
|
3371
|
+
* Adds React hook support (sourceName resolution) to core types.
|
|
3372
|
+
* This wrapper allows hooks to accept `sourceName` as a convenience,
|
|
3373
|
+
* which is then resolved to a `DocumentSource` at the React layer.
|
|
3374
|
+
* For now, we are trying to avoid source name resolution in core --
|
|
3375
|
+
* functions having sources explicitly passed will reduce complexity.
|
|
3376
|
+
*
|
|
3377
|
+
* @typeParam T - The core type to extend (must have optional `source` field)
|
|
3378
|
+
* @beta
|
|
3379
|
+
*/
|
|
3380
|
+
declare type WithSourceNameSupport<
|
|
3381
|
+
T extends {
|
|
3382
|
+
source?: DocumentSource
|
|
3383
|
+
},
|
|
3384
|
+
> = T & {
|
|
3385
|
+
/**
|
|
3386
|
+
* Optional name of a source to resolve from context.
|
|
3387
|
+
* If provided, will be resolved to a `DocumentSource` via `SourcesContext`.
|
|
3388
|
+
* @beta
|
|
3389
|
+
*/
|
|
3390
|
+
sourceName?: string
|
|
3391
|
+
}
|
|
3392
|
+
|
|
2848
3393
|
declare interface WorkspacesByProjectIdDataset {
|
|
2849
3394
|
[key: `${string}:${string}`]: DashboardResource[]
|
|
2850
3395
|
}
|