@sanity/sdk-react 0.0.0-alpha.8 → 0.0.0-chore-react-18-compat.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 (100) hide show
  1. package/README.md +33 -126
  2. package/dist/index.d.ts +4811 -2
  3. package/dist/index.js +1069 -2
  4. package/dist/index.js.map +1 -1
  5. package/package.json +23 -45
  6. package/src/_exports/index.ts +66 -10
  7. package/src/components/Login/LoginLinks.test.tsx +90 -0
  8. package/src/components/Login/LoginLinks.tsx +58 -0
  9. package/src/components/SDKProvider.test.tsx +79 -0
  10. package/src/components/SDKProvider.tsx +42 -0
  11. package/src/components/SanityApp.test.tsx +104 -2
  12. package/src/components/SanityApp.tsx +54 -17
  13. package/src/components/auth/AuthBoundary.test.tsx +4 -4
  14. package/src/components/auth/AuthBoundary.tsx +13 -3
  15. package/src/components/auth/Login.test.tsx +1 -1
  16. package/src/components/auth/Login.tsx +11 -26
  17. package/src/components/auth/LoginCallback.test.tsx +3 -3
  18. package/src/components/auth/LoginCallback.tsx +8 -11
  19. package/src/components/auth/LoginError.tsx +12 -8
  20. package/src/components/auth/LoginFooter.tsx +13 -20
  21. package/src/components/auth/LoginLayout.tsx +8 -9
  22. package/src/components/auth/authTestHelpers.tsx +1 -8
  23. package/src/components/utils.ts +22 -0
  24. package/src/context/SanityInstanceContext.ts +4 -0
  25. package/src/context/SanityProvider.test.tsx +1 -1
  26. package/src/context/SanityProvider.tsx +10 -8
  27. package/src/hooks/_synchronous-groq-js.mjs +4 -0
  28. package/src/hooks/auth/useAuthState.tsx +0 -2
  29. package/src/hooks/auth/useCurrentUser.tsx +27 -20
  30. package/src/hooks/auth/useDashboardOrganizationId.test.tsx +42 -0
  31. package/src/hooks/auth/useDashboardOrganizationId.tsx +29 -0
  32. package/src/hooks/auth/useHandleAuthCallback.test.tsx +16 -0
  33. package/src/hooks/auth/{useHandleCallback.tsx → useHandleAuthCallback.tsx} +6 -6
  34. package/src/hooks/auth/useLogOut.test.tsx +2 -2
  35. package/src/hooks/client/useClient.ts +9 -30
  36. package/src/hooks/comlink/useFrameConnection.test.tsx +55 -10
  37. package/src/hooks/comlink/useFrameConnection.ts +39 -43
  38. package/src/hooks/comlink/useManageFavorite.test.ts +111 -0
  39. package/src/hooks/comlink/useManageFavorite.ts +130 -0
  40. package/src/hooks/comlink/useRecordDocumentHistoryEvent.test.ts +81 -0
  41. package/src/hooks/comlink/useRecordDocumentHistoryEvent.ts +106 -0
  42. package/src/hooks/comlink/useWindowConnection.test.ts +53 -12
  43. package/src/hooks/comlink/useWindowConnection.ts +69 -29
  44. package/src/hooks/context/useSanityInstance.test.tsx +1 -1
  45. package/src/hooks/context/useSanityInstance.ts +21 -5
  46. package/src/hooks/dashboard/useNavigateToStudioDocument.test.ts +178 -0
  47. package/src/hooks/dashboard/useNavigateToStudioDocument.ts +123 -0
  48. package/src/hooks/dashboard/useStudioWorkspacesByResourceId.test.tsx +278 -0
  49. package/src/hooks/dashboard/useStudioWorkspacesByResourceId.ts +92 -0
  50. package/src/hooks/datasets/useDatasets.ts +40 -0
  51. package/src/hooks/document/useApplyDocumentActions.test.ts +25 -0
  52. package/src/hooks/document/useApplyDocumentActions.ts +75 -0
  53. package/src/hooks/document/useDocument.test.ts +81 -0
  54. package/src/hooks/document/useDocument.ts +107 -0
  55. package/src/hooks/document/useDocumentEvent.test.ts +63 -0
  56. package/src/hooks/document/useDocumentEvent.ts +54 -0
  57. package/src/hooks/document/useDocumentPermissions.ts +84 -0
  58. package/src/hooks/document/useDocumentSyncStatus.test.ts +16 -0
  59. package/src/hooks/document/useDocumentSyncStatus.ts +33 -0
  60. package/src/hooks/document/useEditDocument.test.ts +179 -0
  61. package/src/hooks/document/useEditDocument.ts +195 -0
  62. package/src/hooks/documents/useDocuments.test.tsx +152 -0
  63. package/src/hooks/documents/useDocuments.ts +174 -0
  64. package/src/hooks/helpers/createCallbackHook.tsx +3 -2
  65. package/src/hooks/helpers/createStateSourceHook.test.tsx +66 -0
  66. package/src/hooks/helpers/createStateSourceHook.tsx +29 -10
  67. package/src/hooks/paginatedDocuments/usePaginatedDocuments.test.tsx +259 -0
  68. package/src/hooks/paginatedDocuments/usePaginatedDocuments.ts +290 -0
  69. package/src/hooks/preview/usePreview.test.tsx +6 -6
  70. package/src/hooks/preview/usePreview.tsx +12 -9
  71. package/src/hooks/projection/useProjection.test.tsx +218 -0
  72. package/src/hooks/projection/useProjection.ts +147 -0
  73. package/src/hooks/projects/useProject.ts +48 -0
  74. package/src/hooks/projects/useProjects.ts +45 -0
  75. package/src/hooks/query/useQuery.test.tsx +188 -0
  76. package/src/hooks/query/useQuery.ts +103 -0
  77. package/src/hooks/users/useUsers.test.ts +163 -0
  78. package/src/hooks/users/useUsers.ts +107 -0
  79. package/src/utils/getEnv.ts +21 -0
  80. package/src/version.ts +8 -0
  81. package/dist/_chunks-es/context.js +0 -8
  82. package/dist/_chunks-es/context.js.map +0 -1
  83. package/dist/_chunks-es/useLogOut.js +0 -44
  84. package/dist/_chunks-es/useLogOut.js.map +0 -1
  85. package/dist/components.d.ts +0 -111
  86. package/dist/components.js +0 -153
  87. package/dist/components.js.map +0 -1
  88. package/dist/context.d.ts +0 -45
  89. package/dist/context.js +0 -5
  90. package/dist/context.js.map +0 -1
  91. package/dist/hooks.d.ts +0 -3485
  92. package/dist/hooks.js +0 -167
  93. package/dist/hooks.js.map +0 -1
  94. package/src/_exports/components.ts +0 -2
  95. package/src/_exports/context.ts +0 -2
  96. package/src/_exports/hooks.ts +0 -27
  97. package/src/hooks/auth/useHandleCallback.test.tsx +0 -16
  98. package/src/hooks/client/useClient.test.tsx +0 -130
  99. package/src/hooks/documentCollection/useDocuments.test.ts +0 -130
  100. package/src/hooks/documentCollection/useDocuments.ts +0 -135
@@ -1,4 +1,3 @@
1
- import {Button, Heading, Stack, Text} from '@sanity/ui'
2
1
  import {useCallback} from 'react'
3
2
  import {type FallbackProps} from 'react-error-boundary'
4
3
 
