@sanity/sdk-react 2.3.1 → 2.5.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/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { c } from "react-compiler-runtime";
3
3
  import { ClientError, CorsOriginError } from "@sanity/client";
4
- import { getAuthState, getNodeState, getIsInDashboardState, setAuthToken, AuthStateType, getLoginUrlState, observeOrganizationVerificationState, handleAuthCallback, logout, getCorsErrorProjectId, createSanityInstance, getTokenState, getCurrentUserState, getDashboardOrganizationId, getClientState, getOrCreateController, getOrCreateChannel, releaseChannel, getFavoritesState, resolveFavoritesState, resolveDatasets, getDatasetsState, applyDocumentActions, resolveDocument, getDocumentState, subscribeDocumentEvents, getPermissionsState, getDocumentSyncStatus, editDocument, getQueryKey, parseQueryKey, getQueryState, resolveQuery, createGroqSearchFilter, getPresence, getPreviewState, resolvePreview, getProjectionState, resolveProjection, resolveProject, getProjectState, resolveProjects, getProjectsState, getActiveReleasesState, getPerspectiveState, getUsersKey, parseUsersKey, getUsersState, resolveUsers, loadMoreUsers } from "@sanity/sdk";
4
+ import { getAuthState, getNodeState, getIsInDashboardState, setAuthToken, AuthStateType, getLoginUrlState, observeOrganizationVerificationState, handleAuthCallback, logout, isProjectUserNotFoundClientError, getClientErrorApiDescription, getClientErrorApiBody, getCorsErrorProjectId, createSanityInstance, agentGenerate, agentTransform, agentTranslate, agentPrompt, agentPatch, getTokenState, getCurrentUserState, getDashboardOrganizationId, getClientState, getOrCreateController, getOrCreateChannel, releaseChannel, getFavoritesState, resolveFavoritesState, resolveDatasets, getDatasetsState, applyDocumentActions, resolveDocument, getDocumentState, subscribeDocumentEvents, getPermissionsState, getDocumentSyncStatus, editDocument, getQueryKey, parseQueryKey, getQueryState, resolveQuery, createGroqSearchFilter, getPresence, getPreviewState, resolvePreview, getProjectionState, resolveProjection, resolveProject, getProjectState, resolveProjects, getProjectsState, getActiveReleasesState, getPerspectiveState, getUsersKey, parseUsersKey, getUsersState, resolveUsers, loadMoreUsers } from "@sanity/sdk";
5
5
  export * from "@sanity/sdk";
6
- import { createContext, useContext, useSyncExternalStore, useRef, useEffect, useState, Suspense, useMemo, useCallback, useInsertionEffect, useTransition } from "react";
6
+ import { createContext, useContext, useSyncExternalStore, useRef, useEffect, useState, Suspense, useCallback, useMemo, useInsertionEffect, useTransition } from "react";
7
7
  import { ErrorBoundary } from "react-error-boundary";
8
8
  import { SDK_CHANNEL_NAME, SDK_NODE_NAME } from "@sanity/message-protocol";
9
9
  import { firstValueFrom, filter, identity, Observable, startWith, distinctUntilChanged, switchMap, EMPTY } from "rxjs";
@@ -297,13 +297,13 @@ function _temp$5(replacementLocation) {
297
297
  }
298
298
  const useLogOut = createCallbackHook(logout);