@@ -33,13 +32,18 @@ export function LoginError({
33
32
 
34
33
  return (
35
34
  <LoginLayout header={header} footer={footer}>
36
- <Stack space={5} marginBottom={5}>
37
- <Heading as="h6" align="center">
38
- Authentication Error
39
- </Heading>
40
- <Text align="center">Please try again or contact support if the problem persists.</Text>
41
- <Button mode="ghost" onClick={handleRetry} text="Retry" fontSize={2} />
42
- </Stack>
35
+ <div className="sc-login-error">
36
+ <div className="sc-login-error__content">
37
+ <h2 className="sc-login-error__title">Authentication Error</h2>
38
+ <p className="sc-login-error__description">
39
+ Please try again or contact support if the problem persists.
40
+ </p>
41
+ </div>
42
+
43
+ <button className="sc-login-error__button" onClick={handleRetry}>
44
+ Retry
45
+ </button>
46
+ </div>
43
47
  </LoginLayout>
44
48
  )
45
49
  }
@@ -1,5 +1,5 @@
1
1
  import {SanityLogo} from '@sanity/logos'
2
- import {Box, Flex, Inline, Text} from '@sanity/ui'
2
+ import {Fragment} from 'react'
3
3
 
4
4
  const LINKS = [
5
5
  {
@@ -32,27 +32,20 @@ const LINKS = [
32
32
  */
33
33
  export function LoginFooter(): React.ReactNode {
34
34
  return (
35
- <Box>
36
- <Flex justify="center">
37
- <SanityLogo />
38
- </Flex>
35
+ <div className="sc-login-footer">
36
+ <SanityLogo className="sc-login-footer__logo" />
39
37
 
40
- <Flex justify="center">
41
- <Inline space={2} paddingY={3}>
42
- {LINKS.map((link) => (
43
- <Text size={0} key={link.url}>
44
- <a
45
- href={link.url}
46
- target="_blank"
47
- rel="noopener noreferrer"
48
- style={{color: 'inherit'}}
49
- >
38
+ <ul className="sc-login-footer__links">
39
+ {LINKS.map((link) => (
40
+ <Fragment key={link.title}>
41
+ <li className="sc-login-footer__link">
42
+ <a href={link.url} target="_blank" rel="noopener noreferrer">
50
43
  {link.title}
51
44
  </a>
52
- </Text>
53
- ))}
54
- </Inline>
55
- </Flex>
56
- </Box>
45
+ </li>
46
+ </Fragment>
47
+ ))}
48
+ </ul>
49
+ </div>
57
50
  )
58
51
  }
@@ -1,10 +1,7 @@
1
- import {Card, Container} from '@sanity/ui'
2
-
3
1
  import {LoginFooter} from './LoginFooter'
4
2
 
5
3
  /**
6
4
  * @alpha
7
- * @internal
8
5
  */
9
6
  export interface LoginLayoutProps {
10
7
  /** Optional header content rendered at top of card */
@@ -57,14 +54,16 @@ export function LoginLayout({
57
54
  header,
58
55
  }: LoginLayoutProps): React.ReactNode {
59
56
  return (
60
- <Container width={0}>
61
- <Card shadow={1} radius={2} padding={4}>
62
- {header && header}
57
+ <div className="sc-login-layout">
58
+ <div className="sc-login-layout__container">
59
+ <div className="sc-login-layout__card">
60
+ {header && <div className="sc-login-layout__card-header">{header}</div>}
63
61
 
64
- {children && children}
62
+ {children && <div className="sc-login-layout__card-body">{children}</div>}
63
+ </div>
65
64
 
66
65
  {footer}
67
- </Card>
68
- </Container>
66
+ </div>
67
+ </div>
69
68
  )
70
69
  }
@@ -1,18 +1,11 @@
1
1
  import {createSanityInstance} from '@sanity/sdk'
2
- import {ThemeProvider} from '@sanity/ui'
3
- import {buildTheme} from '@sanity/ui/theme'
4
2
  import {render, type RenderResult} from '@testing-library/react'
5
3
  import React from 'react'
6
4
 
7
5
  import {SanityProvider} from '../../context/SanityProvider'
8
6
 
9
7
  const sanityInstance = createSanityInstance({projectId: 'test-project-id', dataset: 'production'})
10
- const theme = buildTheme()
11
8
 
12
9
  export const renderWithWrappers = (ui: React.ReactElement): RenderResult => {
13
- return render(
14
- <SanityProvider sanityInstance={sanityInstance}>
15
- <ThemeProvider theme={theme}>{ui}</ThemeProvider>
16
- </SanityProvider>,
17
- )
10
+ return render(<SanityProvider sanityInstances={[sanityInstance]}>{ui}</SanityProvider>)
18
11
  }
@@ -0,0 +1,22 @@
1
+ export function isInIframe(): boolean {
2
+ return typeof window !== 'undefined' && window.self !== window.top
3
+ }
4
+
5
+ /**
6
+ * @internal
7
+ *
8
+ * Checks if the current URL is a local URL.
9
+ *
10
+ * @param window - The window object
11
+ * @returns True if the current URL is a local URL, false otherwise
12
+ */
13
+ export function isLocalUrl(window: Window): boolean {
14
+ const url = typeof window !== 'undefined' ? window.location.href : ''
15
+
16
+ return (
17
+ url.startsWith('http://localhost') ||
18
+ url.startsWith('https://localhost') ||
19
+ url.startsWith('http://127.0.0.1') ||
20
+ url.startsWith('https://127.0.0.1')
21
+ )
22
+ }
@@ -0,0 +1,4 @@
1
+ import {type SanityInstance} from '@sanity/sdk'
2
+ import {createContext} from 'react'
3
+
4
+ export const SanityInstanceContext = createContext<SanityInstance[] | null>(null)
@@ -15,7 +15,7 @@ describe('SanityProvider', () => {
15
15
  }
16
16
 
17
17
  const {getByTestId} = render(
18
- <SanityProvider sanityInstance={sanityInstance}>
18
+ <SanityProvider sanityInstances={[sanityInstance]}>
19
19
  <TestComponent />
20
20
  </SanityProvider>,
21
21
  )
@@ -1,21 +1,23 @@
1
1
  import {type SanityInstance} from '@sanity/sdk'
2
- import {createContext, type ReactElement} from 'react'
2
+ import {type ReactElement} from 'react'
3
+
4
+ import {SanityInstanceContext} from './SanityInstanceContext'
3
5
 
4
6
  /**
5
- * @public
7
+ * @internal
6
8
  */
7
9
  export interface SanityProviderProps {
8
10
  children: React.ReactNode
9
- sanityInstance: SanityInstance
11
+ sanityInstances: SanityInstance[]
10
12
  }
11
13
 
12
- export const SanityInstanceContext = createContext<SanityInstance | null>(null)
13
-
14
14
  /**
15
+ * @internal
16
+ *
15
17
  * Top-level context provider that provides access to the Sanity configuration instance.
16
18
  * This must wrap any components making use of the Sanity SDK React hooks.
19
+ *
17
20
  * @remarks In most cases, SanityApp should be used rather than SanityProvider directly; SanityApp bundles both SanityProvider and an authentication layer.
18
- * @internal
19
21
  * @param props - Sanity project and dataset configuration
20
22
  * @returns Rendered component
21
23
  * @example
@@ -39,9 +41,9 @@ export const SanityInstanceContext = createContext<SanityInstance | null>(null)
39
41
  * }
40
42
  * ```
41
43
  */
42
- export const SanityProvider = ({children, sanityInstance}: SanityProviderProps): ReactElement => {
44
+ export const SanityProvider = ({children, sanityInstances}: SanityProviderProps): ReactElement => {
43
45
  return (
44
- <SanityInstanceContext.Provider value={sanityInstance}>
46
+ <SanityInstanceContext.Provider value={sanityInstances}>
45
47
  {children}
46
48
  </SanityInstanceContext.Provider>
47
49
  )
@@ -0,0 +1,4 @@
1
+ // NOTE: this is a stop-gap measure until sychronous groq is out
2
+ // eslint-disable
3
+ // prettier-ignore
4
+ class e{pattern;patternRe;constructor(e){this.pattern=e,this.patternRe=function(e){const t=[];for(const r of e.split("."))"*"===r?t.push("[^.]+"):"**"===r?t.push(".*"):t.push(r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"));return new RegExp(`^${t.join(".")}$`)}(e)}matches(e){return this.patternRe.test(e)}toJSON(){return this.pattern}}class t{type="stream";generator;ticker;isDone;data;constructor(e){this.generator=e,this.ticker=null,this.isDone=!1,this.data=[]}isArray(){return!0}async get(){const e=[];for await(const t of this)e.push(await t.get());return e}async first(e=()=>!0){for await(const t of this)if(e(t))return t}async reduce(e,t){let r=t;for await(const t of this)r=await e(r,t);return r}async*[Symbol.asyncIterator](){let e=0;for(;;){for(;e<this.data.length;e++)yield this.data[e];if(this.isDone)return;await this._nextTick()}}_nextTick(){if(this.ticker)return this.ticker;let e;const t=()=>{this.ticker=new Promise((t=>{e=t}))},r=()=>{e(),t()};return t(),(async()=>{for await(const e of this.generator())this.data.push(e),r();this.isDone=!0,r()})(),this.ticker}}const r=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|([-+]\d{2}:\d{2}))$/;function n(e,t){let r=e.toString();for(;r.length<t;)r=`0${r}`;return r}class o{data;type;constructor(e,t){this.data=e,this.type=t}isArray(){return"array"===this.type}get(){return this.data}first(e=()=>!0){if(!this.isArray())throw new Error("`first` can only be called on array `StaticValue`s");const t=this.get();for(const r of t){const t=f(r,"sync");if(e(t))return t}}reduce(e,t){if(!this.isArray())throw new Error("`reduce` can only be called on array `StaticValue`s");const r=this.get();let n=t;for(const t of r){n=e(n,f(t,"sync"))}return n}[Symbol.asyncIterator](){if(Array.isArray(this.data))return function*(e){for(const t of e)yield f(t,"async")}(this.data);throw new Error(`Cannot iterate over: ${this.type}`)}}const i=new o(null,"null"),s=new o(!0,"boolean"),a=new o(!1,"boolean");class c{date;constructor(e){this.date=e}static parseToValue(e){const t=function(e){return r.test(e)?new Date(e):null}(e);return t?new o(new c(t),"datetime"):i}equals(e){return this.date.getTime()==e.date.getTime()}add(e){const t=new Date(this.date.getTime());return t.setTime(t.getTime()+1e3*e),new c(t)}difference(e){return(this.date.getTime()-e.date.getTime())/1e3}compareTo(e){return this.date.getTime()-e.date.getTime()}toString(){return function(e){const t=n(e.getUTCFullYear(),4),r=n(e.getUTCMonth()+1,2),o=n(e.getUTCDate(),2),i=n(e.getUTCHours(),2),s=n(e.getUTCMinutes(),2),a=n(e.getUTCSeconds(),2);let c="";const u=e.getMilliseconds();return 0!=u&&(c=`.${n(u,3)}`),`${t}-${r}-${o}T${i}:${s}:${a}${c}Z`}(this.date)}toJSON(){return this.toString()}}function u(e){return Number.isFinite(e)?new o(e,"number"):i}function p(e){return new o(e,"string")}function l(e){return new o(e,"datetime")}function f(e,r){return(n=e)&&"function"==typeof n.next&&"sync"!==r?new t((async function*(){for await(const t of e)yield f(t,"async")})):null==e?i:new o(e,y(e));var n}function y(t){return null===t||typeof t>"u"?"null":Array.isArray(t)?"array":t instanceof e?"path":t instanceof c?"datetime":typeof t}const d=e=>"object"==typeof e&&!!e&&"then"in e&&"function"==typeof e.then;function h(e){const t=e(),r=t.next();if(r.done)return r.value;function n(e){const r=t.next(e);if(r.done)return r.value;const o=r.value;return o&&d(o)?o.then(n):n(o)}const o=r.value;return o&&d(o)?o.then(n):n(o)}function m(e,t){return"string"===e.type&&"string"===t.type||"boolean"===e.type&&"boolean"===t.type||"null"===e.type&&"null"===t.type||"number"===e.type&&"number"===t.type?e.data===t.data:"datetime"===e.type&&"datetime"===t.type&&e.data.equals(t.data)}const b=/([^!@#$%^&*(),\\/?";:{}|[\]+<>\s-])+/g,g=/([^!@#$%^&(),\\/?";:{}|[\]+<>\s-])+/g,w=/(\b\.+|\.+\b)/g;function k(e){return e.replace(w,"").match(b)||[]}function v(e){return x(e).map((e=>t=>t.some((t=>e.test(t)))))}function x(e){return(e.replace(w,"").match(g)||[]).map((e=>new RegExp(`^${e.slice(0,1024).replace(/\*/g,".*")}$`,"i")))}const _={datetime:1,number:2,string:3,boolean:4};function A(e,t){const r=y(e);if(r!==y(t))return null;switch(r){case"number":case"boolean":return e-t;case"string":return e<t?-1:e>t?1:0;case"datetime":return e.compareTo(t);default:return null}}function E(e,t){const r=y(e),n=y(t),o=_[r]||100,i=_[n]||100;if(o!==i)return o-i;let s=A(e,t);return null===s&&(s=0),s}const j={"==":function(e,t){return m(e,t)?s:a},"!=":function(e,t){return m(e,t)?a:s},">":function(e,t){if("stream"===e.type||"stream"===t.type)return i;const r=A(e.data,t.data);return null===r?i:r>0?s:a},">=":function(e,t){if("stream"===e.type||"stream"===t.type)return i;const r=A(e.data,t.data);return null===r?i:r>=0?s:a},"<":function(e,t){if("stream"===e.type||"stream"===t.type)return i;const r=A(e.data,t.data);return null===r?i:r<0?s:a},"<=":function(e,t){if("stream"===e.type||"stream"===t.type)return i;const r=A(e.data,t.data);return null===r?i:r<=0?s:a},in:function(e,t){return h((function*(){return"path"===t.type?"string"!==e.type?i:t.data.matches(e.data)?s:a:t.isArray()?(yield t.first((t=>m(e,t))))?s:a:i}))},match:function(e,t){return h((function*(){const r=yield e.get(),n=yield t.get();let o,i=[];if(Array.isArray(r)?i=r.filter((e=>"string"==typeof e)):"string"==typeof r&&(i=[r]),Array.isArray(n)?o=n.filter((e=>"string"==typeof e)):"string"==typeof n&&(o=[n]),!o?.length)return a;return function(e,t){return 0!==e.length&&0!==t.length&&t.every((t=>t(e)))}(i.flatMap(k),o.flatMap(v))?s:a}))},"+":function(e,r,n){return"datetime"===e.type&&"number"===r.type?l(e.data.add(r.data)):"number"===e.type&&"number"===r.type?u(e.data+r.data):"string"===e.type&&"string"===r.type?p(e.data+r.data):"object"===e.type&&"object"===r.type?f({...e.data,...r.data},n):"array"===e.type&&"array"===r.type?f(e.data.concat(r.data),n):e.isArray()&&r.isArray()?"sync"===n?h((function*(){const t=[...yield e.get(),...yield r.get()];return new o(t,"array")})):new t((async function*(){for await(const t of e)yield t;for await(const e of r)yield e})):i},"-":function(e,t){return"datetime"===e.type&&"number"===t.type?l(e.data.add(-t.data)):"datetime"===e.type&&"datetime"===t.type?u(e.data.difference(t.data)):"number"===e.type&&"number"===t.type?u(e.data-t.data):i},"*":S(((e,t)=>e*t)),"/":S(((e,t)=>e/t)),"%":S(((e,t)=>e%t)),"**":S(((e,t)=>Math.pow(e,t)))};function S(e){return function(t,r){if("number"===t.type&&"number"===r.type){return u(e(t.data,r.data))}return i}}let O=class e{params;source;value;parent;context;isHidden=!1;constructor(e,t,r,n,o){this.params=e,this.source=t,this.value=r,this.context=n,this.parent=o}createNested(t){return this.isHidden?new e(this.params,this.source,t,this.context,this.parent):new e(this.params,this.source,t,this.context,this)}createHidden(e){const t=this.createNested(e);return t.isHidden=!0,t}};function I(e,t,r){return(0,$[e.type])(e,t,r)}const $={This:(e,t)=>t.value,Selector(){throw new Error("Selectors can not be evaluated")},Everything:(e,t)=>t.source,Parameter:({name:e},t,r)=>f(t.params[e],r),Context({key:e},t){if("before"===e||"after"===e)return t.context[e]||i;throw new Error(`unknown context key: ${e}`)},Parent({n:e},t){let r=t;for(let t=0;t<e;t++){if(!r.parent)return i;r=r.parent}return r.value},OpCall:({op:e,left:t,right:r},n,o)=>h((function*(){const i=j[e];if(!i)throw new Error(`Unknown operator: ${e}`);const s=yield I(t,n,o),a=yield I(r,n,o);return yield i(s,a,o)})),Select:({alternatives:e,fallback:t},r,n)=>h((function*(){for(const t of e){const e=yield I(t.condition,r,n);if("boolean"===e.type&&!0===e.data)return yield I(t.value,r,n)}return t?yield I(t,r,n):i})),InRange:({base:e,left:t,right:r,isInclusive:n},o,c)=>h((function*(){const u=yield I(e,o,c),p=yield I(t,o,c),l=yield I(r,o,c),f=A(yield u.get(),yield p.get());if(null===f)return i;const y=A(yield u.get(),yield l.get());return null===y?i:n?f>=0&&y<=0?s:a:f>=0&&y<0?s:a})),Filter:({base:e,expr:r},n,s)=>h((function*(){const a=yield I(e,n,s);if(!a.isArray())return i;if("sync"===s){const e=yield a.get(),t=[];for(const o of e){const e=f(o,s),i=n.createNested(e),a=yield I(r,i,s);"boolean"===a.type&&!0===a.data&&t.push(o)}return new o(t,"array")}return new t((async function*(){for await(const e of a){const t=n.createNested(e),o=await I(r,t,s);"boolean"===o.type&&!0===o.data&&(yield e)}}))})),Projection:({base:e,expr:t},r,n)=>h((function*(){const o=yield I(e,r,n);if("object"!==o.type)return i;const s=r.createNested(o);return yield I(t,s,n)})),FuncCall:({func:e,args:t},r,n)=>e(t,r,n),PipeFuncCall:({func:e,base:t,args:r},n,o)=>h((function*(){const i=yield I(t,n,o);return yield e(i,r,n,o)})),AccessAttribute:({base:e,name:t},r,n)=>h((function*(){let o=r.value;return e&&(o=yield I(e,r,n)),"object"===o.type&&o.data.hasOwnProperty(t)?f(o.data[t],n):i})),AccessElement:({base:e,index:t},r,n)=>h((function*(){const o=yield I(e,r,n);if(!o.isArray())return i;const s=yield o.get();return f(s[t<0?t+s.length:t],n)})),Slice:({base:e,left:t,right:r,isInclusive:n},o,s)=>h((function*(){const a=yield I(e,o,s);if(!a.isArray())return i;const c=yield a.get();let u=t,p=r;return u<0&&(u=c.length+u),p<0&&(p=c.length+p),n&&p++,u<0&&(u=0),p<0&&(p=0),f(c.slice(u,p),s)})),Deref:({base:e},t,r)=>h((function*(){const n=yield I(e,t,r);if(!t.source.isArray()||"object"!==n.type)return i;const o=n.data._ref;if("string"!=typeof o)return i;if(t.context.dereference){return f(yield t.context.dereference({_ref:o}),r)}return(yield t.source.first((e=>"object"===e.type&&o==e.data._id)))||i})),Value:({value:e},t,r)=>f(e,r),Group:({base:e},t,r)=>I(e,t,r),Object:({attributes:e},t,r)=>h((function*(){const n={};for(const o of e){const e=o.type;switch(o.type){case"ObjectAttributeValue":{const e=yield I(o.value,t,r);n[o.name]=yield e.get();break}case"ObjectConditionalSplat":{const e=yield I(o.condition,t,r);if("boolean"!==e.type||!1===e.data)continue;const i=yield I(o.value,t,r);"object"===i.type&&Object.assign(n,i.data);break}case"ObjectSplat":{const e=yield I(o.value,t,r);"object"===e.type&&Object.assign(n,e.data);break}default:throw new Error(`Unknown node type: ${e}`)}}return f(n,r)})),Array:({elements:e},r,n)=>h((function*(){if("sync"===n){const t=[];for(const o of e){const e=yield I(o.value,r,n);if(o.isSplat){if(e.isArray()){const r=yield e.get();t.push(...r)}}else t.push(yield e.get())}return new o(t,"array")}return new t((async function*(){for(const t of e){const e=await I(t.value,r,n);if(t.isSplat){if(e.isArray())for await(const t of e)yield t}else yield e}}))})),Tuple(){throw new Error("tuples can not be evaluated")},Or:({left:e,right:t},r,n)=>h((function*(){const o=yield I(e,r,n),c=yield I(t,r,n);return"boolean"===o.type&&!0===o.data||"boolean"===c.type&&!0===c.data?s:"boolean"!==o.type||"boolean"!==c.type?i:a})),And:({left:e,right:t},r,n)=>h((function*(){const o=yield I(e,r,n),c=yield I(t,r,n);return"boolean"===o.type&&!1===o.data||"boolean"===c.type&&!1===c.data?a:"boolean"!==o.type||"boolean"!==c.type?i:s})),Not:({base:e},t,r)=>h((function*(){const n=yield I(e,t,r);return"boolean"!==n.type?i:n.data?a:s})),Neg:({base:e},t,r)=>h((function*(){const n=yield I(e,t,r);return"number"!==n.type?i:u(-n.data)})),Pos:({base:e},t,r)=>h((function*(){const n=yield I(e,t,r);return"number"!==n.type?i:u(n.data)})),Asc:()=>i,Desc:()=>i,ArrayCoerce:({base:e},t,r)=>h((function*(){const n=yield I(e,t,r);return n.isArray()?n:i})),Map:({base:e,expr:r},n,s)=>h((function*(){const a=yield I(e,n,s);if(!a.isArray())return i;if("sync"===s){const e=yield a.get(),t=[];for(const o of e){const e=f(o,"sync"),i=n.createHidden(e),a=yield I(r,i,s);t.push(yield a.get())}return new o(t,"array")}return new t((async function*(){for await(const e of a){const t=n.createHidden(e);yield await I(r,t,s)}}))})),FlatMap:({base:e,expr:r},n,s)=>h((function*(){const a=yield I(e,n,s);if(!a.isArray())return i;if("sync"===s){const e=yield a.get(),t=[];for(const o of e){const e=f(o,"sync"),i=n.createHidden(e),a=yield I(r,i,s);if(a.isArray()){const e=yield a.get();t.push(...e)}else{const e=yield a.get();t.push(e)}}return new o(t,"array")}return new t((async function*(){for await(const e of a){const t=n.createHidden(e),o=await I(r,t,s);if(o.isArray())for await(const e of o)yield e;else yield o}}))}))};function C(e,t={}){const r=f(t.root,"sync"),n=f(t.dataset,"sync"),o={...t.params},i=new O(o,n,r,function(e={},t){return{timestamp:e.timestamp||new Date,identity:void 0===e.identity?"me":e.identity,sanity:e.sanity,after:e.after?f(e.after,t):null,before:e.before?f(e.before,t):null,dereference:e.dereference}}(t,"sync"),null),s=I(e,i,"sync");if(d(s))throw new Error("Unexpected promise when evaluating. This expression may not support evaluateSync.");return s}function M(e){switch(e.type){case"Group":return M(e.base);case"Value":case"Parameter":return!0;case"Pos":case"Neg":return M(e.base);case"OpCall":switch(e.op){case"+":case"-":case"*":case"/":case"%":case"**":return M(e.left)&&M(e.right);default:return!1}default:return!1}}const T=new O({},i,i,{timestamp:new Date(0),identity:"me",before:null,after:null},null);function P(e){return M(e)?function(e){const t=I(e,T,"sync");if(d(t))throw new Error("BUG: constant evaluate should never return a promise");return t}(e):null}function N(e,t){return h((function*(){if("object"===e.type)return V(e.data);if(e.isArray()){const r=yield U(e,t);if(r.length>0)return r.join("\n\n")}return null}))}function U(e,t){return h((function*(){const r=[],n=yield e.get();for(const e of n){const n=f(e,t);if("object"===n.type){const e=V(n.data);null!==e&&r.push(e)}else if(n.isArray()){const e=yield U(n,t);r.push(...e)}}return r}))}function V(e){if("string"!=typeof e._type)return null;const t=e.children;if(!Array.isArray(t))return null;let r="";for(const e of t)e&&"object"==typeof e&&"string"==typeof e._type&&"span"===e._type&&"string"==typeof e.text&&(r+=e.text);return r}const D=1.2;function F(e,t,r){return h((function*(){if("OpCall"===e.type&&"match"===e.op){return function(e,t){return h((function*(){const r=yield e.get(),n=yield t.get();let o,i=[];if(Array.isArray(r)?i=r.filter((e=>"string"==typeof e)):"string"==typeof r&&(i=[r]),Array.isArray(n)?o=n.filter((e=>"string"==typeof e)):"string"==typeof n&&(o=[n]),!o?.length)return 0;const s=i.flatMap(k),a=o.flatMap(x);if(0===s.length||0===a.length)return 0;let c=0;for(const e of a){const t=s.reduce(((t,r)=>t+(e.test(r)?1:0)),0);c+=2.2*t/(t+D)}return c}))}(yield I(e.left,t,r),yield I(e.right,t,r))}if("FuncCall"===e.type&&"boost"===e.name){const n=yield F(e.args[0],t,r),o=yield I(e.args[1],t,r);return"number"===o.type&&n>0?n+o.data:0}switch(e.type){case"Or":return(yield F(e.left,t,r))+(yield F(e.right,t,r));case"And":{const n=yield F(e.left,t,r),o=yield F(e.right,t,r);return 0===n||0===o?0:n+o}default:{const n=yield I(e,t,r);return"boolean"===n.type&&!0===n.data?1:0}}}))}function R(e,t){switch(y(e)){case"array":for(const r of e)if(R(r,t))return!0;break;case"object":if(e._ref)return t.has(e._ref);for(const r of Object.values(e))if(R(r,t))return!0}return!1}const q={anywhere:function(){throw new Error("not implemented")}};q.anywhere.arity=1,q.coalesce=function(e,t,r){return h((function*(){for(const n of e){const e=yield I(n,t,r);if("null"!==e.type)return e}return i}))},q.count=function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);if(!n.isArray())return i;return u(yield n.reduce((e=>e+1),0))}))},q.count.arity=1,q.dateTime=function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);return"datetime"===n.type?n:"string"!==n.type?i:c.parseToValue(n.data)}))},q.dateTime.arity=1,q.defined=function(e,t,r){return h((function*(){return"null"===(yield I(e[0],t,r)).type?a:s}))},q.defined.arity=1,q.identity=function(e,t){return p(t.context.identity)},q.identity.arity=0,q.length=function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);if("string"===n.type)return u(function(e){let t=0;for(let r=0;r<e.length;r++){const n=e.charCodeAt(r);n>=55296&&n<=56319||t++}return t}(n.data));if(n.isArray()){return u(yield n.reduce((e=>e+1),0))}return i}))},q.length.arity=1,q.path=function(t,r,n){return h((function*(){const s=yield I(t[0],r,n);return"string"!==s.type?i:(a=new e(s.data),new o(a,"path"));var a}))},q.path.arity=1,q.string=function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);switch(n.type){case"number":case"string":case"boolean":case"datetime":return p(`${n.data}`);default:return i}}))},q.string.arity=1,q.references=function(e,t,r){return h((function*(){const n=new Set;for(const o of e){const e=yield I(o,t,r);if("string"===e.type)n.add(e.data);else if(e.isArray()){const t=yield e.get();for(const e of t)"string"==typeof e&&n.add(e)}}if(0===n.size)return a;return R(yield t.value.get(),n)?s:a}))},q.references.arity=e=>e>=1,q.round=function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);if("number"!==n.type)return i;const o=n.data;let s=0;if(2===e.length){const n=yield I(e[1],t,r);if("number"!==n.type||n.data<0||!Number.isInteger(n.data))return i;s=n.data}return u(0===s?o<0?-Math.round(-o):Math.round(o):Number(o.toFixed(s)))}))},q.round.arity=e=>e>=1&&e<=2,q.now=function(e,t){return p(t.context.timestamp.toISOString())},q.now.arity=0,q.boost=function(){throw new Error("unexpected boost call")},q.boost.arity=2;const G={lower:function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);return"string"!==n.type?i:p(n.data.toLowerCase())}))}};G.lower.arity=1,G.upper=function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);return"string"!==n.type?i:p(n.data.toUpperCase())}))},G.upper.arity=1,G.split=function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);if("string"!==n.type)return i;const o=yield I(e[1],t,r);return"string"!==o.type?i:0===n.data.length?f([],r):0===o.data.length?f(Array.from(n.data),r):f(n.data.split(o.data),r)}))},G.split.arity=2,q.lower=G.lower,q.upper=G.upper,G.startsWith=function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);if("string"!==n.type)return i;const o=yield I(e[1],t,r);return"string"!==o.type?i:n.data.startsWith(o.data)?s:a}))},G.startsWith.arity=2;const H={join:function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);if(!n.isArray())return i;const o=yield I(e[1],t,r);if("string"!==o.type)return i;let s="",a=!1;const c=yield n.get();for(const e of c){const t=f(e,r);switch(a&&(s+=o.data),t.type){case"number":case"string":case"boolean":case"datetime":s+=`${t.data}`;break;default:return i}a=!0}return f(s,r)}))}};H.join.arity=2,H.compact=function(e,r,n){return h((function*(){const o=yield I(e[0],r,n);return o.isArray()?new t((async function*(){for await(const e of o)"null"!==e.type&&(yield e)})):i}))},H.compact.arity=1,H.unique=function(e,r,n){return h((function*(){const s=yield I(e[0],r,n);if(!s.isArray())return i;if("sync"===n){const e=yield s.get(),t=new Set,r=[];for(const n of e){const e=f(n,"sync");switch(e.type){case"number":case"string":case"boolean":case"datetime":t.has(n)||(t.add(n),r.push(e));break;default:r.push(e)}}return new o(r,"array")}return new t((async function*(){const e=new Set;for await(const t of s)switch(t.type){case"number":case"string":case"boolean":case"datetime":e.has(t.data)||(e.add(t.data),yield t);break;default:yield t}}))}))},H.unique.arity=1,H.intersects=function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);if(!n.isArray())return i;const o=yield I(e[1],t,r);return o.isArray()?(yield n.first((e=>!!o.first((t=>m(e,t))))))?s:a:i}))},H.intersects.arity=2;const B={text:function(e,t,r){return h((function*(){const n=yield I(e[0],t,r),o=yield N(n,r);return null===o?i:p(o)}))}};B.text.arity=1;const W={projectId:function(e,t){return t.context.sanity?p(t.context.sanity.projectId):i},dataset:function(e,t){return t.context.sanity?p(t.context.sanity.dataset):i},versionsOf:function(e,t,r){return h((function*(){if(!t.source.isArray())return i;const n=yield I(e[0],t,r);if("string"!==n.type)return i;const o=n.data;return f(yield t.source.reduce(((e,t)=>{if("object"===y(t)){const r=t.get();r&&"_id"in r&&2===r._id.split(".").length&&r._id.endsWith(`.${o}`)&&"_version"in r&&"object"==typeof r._version&&e.push(r._id)}return e}),[]),r)}))}};W.versionsOf.arity=1,W.partOfRelease=function(e,t,r){return h((function*(){if(!t.source.isArray())return i;const n=yield I(e[0],t,r);if("string"!==n.type)return i;const o=n.data;return f(yield t.source.reduce(((e,t)=>{if("object"===y(t)){const r=t.get();r&&"_id"in r&&2===r._id.split(".").length&&r._id.startsWith(`${o}.`)&&"_version"in r&&"object"==typeof r._version&&e.push(r._id)}return e}),[]),r)}))},W.partOfRelease.arity=1;const Z={order:function(e,t,r,n){return h((function*(){if(!e.isArray())return i;const o=[],s=[];let a=0;for(let e of t){let t="asc";"Desc"===e.type?(t="desc",e=e.base):"Asc"===e.type&&(e=e.base),o.push(e),s.push(t),a++}const c=[];let u=0;const p=yield e.get();for(const e of p){const t=f(e,n),i=r.createNested(t),s=[yield t.get(),u];for(let e=0;e<a;e++){const t=yield I(o[e],i,n);s.push(yield t.get())}c.push(s),u++}return c.sort(((e,t)=>{for(let r=0;r<a;r++){let n=E(e[r+2],t[r+2]);if("desc"===s[r]&&(n=-n),0!==n)return n}return e[1]-t[1]})),f(c.map((e=>e[0])),n)}))}};Z.order.arity=e=>e>=1,Z.score=function(e,t,r,n){return h((function*(){if(!e.isArray())return i;const o=[],s=[],a=yield e.get();for(const e of a){const i=f(e,n);if("object"!==i.type){o.push(yield i.get());continue}const a=r.createNested(i);let c="number"==typeof i.data._score?i.data._score:0;for(const e of t)c+=(yield F(e,a,n));const u=Object.assign({},i.data,{_score:c});s.push(u)}return s.sort(((e,t)=>t._score-e._score)),f(s,n)}))},Z.score.arity=e=>e>=1;const z={operation:function(e,t){const r=null!==t.context.before,n=null!==t.context.after;return r&&n?p("update"):n?p("create"):r?p("delete"):i},changedAny:()=>{throw new Error("not implemented")}};z.changedAny.arity=1,z.changedAny.mode="delta",z.changedOnly=()=>{throw new Error("not implemented")},z.changedOnly.arity=1,z.changedOnly.mode="delta";const J={changedAny:()=>{throw new Error("not implemented")}};J.changedAny.arity=3,J.changedOnly=()=>{throw new Error("not implemented")},J.changedOnly.arity=3;const Q={min:function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);if(!n.isArray()||(yield n.first((e=>"null"!==e.type&&"number"!==e.type))))return i;const o=yield n.get();let s;for(const e of o)"number"==typeof e&&(void 0===s||e<s)&&(s=e);return f(s,r)}))}};Q.min.arity=1,Q.max=function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);if(!n.isArray()||(yield n.first((e=>"null"!==e.type&&"number"!==e.type))))return i;const o=yield n.get();let s;for(const e of o)"number"==typeof e&&(void 0===s||e>s)&&(s=e);return f(s,r)}))},Q.max.arity=1,Q.sum=function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);if(!n.isArray()||(yield n.first((e=>"null"!==e.type&&"number"!==e.type))))return i;return f(yield n.reduce(((e,t)=>"number"!==t.type?e:e+t.data),0),r)}))},Q.sum.arity=1,Q.avg=function(e,t,r){return h((function*(){const n=yield I(e[0],t,r);if(!n.isArray()||(yield n.first((e=>"null"!==e.type&&"number"!==e.type))))return i;const o=yield n.reduce(((e,t)=>"number"!==t.type?e:e+1),0),s=yield n.reduce(((e,t)=>"number"!==t.type?e:e+t.data),0);return 0===o?i:f(s/o,r)}))},Q.avg.arity=1;const L={now:function(e,t){return l(new c(t.context.timestamp))}};L.now.arity=0;const Y={global:q,string:G,array:H,pt:B,delta:z,diff:J,sanity:W,math:Q,dateTime:L};class K{string;marks;index;parseOptions;allowBoost=!1;constructor(e,t,r){this.string=e,this.marks=t,this.index=0,this.parseOptions=r}hasMark(e=0){return this.index+e<this.marks.length}getMark(e=0){return this.marks[this.index+e]}shift(){this.index+=1}process(e){const t=this.marks[this.index];this.shift();const r=e[t.name];if(!r)throw new Error(`Unknown handler: ${t.name}`);return r.call(e,this,t)}processString(){return this.shift(),this.processStringEnd()}processStringEnd(){const e=this.marks[this.index-1],t=this.marks[this.index];return this.shift(),this.string.slice(e.position,t.position)}slice(e){const t=this.marks[this.index].position;return this.string.slice(t,t+e)}}const X=/^([\t\n\v\f\r \u0085\u00A0]|(\/\/[^\n]*\n))+/,ee=/^\d+/,te=/^[a-zA-Z_][a-zA-Z_0-9]*/;function re(e,t,r){let n,o=t;switch(e[t]){case"+":{let r=re(e,se(e,t+1),10);if("error"===r.type)return r;n=[{name:"pos",position:o}].concat(r.marks),t=r.position;break}case"-":{let r=re(e,se(e,t+1),8);if("error"===r.type)return r;n=[{name:"neg",position:o}].concat(r.marks),t=r.position;break}case"(":{let r=re(e,se(e,t+1),0);if("error"===r.type)return r;switch(e[t=se(e,r.position)]){case",":for(n=[{name:"tuple",position:o}].concat(r.marks),t=se(e,t+1);;){if(r=re(e,t,0),"error"===r.type)return r;if(","!==e[t=se(e,r.position)])break;t=se(e,t+1)}if(")"!==e[t])return{type:"error",position:t};t++,n.push({name:"tuple_end",position:t});break;case")":t++,n=[{name:"group",position:o}].concat(r.marks);break;default:return{type:"error",position:t}}break}case"!":{let r=re(e,se(e,t+1),10);if("error"===r.type)return r;n=[{name:"not",position:o}].concat(r.marks),t=r.position;break}case"{":{let r=ie(e,t);if("error"===r.type)return r;n=r.marks,t=r.position;break}case"[":if(n=[{name:"array",position:t}],"]"!==e[t=se(e,t+1)])for(;;){"..."===e.slice(t,t+3)&&(n.push({name:"array_splat",position:t}),t=se(e,t+3));let r=re(e,t,0);if("error"===r.type)return r;if(n=n.concat(r.marks),","!==e[t=se(e,t=r.position)]||"]"===e[t=se(e,t+1)])break}if("]"!==e[t])return{type:"error",position:t};t++,n.push({name:"array_end",position:t});break;case"'":case'"':{let r=function(e,t){let r=e[t];t+=1;const n=[{name:"str",position:t}];e:for(;;t++){if(t>e.length)return{type:"error",position:t};switch(e[t]){case r:n.push({name:"str_end",position:t}),t++;break e;case"\\":n.push({name:"str_pause",position:t}),"u"===e[t+1]?"{"===e[t+2]?(n.push({name:"unicode_hex",position:t+3}),t=e.indexOf("}",t+3),n.push({name:"unicode_hex_end",position:t})):(n.push({name:"unicode_hex",position:t+2}),n.push({name:"unicode_hex_end",position:t+6}),t+=5):(n.push({name:"single_escape",position:t+1}),t+=1),n.push({name:"str_start",position:t+1})}}return{type:"success",marks:n,position:t}}(e,t);if("error"===r.type)return r;n=r.marks,t=r.position;break}case"^":for(t++,n=[];"."===e[t]&&"^"===e[t+1];)n.push({name:"dblparent",position:o}),t+=2;n.push({name:"parent",position:o});break;case"@":n=[{name:"this",position:o}],t++;break;case"*":n=[{name:"everything",position:o}],t++;break;case"$":{let r=ae(e,t+1,te);r&&(n=[{name:"param",position:o},{name:"ident",position:o+1},{name:"ident_end",position:t+=1+r}]);break}default:{let r=ae(e,t,ee);if(r){let i="integer";if("."===e[t+=r]){let r=ae(e,t+1,ee);r&&(i="float",t+=1+r)}if("e"===e[t]||"E"===e[t]){i="sci",("+"===e[++t]||"-"===e[t])&&t++;let r=ae(e,t,ee);if(!r)return{type:"error",position:t};t+=r}n=[{name:i,position:o},{name:i+"_end",position:t}];break}let i=ae(e,t,te);if(i){switch(e[t+=i]){case":":case"(":{let r=oe(e,o,t);if("error"===r.type)return r;n=r.marks,t=r.position;break}default:n=[{name:"this_attr",position:o},{name:"ident",position:o},{name:"ident_end",position:t}]}break}}}if(!n)return{type:"error",position:t};let i,s=12;e:for(;;){let a=se(e,t);if(a===e.length){t=a;break}if(i=ne(e,a),"success"!==i.type)switch(e[a]){case"=":switch(e[a+1]){case">":{if(r>1||s<=1)break e;let i=re(e,se(e,a+2),1);if("error"===i.type)return i;n=n.concat(i.marks),n.unshift({name:"pair",position:o}),t=i.position,s=1;break}case"=":{if(r>4||s<=4)break e;let i=re(e,se(e,a+2),5);if("error"===i.type)return i;n.unshift({name:"comp",position:o}),n.push({name:"op",position:a},{name:"op_end",position:a+2}),n=n.concat(i.marks),t=i.position,s=4;break}default:break e}break;case"+":{if(r>6||s<6)break e;let i=re(e,se(e,a+1),7);if("error"===i.type)return i;n=n.concat(i.marks),n.unshift({name:"add",position:o}),t=i.position,s=6;break}case"-":{if(r>6||s<6)break e;let i=re(e,se(e,a+1),7);if("error"===i.type)return i;n=n.concat(i.marks),n.unshift({name:"sub",position:o}),t=i.position,s=6;break}case"*":{if("*"===e[a+1]){if(r>8||s<=8)break e;let i=re(e,se(e,a+2),8);if("error"===i.type)return i;n=n.concat(i.marks),n.unshift({name:"pow",position:o}),t=i.position,s=8;break}if(r>7||s<7)break e;let i=re(e,se(e,a+1),8);if("error"===i.type)return i;n=n.concat(i.marks),n.unshift({name:"mul",position:o}),t=i.position,s=7;break}case"/":{if(r>7||s<7)break e;let i=re(e,se(e,a+1),8);if("error"===i.type)return i;n=n.concat(i.marks),n.unshift({name:"div",position:o}),t=i.position,s=7;break}case"%":{if(r>7||s<7)break e;let i=re(e,se(e,a+1),8);if("error"===i.type)return i;n=n.concat(i.marks),n.unshift({name:"mod",position:o}),t=i.position,s=7;break}case"<":case">":{if(r>4||s<=4)break e;let i=a+1;"="===e[i]&&i++;let c=re(e,se(e,i),5);if("error"===c.type)return c;n.unshift({name:"comp",position:o}),n.push({name:"op",position:a},{name:"op_end",position:i}),n=n.concat(c.marks),t=c.position,s=4;break}case"|":if("|"===e[a+1]){if(r>2||s<2)break e;let i=re(e,se(e,a+2),3);if("error"===i.type)return i;n=n.concat(i.marks),n.unshift({name:"or",position:o}),t=i.position,s=2}else{if(r>11||s<11)break e;let i=se(e,a+1),c=ae(e,i,te);if(!c)return{type:"error",position:i};if("("===e[t=i+c]||":"===e[t]){let r=oe(e,i,t);if("error"===r.type)return r;n=n.concat(r.marks),n.unshift({name:"pipecall",position:o}),t=r.position,s=11}}break;case"&":{if("&"!=e[a+1]||r>3||s<3)break e;let i=re(e,se(e,a+2),4);if("error"===i.type)return i;n=n.concat(i.marks),n.unshift({name:"and",position:o}),t=i.position,s=3;break}case"!":{if("="!==e[a+1]||r>4||s<=4)break e;let i=re(e,se(e,a+2),5);if("error"===i.type)return i;n.unshift({name:"comp",position:o}),n.push({name:"op",position:a},{name:"op_end",position:a+2}),n=n.concat(i.marks),t=i.position,s=4;break}case"d":if("desc"!==e.slice(a,a+4)||r>4||s<4)break e;n.unshift({name:"desc",position:o}),t=a+4,s=4;break;case"a":if("asc"!==e.slice(a,a+3)||r>4||s<4)break e;n.unshift({name:"asc",position:o}),t=a+3,s=4;break;default:switch(ce(e,a,te)){case"in":{if(r>4||s<=4)break e;let i=!1;"("===e[t=se(e,a+2)]&&(i=!0,t=se(e,t+1));let c=t,u=re(e,t,5);if("error"===u.type)return u;if("."===e[t=se(e,u.position)]&&"."===e[t+1]){let r="inc_range";"."===e[t+2]?(r="exc_range",t=se(e,t+3)):t=se(e,t+2);let i=re(e,t,5);if("error"===i.type)return i;n.unshift({name:"in_range",position:o}),n=n.concat({name:r,position:c},u.marks,i.marks),t=i.position}else n.unshift({name:"comp",position:o}),n.push({name:"op",position:a},{name:"op_end",position:a+2}),n=n.concat(u.marks);if(i){if(")"!==e[t=se(e,t)])return{type:"error",position:t};t++}s=4;break}case"match":{if(r>4||s<=4)break e;let i=re(e,se(e,a+5),5);if("error"===i.type)return i;n.unshift({name:"comp",position:o}),n.push({name:"op",position:a},{name:"op_end",position:a+5}),n=n.concat(i.marks),t=i.position,s=4;break}default:break e}}else{for(n.unshift({name:"traverse",position:o});"success"===i.type;)n=n.concat(i.marks),i=ne(e,se(e,t=i.position));n.push({name:"traversal_end",position:t})}}return{type:"success",marks:n,position:t,failPosition:"error"===i?.type&&i.position}}function ne(e,t){let r=t;switch(e[t]){case".":{let n=t=se(e,t+1),o=ae(e,t,te);return o?{type:"success",marks:[{name:"attr_access",position:r},{name:"ident",position:n},{name:"ident_end",position:t+=o}],position:t}:{type:"error",position:t}}case"-":if(">"!==e[t+1])return{type:"error",position:t};let n=[{name:"deref",position:r}],o=se(e,t+=2),i=ae(e,o,te);return i&&(t=o+i,n.push({name:"deref_attr",position:o},{name:"ident",position:o},{name:"ident_end",position:t})),{type:"success",marks:n,position:t};case"[":{if("]"===e[t=se(e,t+1)])return{type:"success",marks:[{name:"array_postfix",position:r}],position:t+1};let n=t,o=re(e,t,0);if("error"===o.type)return o;if("."===e[t=se(e,o.position)]&&"."===e[t+1]){let i="inc_range";"."===e[t+2]?(i="exc_range",t+=3):t+=2;let s=re(e,t=se(e,t),0);return"error"===s.type?s:"]"!==e[t=se(e,s.position)]?{type:"error",position:t}:{type:"success",marks:[{name:"slice",position:r},{name:i,position:n}].concat(o.marks,s.marks),position:t+1}}return"]"!==e[t]?{type:"error",position:t}:{type:"success",marks:[{name:"square_bracket",position:r}].concat(o.marks),position:t+1}}case"|":if("{"===e[t=se(e,t+1)]){let n=ie(e,t);return"error"===n.type||n.marks.unshift({name:"projection",position:r}),n}break;case"{":{let n=ie(e,t);return"error"===n.type||n.marks.unshift({name:"projection",position:r}),n}}return{type:"error",position:t}}function oe(e,t,r){let n=[];if(n.push({name:"func_call",position:t}),":"===e[r]&&":"===e[r+1]){n.push({name:"namespace",position:t}),n.push({name:"ident",position:t},{name:"ident_end",position:r});let o=ae(e,r=se(e,r+2),te);if(!o)return{type:"error",position:r};if(n.push({name:"ident",position:r},{name:"ident_end",position:r+o}),"("!==e[r=se(e,r+o)])return{type:"error",position:r};r=se(e,++r)}else n.push({name:"ident",position:t},{name:"ident_end",position:r}),r=se(e,r+1);let o=r;if(")"!==e[r])for(;;){let t=re(e,r,0);if("error"===t.type)return t;if(n=n.concat(t.marks),o=t.position,","!==e[r=se(e,t.position)]||")"===e[r=se(e,r+1)])break}return")"!==e[r]?{type:"error",position:r}:(n.push({name:"func_args_end",position:o}),{type:"success",marks:n,position:r+1})}function ie(e,t){let r=[{name:"object",position:t}];for(t=se(e,t+1);"}"!==e[t];){let n=t;if("..."===e.slice(t,t+3))if("}"!==e[t=se(e,t+3)]&&","!==e[t]){let o=re(e,t,0);if("error"===o.type)return o;r.push({name:"object_splat",position:n}),r=r.concat(o.marks),t=o.position}else r.push({name:"object_splat_this",position:n});else{let o=re(e,t,0);if("error"===o.type)return o;let i=se(e,o.position);if("str"===o.marks[0].name&&":"===e[i]){let s=re(e,se(e,i+1),0);if("error"===s.type)return s;r.push({name:"object_pair",position:n}),r=r.concat(o.marks,s.marks),t=s.position}else r=r.concat({name:"object_expr",position:t},o.marks),t=o.position}if(","!==e[t=se(e,t)])break;t=se(e,t+1)}return"}"!==e[t]?{type:"error",position:t}:(t++,r.push({name:"object_end",position:t}),{type:"success",marks:r,position:t})}function se(e,t){return t+ae(e,t,X)}function ae(e,t,r){let n=r.exec(e.slice(t));return n?n[0].length:0}function ce(e,t,r){let n=r.exec(e.slice(t));return n?n[0]:null}function ue(e,t){return r=>t(e(r))}function pe(e){return t=>({type:"Map",base:t,expr:e({type:"This"})})}function le(e,t){if(!t)return{type:"a-a",build:e};switch(t.type){case"a-a":return{type:"a-a",build:ue(e,t.build)};case"a-b":return{type:"a-b",build:ue(e,t.build)};case"b-b":return{type:"a-a",build:ue(e,pe(t.build))};case"b-a":return{type:"a-a",build:ue(e,(r=t.build,e=>({type:"FlatMap",base:e,expr:r({type:"This"})})))};default:throw new Error(`unknown type: ${t.type}`)}var r}function fe(e,t){if(!t)return{type:"b-b",build:e};switch(t.type){case"a-a":case"b-a":return{type:"b-a",build:ue(e,t.build)};case"a-b":case"b-b":return{type:"b-b",build:ue(e,t.build)};default:throw new Error(`unknown type: ${t.type}`)}}const ye={"'":"'",'"':'"',"\\":"\\","/":"/",b:"\b",f:"\f",n:"\n",r:"\r",t:"\t"};function de(e){const t=parseInt(e,16);return String.fromCharCode(t)}class he extends Error{name="GroqQueryError"}const me={group:e=>({type:"Group",base:e.process(me)}),everything:()=>({type:"Everything"}),this:()=>({type:"This"}),parent:()=>({type:"Parent",n:1}),dblparent:e=>({type:"Parent",n:e.process(me).n+1}),traverse(e){const t=e.process(me),r=[];for(;"traversal_end"!==e.getMark().name;)r.push(e.process(ge));e.shift();let n=null;for(let e=r.length-1;e>=0;e--)n=r[e](n);if(("Everything"===t.type||"Array"===t.type||"PipeFuncCall"===t.type)&&(n=le((e=>e),n)),null===n)throw new Error("BUG: unexpected empty traversal");return n.build(t)},this_attr(e){const t=e.processString();return"null"===t?{type:"Value",value:null}:"true"===t?{type:"Value",value:!0}:"false"===t?{type:"Value",value:!1}:{type:"AccessAttribute",name:t}},neg:e=>({type:"Neg",base:e.process(me)}),pos:e=>({type:"Pos",base:e.process(me)}),add:e=>({type:"OpCall",op:"+",left:e.process(me),right:e.process(me)}),sub:e=>({type:"OpCall",op:"-",left:e.process(me),right:e.process(me)}),mul:e=>({type:"OpCall",op:"*",left:e.process(me),right:e.process(me)}),div:e=>({type:"OpCall",op:"/",left:e.process(me),right:e.process(me)}),mod:e=>({type:"OpCall",op:"%",left:e.process(me),right:e.process(me)}),pow:e=>({type:"OpCall",op:"**",left:e.process(me),right:e.process(me)}),comp(e){const t=e.process(me);return{type:"OpCall",op:e.processString(),left:t,right:e.process(me)}},in_range(e){const t=e.process(me),r="inc_range"===e.getMark().name;e.shift();return{type:"InRange",base:t,left:e.process(me),right:e.process(me),isInclusive:r}},str(e){let t="";e:for(;e.hasMark();){const r=e.getMark();switch(r.name){case"str_end":t+=e.processStringEnd();break e;case"str_pause":t+=e.processStringEnd();break;case"str_start":e.shift();break;case"single_escape":{const r=e.slice(1);e.shift(),t+=ye[r];break}case"unicode_hex":e.shift(),t+=de(e.processStringEnd());break;default:throw new Error(`unexpected mark: ${r.name}`)}}return{type:"Value",value:t}},integer(e){const t=e.processStringEnd();return{type:"Value",value:Number(t)}},float(e){const t=e.processStringEnd();return{type:"Value",value:Number(t)}},sci(e){const t=e.processStringEnd();return{type:"Value",value:Number(t)}},object(e){const t=[];for(;"object_end"!==e.getMark().name;)t.push(e.process(be));return e.shift(),{type:"Object",attributes:t}},array(e){const t=[];for(;"array_end"!==e.getMark().name;){let r=!1;"array_splat"===e.getMark().name&&(r=!0,e.shift());const n=e.process(me);t.push({type:"ArrayElement",value:n,isSplat:r})}return e.shift(),{type:"Array",elements:t}},tuple(e){const t=[];for(;"tuple_end"!==e.getMark().name;)t.push(e.process(me));return e.shift(),{type:"Tuple",members:t}},func_call(e){let t="global";"namespace"===e.getMark().name&&(e.shift(),t=e.processString());const r=e.processString();if("global"===t&&"select"===r){const t={type:"Select",alternatives:[]};for(;"func_args_end"!==e.getMark().name;)if("pair"===e.getMark().name){if(t.fallback)throw new he("unexpected argument to select()");e.shift();const r=e.process(me),n=e.process(me);t.alternatives.push({type:"SelectAlternative",condition:r,value:n})}else{if(t.fallback)throw new he("unexpected argument to select()");const r=e.process(me);t.fallback=r}return e.shift(),t}const n=[];for(;"func_args_end"!==e.getMark().name;)xe(t,r,n.length)?(e.process(we),n.push({type:"Selector"})):n.push(e.process(me));if(e.shift(),"global"===t&&("before"===r||"after"===r)&&"delta"===e.parseOptions.mode)return{type:"Context",key:r};if("global"===t&&"boost"===r&&!e.allowBoost)throw new he("unexpected boost");const o=Y[t];if(!o)throw new he(`Undefined namespace: ${t}`);const i=o[r];if(!i)throw new he(`Undefined function: ${r}`);if(void 0!==i.arity&&ve(r,i.arity,n.length),void 0!==i.mode&&i.mode!==e.parseOptions.mode)throw new he(`Undefined function: ${r}`);return{type:"FuncCall",func:i,namespace:t,name:r,args:n}},pipecall(e){const t=e.process(me);e.shift();let r="global";if("namespace"===e.getMark().name&&(e.shift(),r=e.processString()),"global"!==r)throw new he(`Undefined namespace: ${r}`);const n=e.processString(),o=[],i=e.allowBoost;for("score"===n&&(e.allowBoost=!0);;){const t=e.getMark().name;if("func_args_end"===t)break;if("order"===n){if("asc"===t){e.shift(),o.push({type:"Asc",base:e.process(me)});continue}if("desc"===t){e.shift(),o.push({type:"Desc",base:e.process(me)});continue}}o.push(e.process(me))}e.shift(),e.allowBoost=i;const s=Z[n];if(!s)throw new he(`Undefined pipe function: ${n}`);return s.arity&&ve(n,s.arity,o.length),{type:"PipeFuncCall",func:s,base:t,name:n,args:o}},pair(){throw new he("unexpected =>")},and:e=>({type:"And",left:e.process(me),right:e.process(me)}),or:e=>({type:"Or",left:e.process(me),right:e.process(me)}),not:e=>({type:"Not",base:e.process(me)}),asc(){throw new he("unexpected asc")},desc(){throw new he("unexpected desc")},param(e){const t=e.processString();return e.parseOptions.params&&e.parseOptions.params.hasOwnProperty(t)?{type:"Value",value:e.parseOptions.params[t]}:{type:"Parameter",name:t}}},be={object_expr(e){if("pair"===e.getMark().name){e.shift();return{type:"ObjectConditionalSplat",condition:e.process(me),value:e.process(me)}}const t=e.process(me);return{type:"ObjectAttributeValue",name:ke(t),value:t}},object_pair(e){const t=e.process(me);if("Value"!==t.type)throw new Error("name must be string");const r=e.process(me);return{type:"ObjectAttributeValue",name:t.value,value:r}},object_splat:e=>({type:"ObjectSplat",value:e.process(me)}),object_splat_this:()=>({type:"ObjectSplat",value:{type:"This"}})},ge={square_bracket(e){const t=e.process(me),r=P(t);return r&&"number"===r.type?e=>function(e,t){if(!t)return{type:"a-b",build:e};switch(t.type){case"a-a":case"b-a":return{type:"a-a",build:ue(e,t.build)};case"a-b":case"b-b":return{type:"a-b",build:ue(e,t.build)};default:throw new Error(`unknown type: ${t.type}`)}}((e=>({type:"AccessElement",base:e,index:r.data})),e):r&&"string"===r.type?e=>fe((e=>({type:"AccessAttribute",base:e,name:r.data})),e):e=>le((e=>({type:"Filter",base:e,expr:t})),e)},slice(e){const t="inc_range"===e.getMark().name;e.shift();const r=e.process(me),n=e.process(me),o=P(r),i=P(n);if(!o||!i||"number"!==o.type||"number"!==i.type)throw new he("slicing must use constant numbers");return e=>le((e=>({type:"Slice",base:e,left:o.data,right:i.data,isInclusive:t})),e)},projection(e){const t=e.process(me);return e=>function(e,t){if(!t)return{type:"b-b",build:e};switch(t.type){case"a-a":return{type:"a-a",build:ue(pe(e),t.build)};case"a-b":return{type:"a-b",build:ue(pe(e),t.build)};case"b-a":return{type:"b-a",build:ue(e,t.build)};case"b-b":return{type:"b-b",build:ue(e,t.build)};default:throw new Error(`unknown type: ${t.type}`)}}((e=>({type:"Projection",base:e,expr:t})),e)},attr_access(e){const t=e.processString();return e=>fe((e=>({type:"AccessAttribute",base:e,name:t})),e)},deref(e){let t=null;"deref_attr"===e.getMark().name&&(e.shift(),t=e.processString());return e=>fe((e=>(e=>t?{type:"AccessAttribute",base:e,name:t}:e)({type:"Deref",base:e})),e)},array_postfix:()=>e=>le((e=>({type:"ArrayCoerce",base:e})),e)},we={group:e=>(e.process(we),null),everything(){throw new Error("Invalid selector syntax")},this(){throw new Error("Invalid selector syntax")},parent(){throw new Error("Invalid selector syntax")},dblparent(){throw new Error("Invalid selector syntax")},traverse(e){for(e.process(we);"traversal_end"!==e.getMark().name;)e.process(ge);return e.shift(),null},this_attr:e=>(e.processString(),null),neg(){throw new Error("Invalid selector syntax")},pos(){throw new Error("Invalid selector syntax")},add(){throw new Error("Invalid selector syntax")},sub(){throw new Error("Invalid selector syntax")},mul(){throw new Error("Invalid selector syntax")},div(){throw new Error("Invalid selector syntax")},mod(){throw new Error("Invalid selector syntax")},pow(){throw new Error("Invalid selector syntax")},comp(){throw new Error("Invalid selector syntax")},in_range(){throw new Error("Invalid selector syntax")},str(){throw new Error("Invalid selector syntax")},integer(){throw new Error("Invalid selector syntax")},float(){throw new Error("Invalid selector syntax")},sci(){throw new Error("Invalid selector syntax")},object(){throw new Error("Invalid selector syntax")},array(){throw new Error("Invalid selector syntax")},tuple(){throw new Error("Invalid selector syntax")},func_call(e,t){const r=me.func_call(e,t);if("anywhere"===r.name&&1===r.args.length)return null;throw new Error("Invalid selector syntax")},pipecall(){throw new Error("Invalid selector syntax")},pair(){throw new Error("Invalid selector syntax")},and(){throw new Error("Invalid selector syntax")},or(){throw new Error("Invalid selector syntax")},not(){throw new Error("Invalid selector syntax")},asc(){throw new Error("Invalid selector syntax")},desc(){throw new Error("Invalid selector syntax")},param(){throw new Error("Invalid selector syntax")}};function ke(e){if("AccessAttribute"===e.type&&!e.base)return e.name;if("PipeFuncCall"===e.type||"Deref"===e.type||"Map"===e.type||"Projection"===e.type||"Slice"===e.type||"Filter"===e.type||"AccessElement"===e.type||"ArrayCoerce"===e.type||"Group"===e.type)return ke(e.base);throw new he(`Cannot determine property key for type: ${e.type}`)}function ve(e,t,r){if("number"==typeof t){if(r!==t)throw new he(`Incorrect number of arguments to function ${e}(). Expected ${t}, got ${r}.`)}else if(t&&!t(r))throw new he(`Incorrect number of arguments to function ${e}().`)}function xe(e,t,r){return"diff"==e&&2==r&&["changedAny","changedOnly"].includes(t)}class _e extends Error{position;name="GroqSyntaxError";constructor(e){super(`Syntax error in GROQ query at position ${e}`),this.position=e}}function Ae(e,t={}){const r=function(e){let t=0;t=se(e,t);let r=re(e,t,0);return"error"===r.type?r:(t=se(e,r.position),t!==e.length?(r.failPosition&&(t=r.failPosition-1),{type:"error",position:t}):(delete r.position,delete r.failPosition,r))}(e);if("error"===r.type)throw new _e(r.position);return new K(e,r.marks,t).process(me)}export{C as evaluateSync,Ae as parse};
@@ -22,7 +22,5 @@ import {createStateSourceHook} from '../helpers/createStateSourceHook'
22
22
  * return <div>Current auth state: {authState}</div>
23
23
  * }
24
24
  * ```
25
- *
26
- * @public
27
25
  */
28
26
  export const useAuthState: () => AuthState = createStateSourceHook(getAuthState)
@@ -2,26 +2,33 @@ import {type CurrentUser, getCurrentUserState} from '@sanity/sdk'
2
2
 
3
3
  import {createStateSourceHook} from '../helpers/createStateSourceHook'
4
4
 
5
+ type UseCurrentUser = {
6
+ /**
7
+ * @public
8
+ *
9
+ * Provides the currently authenticated user’s profile information.
10
+ *
11
+ * @category Users
12
+ * @returns The current user data
13
+ *
14
+ * @example Rendering a basic user profile
15
+ * ```
16
+ * const user = useCurrentUser()
17
+ *
18
+ * return (
19
+ * <figure>
20
+ * <img src={user?.profileImage} alt=`Profile image for ${user?.name}` />
21
+ * <h2>{user?.name}</h2>
22
+ * </figure>
23
+ * )
24
+ * ```
25
+ */
26
+ (): CurrentUser | null
27
+ }
28
+
5
29
  /**
6
- * @TODO This should suspend! And possibly not return `null`?
7
- *
8
30
  * @public
9
- *
10
- * The `useCurrentUser` hook returns the currently authenticated user’s profile information (their name, email, roles, etc).
11
- * If no users are currently logged in, the hook returns null.
12
- *
13
- * @returns The current user data, or `null` if not authenticated
14
- *
15
- * @example Rendering a basic user profile
16
- * ```
17
- * const user = useCurrentUser()
18
- *
19
- * return (
20
- * <figure>
21
- * <img src={user?.profileImage} alt=`Profile image for ${user?.name}` />
22
- * <h2>{user?.name}</h2>
23
- * </figure>
24
- * )
25
- * ```
31
+ * @function
32
+ * @TODO This should not return null users of a custom app will always be authenticated via Core
26
33
  */
27
- export const useCurrentUser: () => CurrentUser | null = createStateSourceHook(getCurrentUserState)
34
+ export const useCurrentUser: UseCurrentUser = createStateSourceHook(getCurrentUserState)
@@ -0,0 +1,42 @@
1
+ import {createSanityInstance, getDashboardOrganizationId} from '@sanity/sdk'
2
+ import {renderHook} from '@testing-library/react'
3
+ import {throwError} from 'rxjs'
4
+ import {describe, expect, it, vi} from 'vitest'
5
+
6
+ import {useDashboardOrganizationId} from './useDashboardOrganizationId'
7
+
8
+ vi.mock('../context/useSanityInstance', () => ({
9
+ useSanityInstance: vi.fn().mockReturnValue(createSanityInstance({projectId: 'p', dataset: 'd'})),
10
+ }))
11
+
12
+ vi.mock('@sanity/sdk', async (importOriginal) => {
13
+ const actual = await importOriginal()
14
+ return {...(actual || {}), getDashboardOrganizationId: vi.fn()}
15
+ })
16
+
17
+ describe('useDashboardOrganizationId', () => {
18
+ it('should return undefined when no organization ID is set', () => {
19
+ const subscribe = vi.fn()
20
+ vi.mocked(getDashboardOrganizationId).mockReturnValue({
21
+ getCurrent: () => undefined,
22
+ subscribe,
23
+ observable: throwError(() => new Error('Unexpected usage of observable')),
24
+ })
25
+
26
+ const {result} = renderHook(() => useDashboardOrganizationId())
27
+ expect(result.current).toBeUndefined()
28
+ })
29
+
30
+ it('should return organization ID when one is set', () => {
31
+ const subscribe = vi.fn()
32
+ const mockOrgId = 'team_123'
33
+ vi.mocked(getDashboardOrganizationId).mockReturnValue({
34
+ getCurrent: () => mockOrgId,
35
+ subscribe,
36
+ observable: throwError(() => new Error('Unexpected usage of observable')),
37
+ })
38
+
39
+ const {result} = renderHook(() => useDashboardOrganizationId())
40
+ expect(result.current).toBe(mockOrgId)
41
+ })
42
+ })
@@ -0,0 +1,29 @@
1
+ import {getDashboardOrganizationId} from '@sanity/sdk'
2
+ import {useMemo, useSyncExternalStore} from 'react'
3
+
4
+ import {useSanityInstance} from '../context/useSanityInstance'
5
+
6
+ /**
7
+ * @remarks
8
+ * A React hook that retrieves the dashboard organization ID that is currently selected in the Sanity Dashboard.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * function DashboardComponent() {
13
+ * const orgId = useDashboardOrganizationId()
14
+ *
15
+ * if (!orgId) return null
16
+ *
17
+ * return <div>Organization ID: {String(orgId)}</div>
18
+ * }
19
+ * ```
20
+ *
21
+ * @returns The dashboard organization ID (string | undefined)
22
+ * @public
23
+ */
24
+ export function useDashboardOrganizationId(): string | undefined {
25
+ const instance = useSanityInstance()
26
+ const {subscribe, getCurrent} = useMemo(() => getDashboardOrganizationId(instance), [instance])
27
+
28
+ return useSyncExternalStore(subscribe, getCurrent)
29
+ }
@@ -0,0 +1,16 @@
1
+ import {handleAuthCallback} from '@sanity/sdk'
2
+ import {identity} from 'rxjs'
3
+ import {describe, it} from 'vitest'
4
+
5
+ import {createCallbackHook} from '../helpers/createCallbackHook'
6
+
7
+ vi.mock('../helpers/createCallbackHook', () => ({createCallbackHook: vi.fn(identity)}))
8
+ vi.mock('@sanity/sdk', () => ({handleAuthCallback: vi.fn()}))
9
+
10
+ describe('useHandleAuthCallback', () => {
11
+ it('calls `createCallbackHook` with `handleAuthCallback`', async () => {
12
+ const {useHandleAuthCallback} = await import('./useHandleAuthCallback')
13
+ expect(createCallbackHook).toHaveBeenCalledWith(handleAuthCallback)
14
+ expect(useHandleAuthCallback).toBe(handleAuthCallback)
15
+ })
16
+ })
@@ -1,4 +1,4 @@
1
- import {handleCallback} from '@sanity/sdk'
1
+ import {handleAuthCallback} from '@sanity/sdk'
2
2
 
3
3
  import {createCallbackHook} from '../helpers/createCallbackHook'
4
4
 
@@ -10,7 +10,7 @@ import {createCallbackHook} from '../helpers/createCallbackHook'
10
10
  * This hook provides access to the authentication store's callback handler,
11
11
  * which processes auth redirects by extracting the session ID and fetching the
12
12
  * authentication token. If fetching the long-lived token is successful,
13
- * `handleCallback` will return a Promise that resolves a new location that
13
+ * `handleAuthCallback` will return a Promise that resolves a new location that
14
14
  * removes the short-lived token from the URL. Use this in combination with
15
15
  * `history.replaceState` or your own router's `replace` function to update the
16
16
  * current location without triggering a reload.
@@ -18,13 +18,13 @@ import {createCallbackHook} from '../helpers/createCallbackHook'
18
18
  * @example
19
19
  * ```tsx
20
20
  * function AuthCallback() {
21
- * const handleCallback = useHandleCallback()
21
+ * const handleAuthCallback = useHandleAuthCallback()
22
22
  * const router = useRouter() // Example router
23
23
  *
24
24
  * useEffect(() => {
25
25
  * async function processCallback() {
26
26
  * // Handle the callback and get the cleaned URL
27
- * const newUrl = await handleCallback(window.location.href)
27
+ * const newUrl = await handleAuthCallback(window.location.href)
28
28
  *
29
29
  * if (newUrl) {
30
30
  * // Replace URL without triggering navigation
@@ -33,7 +33,7 @@ import {createCallbackHook} from '../helpers/createCallbackHook'
33
33
  * }
34
34
  *
35
35
  * processCallback().catch(console.error)
36
- * }, [handleCallback, router])
36
+ * }, [handleAuthCallback, router])
37
37
  *
38
38
  * return <div>Completing login...</div>
39
39
  * }
@@ -42,4 +42,4 @@ import {createCallbackHook} from '../helpers/createCallbackHook'
42
42
  * @returns A callback handler function that processes OAuth redirects
43
43
  * @public
44
44
  */
45
- export const useHandleCallback = createCallbackHook(handleCallback)
45
+ export const useHandleAuthCallback = createCallbackHook(handleAuthCallback)
@@ -7,8 +7,8 @@ import {createCallbackHook} from '../helpers/createCallbackHook'
7
7
  vi.mock('../helpers/createCallbackHook', () => ({createCallbackHook: vi.fn(identity)}))
8
8
  vi.mock('@sanity/sdk', () => ({logout: vi.fn()}))
9
9
 
10
- describe('useHandleCallback', () => {
11
- it('calls `createCallbackHook` with `handleCallback`', async () => {
10
+ describe('useLogOut', () => {
11
+ it('calls `createCallbackHook` with `logout`', async () => {
12
12
  const {useLogOut} = await import('./useLogOut')
13
13
  expect(createCallbackHook).toHaveBeenCalledWith(logout)
14
14
  expect(useLogOut).toBe(logout)
@@ -1,8 +1,6 @@
1
- import {type SanityClient} from '@sanity/client'
2
- import {type ClientOptions, getClient, getSubscribableClient} from '@sanity/sdk'
3
- import {useCallback, useSyncExternalStore} from 'react'
1
+ import {getClientState} from '@sanity/sdk'
4
2
 
5
- import {useSanityInstance} from '../context/useSanityInstance'
3
+ import {createStateSourceHook} from '../helpers/createStateSourceHook'
6
4
 
7
5
  /**
8
6
  * A React hook that provides a client that subscribes to changes in your application,
@@ -12,12 +10,13 @@ import {useSanityInstance} from '../context/useSanityInstance'
12
10
  * The hook uses `useSyncExternalStore` to safely subscribe to changes
13
11
  * and ensure consistency between server and client rendering.
14
12
  *
13
+ * @category Platform
15
14
  * @returns A Sanity client
16
15
  *
17
16
  * @example
18
17
  * ```tsx
19
18
  * function MyComponent() {
20
- * const client = useClient()
19
+ * const client = useClient({apiVersion: '2024-11-12'})
21
20
  * const [document, setDocument] = useState(null)
22
21
  * useEffect(async () => {
23
22
  * const doc = client.fetch('*[_id == "myDocumentId"]')
@@ -28,29 +27,9 @@ import {useSanityInstance} from '../context/useSanityInstance'
28
27
  * ```
29
28
  *
30
29
  * @public
30
+ * @function
31
31
  */
32
- export function useClient(options: ClientOptions): SanityClient {
33
- const instance = useSanityInstance()
34
-
35
- const subscribe = useCallback(
36
- (onStoreChange: () => void) => {
37
- const client$ = getSubscribableClient(instance, options)
38
- const subscription = client$.subscribe({
39
- next: onStoreChange,
40
- error: (error) => {
41
- // @TODO: We should tackle error handling / error boundaries soon
42
- // eslint-disable-next-line no-console
43
- console.error('Error in useClient subscription:', error)
44
- },
45
- })
46
- return () => subscription.unsubscribe()
47
- },
48
- [instance, options],
49
- )
50
-
51
- const getSnapshot = useCallback(() => {
52
- return getClient(instance, options)
53
- }, [instance, options])
54
-
55
- return useSyncExternalStore(subscribe, getSnapshot)
56
- }
32
+ export const useClient = createStateSourceHook({
33
+ getState: getClientState,
34
+ getResourceId: (e) => e.resourceId,
35
+ })