299
299
  function LoginError(t0) {
300
- const $ = c(17), {
300
+ const $ = c(18), {
301
301
  error,
302
302
  resetErrorBoundary
303
303
  } = t0;
304
304
  if (!(error instanceof AuthError || error instanceof ConfigurationError || error instanceof ClientError))
305
305
  throw error;
306
- const logout2 = useLogOut(), authState = useAuthState(), [authErrorMessage, setAuthErrorMessage] = useState("Please try again or contact support if the problem persists.");
306
+ const logout2 = useLogOut(), authState = useAuthState(), [authErrorMessage, setAuthErrorMessage] = useState("Please try again or contact support if the problem persists."), [showRetryCta, setShowRetryCta] = useState(!0);
307
307
  let t1;
308
308
  $[0] !== logout2 || $[1] !== resetErrorBoundary ? (t1 = async () => {
309
309
  await logout2(), resetErrorBoundary();
@@ -313,24 +313,28 @@ function LoginError(t0) {
313
313
  $[3] !== authState.type || $[4] !== error || $[5] !== handleRetry ? (t2 = () => {
314
314
  if (error instanceof ClientError) {
315
315
  if (error.statusCode === 401)
316
- handleRetry();
316
+ if (isProjectUserNotFoundClientError(error)) {
317
+ const description = getClientErrorApiDescription(error);
318
+ description && setAuthErrorMessage(description), setShowRetryCta(!1);
319
+ } else
320
+ setShowRetryCta(!0), handleRetry();
317
321
  else if (error.statusCode === 404) {
318
- const errorMessage = error.response.body.message || "";
319
- errorMessage.startsWith("Session with sid") && errorMessage.endsWith("not found") ? setAuthErrorMessage("The session ID is invalid or expired.") : setAuthErrorMessage("The login link is invalid or expired. Please try again.");
322
+ const errorMessage = getClientErrorApiBody(error)?.message || "";
323
+ errorMessage.startsWith("Session with sid") && errorMessage.endsWith("not found") ? setAuthErrorMessage("The session ID is invalid or expired.") : setAuthErrorMessage("The login link is invalid or expired. Please try again."), setShowRetryCta(!0);
320
324
  }
321
325
  }
322
- authState.type !== AuthStateType.ERROR && error instanceof ConfigurationError && setAuthErrorMessage(error.message);
326
+ authState.type !== AuthStateType.ERROR && error instanceof ConfigurationError && (setAuthErrorMessage(error.message), setShowRetryCta(!0));
323
327
  }, $[3] = authState.type, $[4] = error, $[5] = handleRetry, $[6] = t2) : t2 = $[6];
324
328
  let t3;
325
329
  $[7] !== authState || $[8] !== error || $[9] !== handleRetry ? (t3 = [authState, handleRetry, error], $[7] = authState, $[8] = error, $[9] = handleRetry, $[10] = t3) : t3 = $[10], useEffect(t2, t3);
326
330
  const t4 = error instanceof AuthError ? "Authentication Error" : "Configuration Error";
327
331
  let t5;
328
- $[11] !== handleRetry ? (t5 = {
332
+ $[11] !== handleRetry || $[12] !== showRetryCta ? (t5 = showRetryCta ? {
329
333
  text: "Retry",
330
334
  onClick: handleRetry
331
- }, $[11] = handleRetry, $[12] = t5) : t5 = $[12];
335
+ } : void 0, $[11] = handleRetry, $[12] = showRetryCta, $[13] = t5) : t5 = $[13];
332
336
  let t6;
333
- return $[13] !== authErrorMessage || $[14] !== t4 || $[15] !== t5 ? (t6 = /* @__PURE__ */ jsx(Error$1, { heading: t4, description: authErrorMessage, cta: t5 }), $[13] = authErrorMessage, $[14] = t4, $[15] = t5, $[16] = t6) : t6 = $[16], t6;
337
+ return $[14] !== authErrorMessage || $[15] !== t4 || $[16] !== t5 ? (t6 = /* @__PURE__ */ jsx(Error$1, { heading: t4, description: authErrorMessage, cta: t5 }), $[14] = authErrorMessage, $[15] = t4, $[16] = t5, $[17] = t6) : t6 = $[17], t6;
334
338
  }
335
339
  if (isInIframe() && !document.querySelector("[data-sanity-core]")) {
336
340
  const parsedUrl = new URL(window.location.href), mode = new URLSearchParams(parsedUrl.hash.slice(1)).get("mode"), script = document.createElement("script");
@@ -449,6 +453,60 @@ function SanityApp(t0) {
449
453
  function _temp$4() {
450
454
  console.warn("Redirecting to core", REDIRECT_URL), window.location.replace(REDIRECT_URL);
451
455
  }
456
+ const useAgentGenerate = createCallbackHook(agentGenerate), useAgentTransform = createCallbackHook(agentTransform), useAgentTranslate = createCallbackHook(agentTranslate);
457
+ function promptAdapter(instance, options) {
458
+ return firstValueFrom(agentPrompt(instance, options));
459
+ }
460
+ const useAgentPrompt = createCallbackHook(promptAdapter);
461
+ function patchAdapter(instance, options) {
462
+ return firstValueFrom(agentPatch(instance, options));
463
+ }
464
+ const useAgentPatch = createCallbackHook(patchAdapter);
465
+ function useAgentResourceContext(options) {
466
+ const $ = c(9), {
467
+ projectId,
468
+ dataset,
469
+ documentId
470
+ } = options;
471
+ let t0;
472
+ $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = {
473
+ name: SDK_NODE_NAME,
474
+ connectTo: SDK_CHANNEL_NAME
475
+ }, $[0] = t0) : t0 = $[0];
476
+ const {
477
+ sendMessage
478
+ } = useWindowConnection(t0), lastContextRef = useRef(null);
479
+ let t1;
480
+ $[1] !== dataset || $[2] !== documentId || $[3] !== projectId || $[4] !== sendMessage ? (t1 = () => {
481
+ if (!projectId || !dataset) {
482
+ console.warn("[useAgentResourceContext] projectId and dataset are required", {
483
+ projectId,
484
+ dataset
485
+ });
486
+ return;
487
+ }
488
+ const contextKey = `${projectId}:${dataset}:${documentId || ""}`;
489
+ if (lastContextRef.current !== contextKey)
490
+ try {
491
+ const message = {
492
+ type: "dashboard/v1/events/agent/resource/update",
493
+ data: {
494
+ projectId,
495
+ dataset,
496
+ documentId
497
+ }
498
+ };
499
+ sendMessage(message.type, message.data), lastContextRef.current = contextKey;
500
+ } catch (t22) {
501
+ console.error("[useAgentResourceContext] Failed to update context:", t22);
502
+ }
503
+ }, $[1] = dataset, $[2] = documentId, $[3] = projectId, $[4] = sendMessage, $[5] = t1) : t1 = $[5];
504
+ const updateContext = t1;
505
+ let t2, t3;
506
+ $[6] !== updateContext ? (t2 = () => {
507
+ updateContext();
508
+ }, t3 = [updateContext], $[6] = updateContext, $[7] = t2, $[8] = t3) : (t2 = $[7], t3 = $[8]), useEffect(t2, t3);
509
+ }
452
510
  const useAuthToken = createStateSourceHook(getTokenState), useCurrentUser = createStateSourceHook(getCurrentUserState);
453
511
  function useDashboardOrganizationId() {
454
512
  const $ = c(2), instance = useSanityInstance();
@@ -461,8 +519,12 @@ function useDashboardOrganizationId() {
461
519
  return useSyncExternalStore(subscribe, getCurrent);
462
520
  }
463
521
  const useClient = createStateSourceHook({
464
- getState: getClientState,
465
- getConfig: identity
522
+ getState: (instance, options) => {
523
+ if (!options || typeof options != "object")
524
+ throw new Error('useClient() requires a configuration object with at least an "apiVersion" property. Example: useClient({ apiVersion: "2024-11-12" })');
525
+ return getClientState(instance, options);
526
+ },
527
+ getConfig: (options) => options
466
528
  });
467
529
  function useFrameConnection(options) {
468
530
  const $ = c(12), {
@@ -526,6 +588,84 @@ function useDashboardNavigate(navigateFn) {
526
588
  }
527
589
  }, $[0] = navigateFn, $[1] = t0) : t0 = $[1], useWindowConnection(t0);
528
590
  }
591
+ const SOURCE_ID = "__sanity_internal_sourceId", isDocumentHandleWithSource = (documentHandle) => "source" in documentHandle;
592
+ function getResourceIdFromDocumentHandle(documentHandle) {
593
+ let source;
594
+ const {
595
+ projectId,
596
+ dataset
597
+ } = documentHandle;
598
+ isDocumentHandleWithSource(documentHandle) && (source = documentHandle.source);
599
+ let resourceId = projectId + "." + dataset, resourceType;
600
+ if (source) {
601
+ const sourceId = source[SOURCE_ID];
602
+ if (Array.isArray(sourceId))
603
+ (sourceId[0] === "media-library" || sourceId[0] === "canvas") && (resourceType = sourceId[0], resourceId = sourceId[1]);
604
+ else if (sourceId && typeof sourceId == "object" && "projectId" in sourceId) {
605
+ const datasetSource = sourceId;
606
+ resourceId = `${datasetSource.projectId}.${datasetSource.dataset}`;
607
+ }
608
+ }
609
+ return {
610
+ id: resourceId,
611
+ type: resourceType
612
+ };
613
+ }
614
+ function useDispatchIntent(params) {
615
+ const {
616
+ action,
617
+ intentId,
618
+ documentHandle,
619
+ parameters
620
+ } = params, {
621
+ sendMessage
622
+ } = useWindowConnection({
623
+ name: SDK_NODE_NAME,
624
+ connectTo: SDK_CHANNEL_NAME
625
+ });
626
+ return {
627
+ dispatchIntent: useCallback(() => {
628
+ try {
629
+ if (!action && !intentId)
630
+ throw new Error("useDispatchIntent: Either `action` or `intentId` must be provided.");
631
+ const {
632
+ projectId,
633
+ dataset,
634
+ source
635
+ } = documentHandle;
636
+ if (action && intentId && console.warn("useDispatchIntent: Both `action` and `intentId` were provided. Using `intentId` and ignoring `action`."), !source && (!projectId || !dataset))
637
+ throw new Error("useDispatchIntent: Either `source` or both `projectId` and `dataset` must be provided in documentHandle.");
638
+ const resource = getResourceIdFromDocumentHandle(documentHandle), message = {
639
+ type: "dashboard/v1/events/intents/dispatch-intent",
640
+ data: {
641
+ ...action && !intentId ? {
642
+ action
643
+ } : {},
644
+ ...intentId ? {
645
+ intentId
646
+ } : {},
647
+ document: {
648
+ id: documentHandle.documentId,
649
+ type: documentHandle.documentType
650
+ },
651
+ resource: {
652
+ id: resource.id,
653
+ ...resource.type ? {
654
+ type: resource.type
655
+ } : {}
656
+ },
657
+ ...parameters && Object.keys(parameters).length > 0 ? {
658
+ parameters
659
+ } : {}
660
+ }
661
+ };
662
+ sendMessage(message.type, message.data);
663
+ } catch (error) {
664
+ throw console.error("Failed to dispatch intent:", error), error;
665
+ }
666
+ }, [action, intentId, documentHandle, parameters, sendMessage])
667
+ };
668
+ }
529
669
  function useManageFavorite({
530
670
  documentId,
531
671
  documentType,
@@ -738,7 +878,41 @@ const useDatasets = createStateSourceHook({
738
878
  ),
739
879
  suspender: resolveDatasets,
740
880
  getConfig: identity
741
- }), useApplyDocumentActions = createCallbackHook(applyDocumentActions), useDocumentValue = createStateSourceHook({
881
+ }), useApplyDocumentActions = () => {
882
+ const $ = c(2), instance = useSanityInstance();
883
+ let t0;
884
+ return $[0] !== instance ? (t0 = (actionOrActions, options) => {
885
+ const actions = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions];
886
+ let projectId, dataset;
887
+ for (const action of actions)
888
+ if (action.projectId) {
889
+ if (projectId || (projectId = action.projectId), action.projectId !== projectId)
890
+ throw new Error(`Mismatched project IDs found in actions. All actions must belong to the same project. Found "${action.projectId}" but expected "${projectId}".`);
891
+ if (action.dataset && (dataset || (dataset = action.dataset), action.dataset !== dataset))
892
+ throw new Error(`Mismatched datasets found in actions. All actions must belong to the same dataset. Found "${action.dataset}" but expected "${dataset}".`);
893
+ }
894
+ if (projectId || dataset) {
895
+ const actualInstance = instance.match({
896
+ projectId,
897
+ dataset
898
+ });
899
+ if (!actualInstance)
900
+ throw new Error(`Could not find a matching Sanity instance for the requested action: ${JSON.stringify({
901
+ projectId,
902
+ dataset
903
+ }, null, 2)}.
904
+ Please ensure there is a ResourceProvider component with a matching configuration in the component hierarchy.`);
905
+ return applyDocumentActions(actualInstance, {
906
+ actions,
907
+ ...options
908
+ });
909
+ }
910
+ return applyDocumentActions(instance, {
911
+ actions,
912
+ ...options
913
+ });
914
+ }, $[0] = instance, $[1] = t0) : t0 = $[1], t0;
915
+ }, useDocumentValue = createStateSourceHook({
742
916
  // Pass options directly to getDocumentState
743
917
  getState: (instance, options) => getDocumentState(instance, options),
744
918
  // Pass options directly to getDocumentState for checking current value
@@ -777,8 +951,8 @@ function useDocumentEvent(options) {
777
951
  }
778
952
  function useDocumentPermissions(actionOrActions) {
779
953
  const $ = c(13);
780
- let t0;
781
- $[0] !== actionOrActions ? (t0 = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions], $[0] = actionOrActions, $[1] = t0) : t0 = $[1];
954
+ let t0, t1;
955
+ $[0] !== actionOrActions ? (t1 = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions], $[0] = actionOrActions, $[1] = t1) : t1 = $[1], t0 = t1;
782
956
  const actions = t0;
783
957
  let projectId, dataset;
784
958
  if ($[2] !== actions || $[3] !== dataset || $[4] !== projectId) {
@@ -792,20 +966,26 @@ function useDocumentPermissions(actionOrActions) {
792
966
  $[2] = actions, $[3] = dataset, $[4] = projectId, $[5] = projectId, $[6] = dataset;
793
967
  } else
794
968
  projectId = $[5], dataset = $[6];
795
- let t1;
796
- $[7] !== dataset || $[8] !== projectId ? (t1 = {
969
+ let t2;
970
+ $[7] !== dataset || $[8] !== projectId ? (t2 = {
797
971
  projectId,
798
972
  dataset
799
- }, $[7] = dataset, $[8] = projectId, $[9] = t1) : t1 = $[9];
800
- const instance = useSanityInstance(t1);
801
- if (getPermissionsState(instance, actionOrActions).getCurrent() === void 0)
802
- throw firstValueFrom(getPermissionsState(instance, actionOrActions).observable.pipe(filter(_temp$2)));
803
- let t2, t3;
804
- $[10] !== actionOrActions || $[11] !== instance ? (t3 = getPermissionsState(instance, actionOrActions), $[10] = actionOrActions, $[11] = instance, $[12] = t3) : t3 = $[12], t2 = t3;
973
+ }, $[7] = dataset, $[8] = projectId, $[9] = t2) : t2 = $[9];
974
+ const instance = useSanityInstance(t2);
975
+ if (getPermissionsState(instance, {
976
+ actions
977
+ }).getCurrent() === void 0)
978
+ throw firstValueFrom(getPermissionsState(instance, {
979
+ actions
980
+ }).observable.pipe(filter(_temp$2)));
981
+ let t3, t4;
982
+ $[10] !== actions || $[11] !== instance ? (t4 = getPermissionsState(instance, {
983
+ actions
984
+ }), $[10] = actions, $[11] = instance, $[12] = t4) : t4 = $[12], t3 = t4;
805
985
  const {
806
986
  subscribe,
807
987
  getCurrent
808
- } = t2;
988
+ } = t3;
809
989
  return useSyncExternalStore(subscribe, getCurrent);
810
990
  }
811
991
  function _temp$2(result) {
@@ -1125,35 +1305,27 @@ function useDocumentPreview(t0) {
1125
1305
  return currentState;
1126
1306
  }, $[9] = docHandle, $[10] = instance, $[11] = stateSource, $[12] = t3) : t3 = $[12], useSyncExternalStore(subscribe, t3);
1127
1307
  }
1128
- function useDocumentProjection(t0) {
1129
- const $ = c(12);
1130
- let docHandle, projection, ref;
1131
- $[0] !== t0 ? ({
1132
- ref,
1133
- projection,
1134
- ...docHandle
1135
- } = t0, $[0] = t0, $[1] = docHandle, $[2] = projection, $[3] = ref) : (docHandle = $[1], projection = $[2], ref = $[3]);
1136
- const instance = useSanityInstance(docHandle);
1137
- let stateSource, t1;
1138
- if ($[4] !== docHandle || $[5] !== instance || $[6] !== projection ? (stateSource = getProjectionState(instance, {
1308
+ function useDocumentProjection({
1309
+ ref,
1310
+ projection,
1311
+ ...docHandle
1312
+ }) {
1313
+ const instance = useSanityInstance(docHandle), normalizedProjection = useMemo(() => projection.trim(), [projection]), stateSource = useMemo(() => getProjectionState(instance, {
1139
1314
  ...docHandle,
1140
- projection
1141
- }), t1 = stateSource.getCurrent()?.data, $[4] = docHandle, $[5] = instance, $[6] = projection, $[7] = stateSource, $[8] = t1) : (stateSource = $[7], t1 = $[8]), t1 === null)
1315
+ projection: normalizedProjection
1316
+ }), [instance, normalizedProjection, docHandle]);
1317
+ if (stateSource.getCurrent()?.data === null)
1142
1318
  throw resolveProjection(instance, {
1143
1319
  ...docHandle,
1144
- projection
1320
+ projection: normalizedProjection
1145
1321
  });
1146
- let t2;
1147
- return $[9] !== ref || $[10] !== stateSource ? (t2 = (onStoreChanged) => {
1322
+ const subscribe = useCallback((onStoreChanged) => {
1148
1323
  const subscription = new Observable((observer) => {
1149
1324
  if (typeof IntersectionObserver > "u" || typeof HTMLElement > "u") {
1150
1325
  observer.next(!0);
1151
1326
  return;
1152
1327
  }
1153
- const intersectionObserver = new IntersectionObserver((t3) => {
1154
- const [entry] = t3;
1155
- return observer.next(entry.isIntersecting);
1156
- }, {
1328
+ const intersectionObserver = new IntersectionObserver(([entry]) => observer.next(entry.isIntersecting), {
1157
1329
  rootMargin: "0px",
1158
1330
  threshold: 0
1159
1331
  });
@@ -1162,7 +1334,8 @@ function useDocumentProjection(t0) {
1162
1334
  next: onStoreChanged
1163
1335
  });
1164
1336
  return () => subscription.unsubscribe();
1165
- }, $[9] = ref, $[10] = stateSource, $[11] = t2) : t2 = $[11], useSyncExternalStore(t2, stateSource.getCurrent);
1337
+ }, [stateSource, ref]);
1338
+ return useSyncExternalStore(subscribe, stateSource.getCurrent);
1166
1339
  }
1167
1340
  const useProject = createStateSourceHook({
1168
1341
  // remove `undefined` since we're suspending when that is the case
@@ -1233,7 +1406,7 @@ function useUsers(options) {
1233
1406
  loadMore
1234
1407
  };
1235
1408
  }
1236
- var version = "2.3.1";
1409
+ var version = "2.5.0";
1237
1410
  function getEnv(key) {
1238
1411
  if (typeof import.meta < "u" && import.meta.env)
1239
1412
  return import.meta.env[key];
@@ -1251,6 +1424,12 @@ export {
1251
1424
  SDKProvider,
1252
1425
  SanityApp,
1253
1426
  useActiveReleases,
1427
+ useAgentGenerate,
1428
+ useAgentPatch,
1429
+ useAgentPrompt,
1430
+ useAgentResourceContext,
1431
+ useAgentTransform,
1432
+ useAgentTranslate,
1254
1433
  useApplyDocumentActions,
1255
1434
  useAuthState,
1256
1435
  useAuthToken,
@@ -1259,6 +1438,7 @@ export {
1259
1438
  useDashboardNavigate,
1260
1439
  useDashboardOrganizationId,
1261
1440
  useDatasets,
1441
+ useDispatchIntent,
1262
1442
  useDocument,
1263
1443
  useDocumentEvent,
1264
1444
  useDocumentPermissions,