@sanity/sdk 3.0.0-rc.1 → 3.0.0-rc.2
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 +12 -0
- package/dist/_exports/_internal.d.ts +71 -3
- package/dist/_exports/_internal.d.ts.map +1 -1
- package/dist/_exports/_internal.js +332 -24
- package/dist/_exports/_internal.js.map +1 -1
- package/dist/_exports/agent.d.ts +65 -0
- package/dist/_exports/agent.d.ts.map +1 -0
- package/dist/_exports/agent.js +71 -0
- package/dist/_exports/agent.js.map +1 -0
- package/dist/_exports/comlink.d.ts +118 -0
- package/dist/_exports/comlink.d.ts.map +1 -0
- package/dist/_exports/comlink.js +69 -0
- package/dist/_exports/comlink.js.map +1 -0
- package/dist/authStore-CtE9bLHW.js +754 -0
- package/dist/authStore-CtE9bLHW.js.map +1 -0
- package/dist/authStore-DKFX8fn7.d.ts +3179 -0
- package/dist/authStore-DKFX8fn7.d.ts.map +1 -0
- package/dist/clientStore-BtE2-q2i.js +90 -0
- package/dist/clientStore-BtE2-q2i.js.map +1 -0
- package/dist/createSanityInstance-DUI1bGIg.d.ts +278 -0
- package/dist/createSanityInstance-DUI1bGIg.d.ts.map +1 -0
- package/dist/createStateSourceAction-BOKtqFNm.js +300 -0
- package/dist/createStateSourceAction-BOKtqFNm.js.map +1 -0
- package/dist/getEnv-D5RGkQLu.js +8 -0
- package/dist/getEnv-D5RGkQLu.js.map +1 -0
- package/dist/getNodeState-CR3__B2D.js +67 -0
- package/dist/getNodeState-CR3__B2D.js.map +1 -0
- package/dist/index.d.ts +3 -2335
- package/dist/index.js +4048 -3874
- package/dist/index.js.map +1 -1
- package/dist/logger-DAtJb5RQ.js +173 -0
- package/dist/logger-DAtJb5RQ.js.map +1 -0
- package/dist/object-CxXlSVg7.js +83 -0
- package/dist/object-CxXlSVg7.js.map +1 -0
- package/dist/queryStore-DPf9sN3V.js +1346 -0
- package/dist/queryStore-DPf9sN3V.js.map +1 -0
- package/dist/rolldown-runtime-vyAXikos.js +9 -0
- package/dist/setCleanupTimeout-BiM6q1KF.js +31 -0
- package/dist/setCleanupTimeout-BiM6q1KF.js.map +1 -0
- package/dist/telemetryManager-Dq_qCkeI.js +127 -0
- package/dist/telemetryManager-Dq_qCkeI.js.map +1 -0
- package/dist/version-BChjsi4u.js +9 -0
- package/dist/version-BChjsi4u.js.map +1 -0
- package/package.json +13 -19
- package/src/_exports/_internal.ts +1 -0
- package/src/_exports/agent.ts +19 -0
- package/src/_exports/comlink.ts +16 -0
- package/src/_exports/index.ts +38 -86
- package/src/applications/applications.test-d.ts +5 -0
- package/src/applications/applications.ts +5 -2
- package/src/auth/authMode.test.ts +0 -25
- package/src/auth/authMode.ts +3 -6
- package/src/auth/authStore.test.ts +1 -1
- package/src/auth/authStore.ts +0 -1
- package/src/comments/addonDatasetStore.test.ts +215 -0
- package/src/comments/addonDatasetStore.ts +249 -0
- package/src/comments/buildCommentThreads.test.ts +83 -0
- package/src/comments/buildCommentThreads.ts +54 -0
- package/src/comments/commentActions.test.ts +540 -0
- package/src/comments/commentActions.ts +555 -0
- package/src/comments/commentFieldPath.test.ts +40 -0
- package/src/comments/commentFieldPath.ts +44 -0
- package/src/comments/commentsConstants.ts +80 -0
- package/src/comments/commentsStore.test.ts +419 -0
- package/src/comments/commentsStore.ts +483 -0
- package/src/comments/normalizeComment.test.ts +116 -0
- package/src/comments/normalizeComment.ts +45 -0
- package/src/comments/observeComments.test.ts +193 -0
- package/src/comments/observeComments.ts +113 -0
- package/src/comments/reducers.test.ts +277 -0
- package/src/comments/reducers.ts +316 -0
- package/src/comments/types.ts +249 -0
- package/src/comments/weakenReferences.test.ts +47 -0
- package/src/comments/weakenReferences.ts +29 -0
- package/src/config/sanityConfig.ts +3 -75
- package/src/document/applyDocumentActions.test.ts +8 -12
- package/src/document/documentConstants.ts +8 -0
- package/src/document/documentStore.test.ts +104 -19
- package/src/document/documentStore.ts +36 -5
- package/src/document/patchOperations.test.ts +27 -0
- package/src/document/patchOperations.ts +10 -1
- package/src/document/permissions.test.ts +3 -1
- package/src/document/reducers.test.ts +133 -0
- package/src/document/reducers.ts +18 -3
- package/src/document/util.test.ts +46 -0
- package/src/document/util.ts +37 -1
- package/src/installations/installations.test-d.ts +5 -0
- package/src/installations/installations.ts +4 -0
- package/src/presence/bifurTransport.test.ts +155 -3
- package/src/presence/bifurTransport.ts +79 -12
- package/src/presence/paths.test.ts +70 -0
- package/src/presence/paths.ts +41 -0
- package/src/presence/presenceStore.test.ts +822 -2
- package/src/presence/presenceStore.ts +518 -102
- package/src/presence/types.ts +175 -3
- package/src/preview/types.ts +0 -25
- package/src/projection/projectionStore.test.ts +0 -8
- package/src/projection/types.ts +0 -8
- package/src/query/queryStore.ts +7 -6
- package/src/store/createActionBinder.test.ts +51 -29
- package/src/store/createActionBinder.ts +16 -62
- package/src/store/createSanityInstance.test.ts +0 -68
- package/src/store/createSanityInstance.ts +0 -63
- package/src/store/createStateSourceAction.ts +1 -1
- package/src/users/reducers.test.ts +0 -3
- package/dist/_chunks-dts/createGroqSearchFilter.d.ts +0 -1147
- package/dist/_chunks-dts/createGroqSearchFilter.d.ts.map +0 -1
- package/dist/_chunks-es/_internal.js +0 -134
- package/dist/_chunks-es/_internal.js.map +0 -1
- package/dist/_chunks-es/createGroqSearchFilter.js +0 -1864
- package/dist/_chunks-es/createGroqSearchFilter.js.map +0 -1
- package/dist/_chunks-es/telemetryManager.js +0 -93
- package/dist/_chunks-es/telemetryManager.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/src/applications/userApplications.test.ts +0 -126
- package/src/applications/userApplications.ts +0 -261
- package/src/preview/getPreviewState.test.ts +0 -137
- package/src/preview/getPreviewState.ts +0 -69
- package/src/preview/resolvePreview.test.ts +0 -64
- package/src/preview/resolvePreview.ts +0 -43
|
@@ -0,0 +1,754 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-vyAXikos.js";
|
|
2
|
+
import { a as defineStore, i as bindActionGlobally, t as createStateSourceAction } from "./createStateSourceAction-BOKtqFNm.js";
|
|
3
|
+
import { n as createLogger } from "./logger-DAtJb5RQ.js";
|
|
4
|
+
import { createClient } from "@sanity/client";
|
|
5
|
+
import { EMPTY, Observable, catchError, defer, distinctUntilChanged, exhaustMap, filter, fromEvent, map, switchMap, takeWhile, timer } from "rxjs";
|
|
6
|
+
import "@sanity/types";
|
|
7
|
+
/**
|
|
8
|
+
* Returns the staging API host if the `__SANITY_STAGING__` build-time flag is
|
|
9
|
+
* set to `true` (mirroring how Sanity Studio detects staging builds).
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
function getStagingApiHost() {
|
|
14
|
+
if (typeof __SANITY_STAGING__ < "u" && __SANITY_STAGING__ === !0) return "https://api.sanity.work";
|
|
15
|
+
}
|
|
16
|
+
const loggers = /* @__PURE__ */ new WeakMap();
|
|
17
|
+
/**
|
|
18
|
+
* Returns the auth logger for a Sanity instance, creating it on first use.
|
|
19
|
+
*
|
|
20
|
+
* The logger is cached per instance so repeated action calls (logout,
|
|
21
|
+
* setAuthToken, handleAuthCallback) reuse the same logger instead of
|
|
22
|
+
* rebuilding it. The instance details are nested under `instanceContext`,
|
|
23
|
+
* which is what the logger's formatter reads to render the
|
|
24
|
+
* `[project:x] [dataset:y] [instance:z]` prefix.
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
function getAuthLogger(instance) {
|
|
29
|
+
let logger = loggers.get(instance);
|
|
30
|
+
return logger || (logger = createLogger("auth", { instanceContext: {
|
|
31
|
+
instanceId: instance.instanceId,
|
|
32
|
+
projectId: instance.config.projectId,
|
|
33
|
+
dataset: instance.config.dataset
|
|
34
|
+
} }), loggers.set(instance, logger)), logger;
|
|
35
|
+
}
|
|
36
|
+
const DEFAULT_BASE = "http://localhost", DEFAULT_API_VERSION = "2021-06-07", REQUEST_TAG_PREFIX = "sanity.sdk.auth";
|
|
37
|
+
/**
|
|
38
|
+
* Determines the auth mode from instance config and environment.
|
|
39
|
+
*
|
|
40
|
+
* Priority:
|
|
41
|
+
* 1. `studio` config provided → `'studio'`
|
|
42
|
+
* 2. Dashboard context detected (`_context` URL param with content) → `'dashboard'`
|
|
43
|
+
* 3. Otherwise → `'standalone'`
|
|
44
|
+
*
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
function resolveAuthMode(config, locationHref) {
|
|
48
|
+
return isStudioConfig(config) ? "studio" : detectDashboardContext(locationHref) ? "dashboard" : "standalone";
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Returns `true` when the config indicates the SDK is running inside a Studio.
|
|
52
|
+
*
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
function isStudioConfig(config) {
|
|
56
|
+
return !!config.studio;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Checks whether the given location href contains a `_context` URL parameter
|
|
60
|
+
* with a non-empty JSON object, indicating the SDK is running inside the
|
|
61
|
+
* Sanity Dashboard.
|
|
62
|
+
*
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
function detectDashboardContext(locationHref) {
|
|
66
|
+
try {
|
|
67
|
+
let contextParam = new URL(locationHref, DEFAULT_BASE).searchParams.get("_context");
|
|
68
|
+
if (!contextParam) return !1;
|
|
69
|
+
let parsed = JSON.parse(contextParam);
|
|
70
|
+
return typeof parsed == "object" && !!parsed && !Array.isArray(parsed) && Object.keys(parsed).length > 0;
|
|
71
|
+
} catch (err) {
|
|
72
|
+
return console.error("Failed to parse dashboard context from initial location:", err), !1;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Represents the various states the authentication type can be in.
|
|
77
|
+
*
|
|
78
|
+
* @public
|
|
79
|
+
*/
|
|
80
|
+
let AuthStateType = /* @__PURE__ */ function(AuthStateType) {
|
|
81
|
+
return AuthStateType.LOGGED_IN = "logged-in", AuthStateType.LOGGING_IN = "logging-in", AuthStateType.ERROR = "error", AuthStateType.LOGGED_OUT = "logged-out", AuthStateType;
|
|
82
|
+
}({});
|
|
83
|
+
const REFRESH_INTERVAL = 432e5;
|
|
84
|
+
function createTokenRefreshStream(token, clientFactory, apiHost) {
|
|
85
|
+
return new Observable((subscriber) => {
|
|
86
|
+
let subscription = clientFactory({
|
|
87
|
+
apiVersion: DEFAULT_API_VERSION,
|
|
88
|
+
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
89
|
+
useProjectHostname: !1,
|
|
90
|
+
useCdn: !1,
|
|
91
|
+
token,
|
|
92
|
+
ignoreBrowserTokenWarning: !0,
|
|
93
|
+
...apiHost && { apiHost }
|
|
94
|
+
}).observable.request({
|
|
95
|
+
uri: "auth/refresh-token",
|
|
96
|
+
method: "POST",
|
|
97
|
+
tag: "refresh-token",
|
|
98
|
+
body: { token }
|
|
99
|
+
}).subscribe(subscriber);
|
|
100
|
+
return () => subscription.unsubscribe();
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function shouldRefreshToken(lastRefresh) {
|
|
104
|
+
return !lastRefresh || Date.now() - lastRefresh >= REFRESH_INTERVAL;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Periodically refreshes stamped auth tokens (those containing `-st`).
|
|
108
|
+
*
|
|
109
|
+
* Two triggers cause a refresh while the user stays logged in:
|
|
110
|
+
* - a 12-hour interval timer (only fires while the tab is visible)
|
|
111
|
+
* - the tab becoming visible again after `lastTokenRefresh` has gone stale
|
|
112
|
+
*
|
|
113
|
+
* Non-stamped tokens (e.g. personal access tokens) are never refreshed.
|
|
114
|
+
*
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
117
|
+
const refreshStampedToken = ({ state, instance }) => {
|
|
118
|
+
let logger = getAuthLogger(instance), { clientFactory, apiHost, storageArea, storageKey } = state.get().options;
|
|
119
|
+
return state.observable.pipe(map((storeState) => storeState.authState), filter((authState) => authState.type === "logged-in"), distinctUntilChanged((prev, curr) => prev.token === curr.token), filter((authState) => authState.token.includes("-st")), exhaustMap(() => new Observable((subscriber) => {
|
|
120
|
+
let visibilityHandler = () => {
|
|
121
|
+
let currentState = state.get();
|
|
122
|
+
document.visibilityState === "visible" && currentState.authState.type === "logged-in" && shouldRefreshToken(currentState.authState.lastTokenRefresh) && createTokenRefreshStream(currentState.authState.token, clientFactory, apiHost).subscribe({
|
|
123
|
+
next: (response) => {
|
|
124
|
+
state.set("setRefreshStampedToken", (prev) => ({ authState: prev.authState.type === "logged-in" ? {
|
|
125
|
+
...prev.authState,
|
|
126
|
+
token: response.token,
|
|
127
|
+
lastTokenRefresh: Date.now()
|
|
128
|
+
} : prev.authState })), subscriber.next(response);
|
|
129
|
+
},
|
|
130
|
+
error: (error) => subscriber.error(error)
|
|
131
|
+
});
|
|
132
|
+
}, timerSubscription = timer(REFRESH_INTERVAL, REFRESH_INTERVAL).pipe(filter(() => document.visibilityState === "visible"), switchMap(() => {
|
|
133
|
+
let currentState = state.get().authState;
|
|
134
|
+
if (currentState.type !== "logged-in") throw Error("User logged out before refresh could complete");
|
|
135
|
+
return createTokenRefreshStream(currentState.token, clientFactory, apiHost);
|
|
136
|
+
})).subscribe({
|
|
137
|
+
next: (response) => {
|
|
138
|
+
state.set("setRefreshStampedToken", (prev) => ({ authState: prev.authState.type === "logged-in" ? {
|
|
139
|
+
...prev.authState,
|
|
140
|
+
token: response.token,
|
|
141
|
+
lastTokenRefresh: Date.now()
|
|
142
|
+
} : prev.authState })), subscriber.next(response);
|
|
143
|
+
},
|
|
144
|
+
error: (error) => subscriber.error(error)
|
|
145
|
+
});
|
|
146
|
+
return document.addEventListener("visibilitychange", visibilityHandler), () => {
|
|
147
|
+
document.removeEventListener("visibilitychange", visibilityHandler), timerSubscription.unsubscribe();
|
|
148
|
+
};
|
|
149
|
+
}).pipe(takeWhile(() => state.get().authState.type === "logged-in"), map((response) => ({ token: response.token }))))).subscribe({
|
|
150
|
+
next: (response) => {
|
|
151
|
+
logger.debug("Token refresh completed, updating state"), state.set("setRefreshStampedToken", (prev) => ({ authState: prev.authState.type === "logged-in" ? {
|
|
152
|
+
...prev.authState,
|
|
153
|
+
token: response.token,
|
|
154
|
+
lastTokenRefresh: Date.now()
|
|
155
|
+
} : prev.authState })), storageArea?.setItem(storageKey, JSON.stringify({ token: response.token }));
|
|
156
|
+
},
|
|
157
|
+
error: (error) => {
|
|
158
|
+
logger.error("Token refresh failed", { error }), state.set("setRefreshStampedTokenError", { authState: {
|
|
159
|
+
type: "error",
|
|
160
|
+
error
|
|
161
|
+
} });
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}, subscribeToStateAndFetchCurrentUser = ({ state, instance }, fetchOptions) => {
|
|
165
|
+
let logger = getAuthLogger(instance), { clientFactory, apiHost } = state.get().options, useProjectHostname = fetchOptions?.useProjectHostname ?? isStudioConfig(instance.config), projectId = instance.config.projectId;
|
|
166
|
+
return state.observable.pipe(map(({ authState, options: storeOptions }) => ({
|
|
167
|
+
authState,
|
|
168
|
+
authMethod: storeOptions.authMethod
|
|
169
|
+
})), filter((value) => value.authState.type === "logged-in" && !value.authState.currentUser), map((value) => ({
|
|
170
|
+
token: value.authState.token,
|
|
171
|
+
authMethod: value.authMethod
|
|
172
|
+
})), distinctUntilChanged((prev, curr) => prev.token === curr.token && prev.authMethod === curr.authMethod)).pipe(map(({ token, authMethod }) => clientFactory({
|
|
173
|
+
apiVersion: DEFAULT_API_VERSION,
|
|
174
|
+
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
175
|
+
token: authMethod === "cookie" ? void 0 : token,
|
|
176
|
+
ignoreBrowserTokenWarning: !0,
|
|
177
|
+
useProjectHostname,
|
|
178
|
+
useCdn: !1,
|
|
179
|
+
...authMethod === "cookie" ? { withCredentials: !0 } : {},
|
|
180
|
+
...useProjectHostname && projectId ? { projectId } : {},
|
|
181
|
+
...apiHost && { apiHost }
|
|
182
|
+
})), switchMap((client) => client.observable.request({
|
|
183
|
+
uri: "/users/me",
|
|
184
|
+
method: "GET",
|
|
185
|
+
tag: "users.get-current"
|
|
186
|
+
}).pipe(
|
|
187
|
+
/**
|
|
188
|
+
* Catch inside switchMap so the outer subscription survives.
|
|
189
|
+
* Without this, a 401 terminates the subscription permanently
|
|
190
|
+
* and subsequent token refreshes via comlink never re-fetch /users/me.
|
|
191
|
+
* @see SDK-1409
|
|
192
|
+
*/
|
|
193
|
+
catchError((error) => (logger.error("Failed to fetch current user", { error }), state.set("setError", { authState: {
|
|
194
|
+
type: "error",
|
|
195
|
+
error
|
|
196
|
+
} }), EMPTY))
|
|
197
|
+
))).subscribe({ next: (currentUser) => {
|
|
198
|
+
logger.info("Current user fetched successfully", { hasEmail: !!currentUser.email }), logger.debug("Current user details", { userId: currentUser.id }), state.set("setCurrentUser", (prev) => ({ authState: prev.authState.type === "logged-in" ? {
|
|
199
|
+
...prev.authState,
|
|
200
|
+
currentUser
|
|
201
|
+
} : prev.authState }));
|
|
202
|
+
} });
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* Creates a properly initialized {@link LoggedInAuthState}.
|
|
206
|
+
*
|
|
207
|
+
* For stamped tokens (containing `"-st"`), `lastTokenRefresh` is set to
|
|
208
|
+
* `Date.now()` so that the visibility-change handler in
|
|
209
|
+
* {@link refreshStampedToken} does not trigger an unnecessary refresh the
|
|
210
|
+
* first time the tab becomes visible.
|
|
211
|
+
*
|
|
212
|
+
* @param token - The auth token.
|
|
213
|
+
* @param currentUser - The current user, or `null` if not yet fetched.
|
|
214
|
+
* @param existingLastTokenRefresh - An existing timestamp to preserve
|
|
215
|
+
* (e.g. when updating a token while keeping the previous refresh time).
|
|
216
|
+
* @internal
|
|
217
|
+
*/
|
|
218
|
+
function createLoggedInAuthState(token, currentUser, existingLastTokenRefresh) {
|
|
219
|
+
let isStampedToken = token.includes("-st"), lastTokenRefresh = existingLastTokenRefresh ?? (isStampedToken ? Date.now() : void 0);
|
|
220
|
+
return {
|
|
221
|
+
type: "logged-in",
|
|
222
|
+
token,
|
|
223
|
+
currentUser,
|
|
224
|
+
...lastTokenRefresh !== void 0 && { lastTokenRefresh }
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
function getAuthCode(callbackUrl, locationHref) {
|
|
228
|
+
let loc = new URL(locationHref, DEFAULT_BASE), callbackLocation = callbackUrl ? new URL(callbackUrl, DEFAULT_BASE) : void 0, callbackLocationMatches = !callbackLocation || loc.pathname.toLowerCase().startsWith(callbackLocation.pathname.toLowerCase()), authCode = new URLSearchParams(loc.hash.slice(1)).get("sid") || new URLSearchParams(loc.search).get("sid");
|
|
229
|
+
if (!authCode) {
|
|
230
|
+
let contextParam = new URLSearchParams(loc.search).get("_context");
|
|
231
|
+
if (contextParam) try {
|
|
232
|
+
let parsedContext = JSON.parse(contextParam);
|
|
233
|
+
parsedContext && typeof parsedContext == "object" && typeof parsedContext.sid == "string" && parsedContext.sid && (authCode = parsedContext.sid);
|
|
234
|
+
} catch {}
|
|
235
|
+
}
|
|
236
|
+
return authCode && callbackLocationMatches ? authCode : null;
|
|
237
|
+
}
|
|
238
|
+
function getTokenFromLocation(locationHref) {
|
|
239
|
+
let loc = new URL(locationHref);
|
|
240
|
+
return new URLSearchParams(loc.hash.slice(1)).get("token") || null;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Attempts to retrieve a token from the configured storage.
|
|
244
|
+
* If invalid or not present, returns null.
|
|
245
|
+
*/
|
|
246
|
+
function getTokenFromStorage(storageArea, storageKey) {
|
|
247
|
+
if (!storageArea) return null;
|
|
248
|
+
let item = storageArea.getItem(storageKey);
|
|
249
|
+
if (item === null) return null;
|
|
250
|
+
try {
|
|
251
|
+
let parsed = JSON.parse(item);
|
|
252
|
+
if (typeof parsed != "object" || !parsed || !("token" in parsed) || typeof parsed.token != "string") throw Error("Invalid stored auth data structure");
|
|
253
|
+
return parsed.token;
|
|
254
|
+
} catch {
|
|
255
|
+
return storageArea.removeItem(storageKey), null;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Creates an observable stream of storage events. If not in a browser environment,
|
|
260
|
+
* returns an EMPTY observable.
|
|
261
|
+
*/
|
|
262
|
+
function getStorageEvents() {
|
|
263
|
+
return typeof window < "u" && typeof window.addEventListener == "function" ? fromEvent(window, "storage") : EMPTY;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Returns a default storage instance (localStorage) if available.
|
|
267
|
+
* If not available or an error occurs, returns undefined.
|
|
268
|
+
*/
|
|
269
|
+
function getDefaultStorage() {
|
|
270
|
+
try {
|
|
271
|
+
return typeof localStorage < "u" && typeof localStorage.getItem == "function" ? localStorage : void 0;
|
|
272
|
+
} catch {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Returns the default location to use.
|
|
278
|
+
* Tries accessing `location.href`, falls back to a default base if not available or on error.
|
|
279
|
+
*/
|
|
280
|
+
function getDefaultLocation() {
|
|
281
|
+
try {
|
|
282
|
+
return typeof location > "u" ? DEFAULT_BASE : typeof location.href == "string" ? location.href : DEFAULT_BASE;
|
|
283
|
+
} catch {
|
|
284
|
+
return DEFAULT_BASE;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Cleans up the URL by removing the `token` from the hash and the `sid` and `url` search params.
|
|
289
|
+
* @internal
|
|
290
|
+
*/
|
|
291
|
+
function getCleanedUrl(locationUrl) {
|
|
292
|
+
let loc = new URL(locationUrl), rawHash = loc.hash.startsWith("#") ? loc.hash.slice(1) : loc.hash;
|
|
293
|
+
if (rawHash && rawHash.includes("=")) {
|
|
294
|
+
let hashParams = new URLSearchParams(rawHash);
|
|
295
|
+
hashParams.delete("token"), hashParams.delete("withSid");
|
|
296
|
+
let nextHash = hashParams.toString();
|
|
297
|
+
loc.hash = nextHash ? `#${nextHash}` : "";
|
|
298
|
+
}
|
|
299
|
+
return loc.searchParams.delete("sid"), loc.searchParams.delete("url"), loc.toString();
|
|
300
|
+
}
|
|
301
|
+
/** @internal Extracts the structured API error body from a ClientError, if present. */
|
|
302
|
+
function getClientErrorApiBody(error) {
|
|
303
|
+
let body = error.response?.body;
|
|
304
|
+
return body && typeof body == "object" ? body : void 0;
|
|
305
|
+
}
|
|
306
|
+
/** @internal Returns the error type string from an API error body, if available. */
|
|
307
|
+
function getClientErrorApiType(error) {
|
|
308
|
+
let body = getClientErrorApiBody(error);
|
|
309
|
+
return body?.error?.type ?? body?.type;
|
|
310
|
+
}
|
|
311
|
+
/** @internal Returns the error description string from an API error body, if available. */
|
|
312
|
+
function getClientErrorApiDescription(error) {
|
|
313
|
+
let body = getClientErrorApiBody(error);
|
|
314
|
+
return body?.error?.description ?? body?.description;
|
|
315
|
+
}
|
|
316
|
+
/** @internal True if the error represents a projectUserNotFoundError. */
|
|
317
|
+
function isProjectUserNotFoundClientError(error) {
|
|
318
|
+
return getClientErrorApiType(error) === "projectUserNotFoundError";
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Parses the dashboard context from a location href's `_context` URL parameter.
|
|
322
|
+
* Strips the `sid` property from the parsed context (it's handled separately).
|
|
323
|
+
*
|
|
324
|
+
* @internal
|
|
325
|
+
*/
|
|
326
|
+
function parseDashboardContext(locationHref) {
|
|
327
|
+
try {
|
|
328
|
+
let contextParam = new URL(locationHref, DEFAULT_BASE).searchParams.get("_context");
|
|
329
|
+
if (contextParam) {
|
|
330
|
+
let parsedContext = JSON.parse(contextParam);
|
|
331
|
+
if (parsedContext && typeof parsedContext == "object" && !Array.isArray(parsedContext) && Object.keys(parsedContext).length > 0) return delete parsedContext.sid, parsedContext;
|
|
332
|
+
}
|
|
333
|
+
} catch (err) {
|
|
334
|
+
console.error("Failed to parse dashboard context from initial location:", err);
|
|
335
|
+
}
|
|
336
|
+
return {};
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Resolves the initial auth state for Dashboard mode.
|
|
340
|
+
*
|
|
341
|
+
* In dashboard mode the token is provided by the parent frame via Comlink,
|
|
342
|
+
* so the SDK starts in a `LOGGED_OUT` state and waits for the token to arrive.
|
|
343
|
+
* The `_context` URL parameter provides dashboard metadata (orgId, mode, env).
|
|
344
|
+
*
|
|
345
|
+
* A provided token (`auth.token`) or an auth code/callback still takes
|
|
346
|
+
* precedence, even when running inside the dashboard.
|
|
347
|
+
*
|
|
348
|
+
* @internal
|
|
349
|
+
*/
|
|
350
|
+
function getDashboardInitialState(options) {
|
|
351
|
+
let { authConfig, initialLocationHref } = options, providedToken = authConfig.token, callbackUrl = authConfig.callbackUrl, storageKey = "__sanity_auth_token", dashboardContext = parseDashboardContext(initialLocationHref);
|
|
352
|
+
return providedToken ? {
|
|
353
|
+
authState: createLoggedInAuthState(providedToken, null),
|
|
354
|
+
storageKey,
|
|
355
|
+
storageArea: void 0,
|
|
356
|
+
authMethod: void 0,
|
|
357
|
+
dashboardContext
|
|
358
|
+
} : getAuthCode(callbackUrl, initialLocationHref) || getTokenFromLocation(initialLocationHref) ? {
|
|
359
|
+
authState: {
|
|
360
|
+
type: "logging-in",
|
|
361
|
+
isExchangingToken: !1
|
|
362
|
+
},
|
|
363
|
+
storageKey,
|
|
364
|
+
storageArea: void 0,
|
|
365
|
+
authMethod: void 0,
|
|
366
|
+
dashboardContext
|
|
367
|
+
} : {
|
|
368
|
+
authState: {
|
|
369
|
+
type: "logged-out",
|
|
370
|
+
isDestroyingSession: !1
|
|
371
|
+
},
|
|
372
|
+
storageKey,
|
|
373
|
+
storageArea: void 0,
|
|
374
|
+
authMethod: void 0,
|
|
375
|
+
dashboardContext
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Initialize Dashboard auth subscriptions:
|
|
380
|
+
* - Subscribe to state changes and fetch current user
|
|
381
|
+
* - Start stamped token refresh
|
|
382
|
+
*
|
|
383
|
+
* Note: storage events are NOT subscribed in dashboard mode since
|
|
384
|
+
* the dashboard does not use localStorage for token persistence.
|
|
385
|
+
*
|
|
386
|
+
* @internal
|
|
387
|
+
*/
|
|
388
|
+
function initializeDashboardAuth(context, tokenRefresherRunning) {
|
|
389
|
+
let subscriptions = [], startedRefresher = !1;
|
|
390
|
+
return subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !1 })), tokenRefresherRunning || (startedRefresher = !0, subscriptions.push(refreshStampedToken(context))), {
|
|
391
|
+
dispose: () => {
|
|
392
|
+
for (let subscription of subscriptions) subscription.unsubscribe();
|
|
393
|
+
},
|
|
394
|
+
tokenRefresherStarted: startedRefresher
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
const subscribeToStorageEventsAndSetToken = ({ state }) => {
|
|
398
|
+
let { storageArea, storageKey } = state.get().options;
|
|
399
|
+
return defer(getStorageEvents).pipe(filter((e) => e.storageArea === storageArea && e.key === storageKey), map(() => getTokenFromStorage(storageArea, storageKey)), distinctUntilChanged()).subscribe((token) => {
|
|
400
|
+
state.set("updateTokenFromStorageEvent", { authState: token ? createLoggedInAuthState(token, null) : {
|
|
401
|
+
type: "logged-out",
|
|
402
|
+
isDestroyingSession: !1
|
|
403
|
+
} });
|
|
404
|
+
});
|
|
405
|
+
};
|
|
406
|
+
/**
|
|
407
|
+
* Resolves the initial auth state for Standalone mode.
|
|
408
|
+
*
|
|
409
|
+
* Token discovery order:
|
|
410
|
+
* 1. Provided token (`auth.token` in config)
|
|
411
|
+
* 2. Auth code or token from location (OAuth callback)
|
|
412
|
+
* 3. localStorage: `__sanity_auth_token`
|
|
413
|
+
* 4. Falls back to `LOGGED_OUT`
|
|
414
|
+
*
|
|
415
|
+
* @internal
|
|
416
|
+
*/
|
|
417
|
+
function getStandaloneInitialState(options) {
|
|
418
|
+
let { authConfig, initialLocationHref } = options, providedToken = authConfig.token, callbackUrl = authConfig.callbackUrl, storageKey = "__sanity_auth_token", storageArea = authConfig.storageArea ?? getDefaultStorage();
|
|
419
|
+
if (providedToken) return {
|
|
420
|
+
authState: createLoggedInAuthState(providedToken, null),
|
|
421
|
+
storageKey,
|
|
422
|
+
storageArea,
|
|
423
|
+
authMethod: void 0,
|
|
424
|
+
dashboardContext: {}
|
|
425
|
+
};
|
|
426
|
+
if (getAuthCode(callbackUrl, initialLocationHref) || getTokenFromLocation(initialLocationHref)) return {
|
|
427
|
+
authState: {
|
|
428
|
+
type: "logging-in",
|
|
429
|
+
isExchangingToken: !1
|
|
430
|
+
},
|
|
431
|
+
storageKey,
|
|
432
|
+
storageArea,
|
|
433
|
+
authMethod: void 0,
|
|
434
|
+
dashboardContext: {}
|
|
435
|
+
};
|
|
436
|
+
let token = getTokenFromStorage(storageArea, storageKey);
|
|
437
|
+
return token ? {
|
|
438
|
+
authState: createLoggedInAuthState(token, null),
|
|
439
|
+
storageKey,
|
|
440
|
+
storageArea,
|
|
441
|
+
authMethod: "localstorage",
|
|
442
|
+
dashboardContext: {}
|
|
443
|
+
} : {
|
|
444
|
+
authState: {
|
|
445
|
+
type: "logged-out",
|
|
446
|
+
isDestroyingSession: !1
|
|
447
|
+
},
|
|
448
|
+
storageKey,
|
|
449
|
+
storageArea,
|
|
450
|
+
authMethod: void 0,
|
|
451
|
+
dashboardContext: {}
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Initialize Standalone auth subscriptions:
|
|
456
|
+
* - Subscribe to state changes and fetch current user
|
|
457
|
+
* - Subscribe to storage events for token key
|
|
458
|
+
* - Start stamped token refresh
|
|
459
|
+
*
|
|
460
|
+
* @internal
|
|
461
|
+
*/
|
|
462
|
+
function initializeStandaloneAuth(context, tokenRefresherRunning) {
|
|
463
|
+
let subscriptions = [], startedRefresher = !1;
|
|
464
|
+
return subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !1 })), context.state.get().options?.storageArea && subscriptions.push(subscribeToStorageEventsAndSetToken(context)), tokenRefresherRunning || (startedRefresher = !0, subscriptions.push(refreshStampedToken(context))), {
|
|
465
|
+
dispose: () => {
|
|
466
|
+
for (let subscription of subscriptions) subscription.unsubscribe();
|
|
467
|
+
},
|
|
468
|
+
tokenRefresherStarted: startedRefresher
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Attempts to check for cookie auth by making a withCredentials request to the users endpoint.
|
|
473
|
+
* @param projectId - The project ID to check for cookie auth.
|
|
474
|
+
* @param clientFactory - A factory function that creates a Sanity client.
|
|
475
|
+
* @returns True if the user is authenticated, false otherwise.
|
|
476
|
+
* @internal
|
|
477
|
+
*/
|
|
478
|
+
async function checkForCookieAuth(projectId, clientFactory) {
|
|
479
|
+
if (!projectId) return !1;
|
|
480
|
+
try {
|
|
481
|
+
let user = await clientFactory({
|
|
482
|
+
projectId,
|
|
483
|
+
useCdn: !1,
|
|
484
|
+
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
485
|
+
timeout: 1e4
|
|
486
|
+
}).request({
|
|
487
|
+
uri: "/users/me",
|
|
488
|
+
withCredentials: !0,
|
|
489
|
+
tag: "users.get-current"
|
|
490
|
+
});
|
|
491
|
+
return typeof user == "object" && !!user && typeof user.id == "string";
|
|
492
|
+
} catch {
|
|
493
|
+
return !1;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Attempts to retrieve a studio token from local storage.
|
|
498
|
+
* @param storageArea - The storage area to retrieve the token from.
|
|
499
|
+
* @param storageKey - The storage key to retrieve the token from.
|
|
500
|
+
* @returns The studio token or null if it does not exist.
|
|
501
|
+
* @internal
|
|
502
|
+
*/
|
|
503
|
+
function getStudioTokenFromLocalStorage(storageArea, storageKey) {
|
|
504
|
+
return !storageArea || !storageKey ? null : getTokenFromStorage(storageArea, storageKey) || null;
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Resolves the initial auth state for Studio mode.
|
|
508
|
+
*
|
|
509
|
+
* When a `tokenSource` is provided (via `config.studio.auth.token`), the
|
|
510
|
+
* initial state is `LOGGING_IN` — the actual token arrives asynchronously
|
|
511
|
+
* via the subscription set up in `initializeStudioAuth`.
|
|
512
|
+
*
|
|
513
|
+
* Fallback token discovery order (no tokenSource):
|
|
514
|
+
* 1. Provided token (`auth.token` in config)
|
|
515
|
+
* 2. localStorage: `__studio_auth_token_${projectId}`
|
|
516
|
+
* 3. Falls back to `LOGGED_OUT` (cookie auth is checked async in `initializeStudioAuth`)
|
|
517
|
+
*
|
|
518
|
+
* @internal
|
|
519
|
+
*/
|
|
520
|
+
function getStudioInitialState(options) {
|
|
521
|
+
let { authConfig, projectId, tokenSource } = options, storageArea = authConfig.storageArea ?? getDefaultStorage(), studioStorageKey = `__studio_auth_token_${projectId ?? ""}`;
|
|
522
|
+
if (tokenSource) return {
|
|
523
|
+
authState: {
|
|
524
|
+
type: "logging-in",
|
|
525
|
+
isExchangingToken: !1
|
|
526
|
+
},
|
|
527
|
+
storageKey: studioStorageKey,
|
|
528
|
+
storageArea,
|
|
529
|
+
authMethod: void 0,
|
|
530
|
+
dashboardContext: {}
|
|
531
|
+
};
|
|
532
|
+
let providedToken = authConfig.token, authMethod, token = getStudioTokenFromLocalStorage(storageArea, studioStorageKey);
|
|
533
|
+
return token && (authMethod = "localstorage"), providedToken ? {
|
|
534
|
+
authState: createLoggedInAuthState(providedToken, null),
|
|
535
|
+
storageKey: studioStorageKey,
|
|
536
|
+
storageArea,
|
|
537
|
+
authMethod,
|
|
538
|
+
dashboardContext: {}
|
|
539
|
+
} : token ? {
|
|
540
|
+
authState: createLoggedInAuthState(token, null),
|
|
541
|
+
storageKey: studioStorageKey,
|
|
542
|
+
storageArea,
|
|
543
|
+
authMethod: "localstorage",
|
|
544
|
+
dashboardContext: {}
|
|
545
|
+
} : {
|
|
546
|
+
authState: {
|
|
547
|
+
type: "logged-out",
|
|
548
|
+
isDestroyingSession: !1
|
|
549
|
+
},
|
|
550
|
+
storageKey: studioStorageKey,
|
|
551
|
+
storageArea,
|
|
552
|
+
authMethod: void 0,
|
|
553
|
+
dashboardContext: {}
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Initialize Studio auth subscriptions.
|
|
558
|
+
*
|
|
559
|
+
* When a `tokenSource` is available (reactive path), subscribes to it for
|
|
560
|
+
* ongoing token sync. The Studio is the token authority — no independent
|
|
561
|
+
* token refresh or cookie auth probing is needed.
|
|
562
|
+
*
|
|
563
|
+
* Fallback path (no tokenSource):
|
|
564
|
+
* - Subscribe to state changes and fetch current user
|
|
565
|
+
* - Subscribe to storage events for studio token key
|
|
566
|
+
* - Check for cookie auth asynchronously if no token was found
|
|
567
|
+
* - Start stamped token refresh
|
|
568
|
+
*
|
|
569
|
+
* @internal
|
|
570
|
+
*/
|
|
571
|
+
function initializeStudioAuth(context, tokenRefresherRunning) {
|
|
572
|
+
let tokenSource = context.instance.config.studio?.auth?.token;
|
|
573
|
+
return tokenSource ? initializeWithTokenSource(context, tokenSource) : initializeWithFallback(context, tokenRefresherRunning);
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Subscribe to a reactive token source from the Studio workspace.
|
|
577
|
+
*
|
|
578
|
+
* When the token source emits a non-null token, the SDK uses it directly.
|
|
579
|
+
* When it emits `null`, the behavior depends on the `authenticated` flag
|
|
580
|
+
* from the Studio's workspace config:
|
|
581
|
+
*
|
|
582
|
+
* - `authenticated: true` — the Studio has already verified the user is
|
|
583
|
+
* logged in (e.g. via cookie auth). The SDK treats the null token as
|
|
584
|
+
* cookie-based auth and stays in the LOGGED_IN state.
|
|
585
|
+
*
|
|
586
|
+
* - `authenticated` absent/false — the user is genuinely not authenticated;
|
|
587
|
+
* transition to LOGGED_OUT.
|
|
588
|
+
*
|
|
589
|
+
* No async cookie probing is needed here because this code path only runs
|
|
590
|
+
* when a Studio provides SDKStudioContext, and the Studio's Workspace type
|
|
591
|
+
* always includes `authenticated`. The async `checkForCookieAuth` fallback
|
|
592
|
+
* remains in `initializeWithFallback` for the non-Studio path.
|
|
593
|
+
*/
|
|
594
|
+
function initializeWithTokenSource(context, tokenSource) {
|
|
595
|
+
let subscriptions = [], studioAuthenticated = context.instance.config.studio?.authenticated === !0;
|
|
596
|
+
subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !0 }));
|
|
597
|
+
let tokenSub = tokenSource.subscribe({ next: (token) => {
|
|
598
|
+
let { state } = context;
|
|
599
|
+
token ? state.set("studioTokenSource", (prev) => ({
|
|
600
|
+
options: {
|
|
601
|
+
...prev.options,
|
|
602
|
+
authMethod: void 0
|
|
603
|
+
},
|
|
604
|
+
authState: createLoggedInAuthState(token, null)
|
|
605
|
+
})) : studioAuthenticated ? state.set("studioTokenSourceCookieAuth", (prev) => ({
|
|
606
|
+
options: {
|
|
607
|
+
...prev.options,
|
|
608
|
+
authMethod: "cookie"
|
|
609
|
+
},
|
|
610
|
+
authState: prev.authState.type === "logged-in" ? prev.authState : createLoggedInAuthState("", null)
|
|
611
|
+
})) : state.set("studioTokenSourceLoggedOut", (prev) => ({
|
|
612
|
+
options: {
|
|
613
|
+
...prev.options,
|
|
614
|
+
authMethod: void 0
|
|
615
|
+
},
|
|
616
|
+
authState: {
|
|
617
|
+
type: "logged-out",
|
|
618
|
+
isDestroyingSession: !1
|
|
619
|
+
}
|
|
620
|
+
}));
|
|
621
|
+
} });
|
|
622
|
+
return {
|
|
623
|
+
dispose: () => {
|
|
624
|
+
tokenSub.unsubscribe();
|
|
625
|
+
for (let subscription of subscriptions) subscription.unsubscribe();
|
|
626
|
+
},
|
|
627
|
+
tokenRefresherStarted: !1
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Fallback initialization when no reactive token source is available.
|
|
632
|
+
* Uses localStorage/cookie discovery (existing behavior).
|
|
633
|
+
*/
|
|
634
|
+
function initializeWithFallback(context, tokenRefresherRunning) {
|
|
635
|
+
let subscriptions = [], startedRefresher = !1;
|
|
636
|
+
subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !0 })), context.state.get().options?.storageArea && subscriptions.push(subscribeToStorageEventsAndSetToken(context));
|
|
637
|
+
try {
|
|
638
|
+
let { instance, state } = context;
|
|
639
|
+
if (!(state.get().authState?.type === "logged-in" && state.get().authState.token)) {
|
|
640
|
+
let projectIdValue = instance.config.projectId, clientFactory = state.get().options.clientFactory;
|
|
641
|
+
checkForCookieAuth(projectIdValue, clientFactory).then((isCookieAuthEnabled) => {
|
|
642
|
+
isCookieAuthEnabled && state.set("enableCookieAuth", (prev) => ({
|
|
643
|
+
options: {
|
|
644
|
+
...prev.options,
|
|
645
|
+
authMethod: "cookie"
|
|
646
|
+
},
|
|
647
|
+
authState: prev.authState.type === "logged-in" ? prev.authState : createLoggedInAuthState("", null)
|
|
648
|
+
}));
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
} catch {}
|
|
652
|
+
return tokenRefresherRunning || (startedRefresher = !0, subscriptions.push(refreshStampedToken(context))), {
|
|
653
|
+
dispose: () => {
|
|
654
|
+
for (let subscription of subscriptions) subscription.unsubscribe();
|
|
655
|
+
},
|
|
656
|
+
tokenRefresherStarted: startedRefresher
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
var authStore_exports = /* @__PURE__ */ __exportAll({
|
|
660
|
+
authStore: () => authStore,
|
|
661
|
+
getAuthMethodState: () => getAuthMethodState,
|
|
662
|
+
getAuthState: () => getAuthState,
|
|
663
|
+
getCurrentUserState: () => getCurrentUserState,
|
|
664
|
+
getDashboardOrganizationId: () => getDashboardOrganizationId,
|
|
665
|
+
getIsInDashboardState: () => getIsInDashboardState,
|
|
666
|
+
getLoginUrlState: () => getLoginUrlState,
|
|
667
|
+
getTokenState: () => getTokenState,
|
|
668
|
+
setAuthToken: () => setAuthToken
|
|
669
|
+
});
|
|
670
|
+
let tokenRefresherRunning = !1;
|
|
671
|
+
const authStore = defineStore({
|
|
672
|
+
name: "Auth",
|
|
673
|
+
getInitialState(instance) {
|
|
674
|
+
let logger = getAuthLogger(instance);
|
|
675
|
+
logger.debug("Initializing auth store", {
|
|
676
|
+
hasProvidedToken: !!instance.config.auth?.token,
|
|
677
|
+
hasCustomProviders: !!(instance.config.auth?.providers && instance.config.auth.providers.length > 0)
|
|
678
|
+
});
|
|
679
|
+
let { apiHost: configApiHost, callbackUrl, providers: customProviders, token: providedToken, clientFactory = createClient, initialLocationHref = getDefaultLocation() } = instance.config.auth ?? {}, apiHost = configApiHost ?? getStagingApiHost(), authConfig = instance.config.auth ?? {}, loginDomain = "https://www.sanity.io";
|
|
680
|
+
try {
|
|
681
|
+
apiHost && new URL(apiHost).hostname.endsWith(".sanity.work") && (loginDomain = "https://www.sanity.work");
|
|
682
|
+
} catch {}
|
|
683
|
+
let loginUrl = new URL("/login", loginDomain);
|
|
684
|
+
loginUrl.searchParams.set("origin", getCleanedUrl(initialLocationHref)), loginUrl.searchParams.set("type", "stampedToken"), loginUrl.searchParams.set("withSid", "true");
|
|
685
|
+
let mode = resolveAuthMode(instance.config, initialLocationHref), strategyOptions = {
|
|
686
|
+
authConfig,
|
|
687
|
+
projectId: instance.config.projectId,
|
|
688
|
+
initialLocationHref,
|
|
689
|
+
clientFactory,
|
|
690
|
+
tokenSource: instance.config.studio?.auth?.token
|
|
691
|
+
}, result;
|
|
692
|
+
switch (mode) {
|
|
693
|
+
case "studio":
|
|
694
|
+
result = getStudioInitialState(strategyOptions);
|
|
695
|
+
break;
|
|
696
|
+
case "dashboard":
|
|
697
|
+
result = getDashboardInitialState(strategyOptions);
|
|
698
|
+
break;
|
|
699
|
+
case "standalone": result = getStandaloneInitialState(strategyOptions);
|
|
700
|
+
}
|
|
701
|
+
return logger.debug("Auth state initialized", {
|
|
702
|
+
authStateType: result.authState.type,
|
|
703
|
+
mode,
|
|
704
|
+
authMethod: result.authMethod
|
|
705
|
+
}), {
|
|
706
|
+
authState: result.authState,
|
|
707
|
+
dashboardContext: result.dashboardContext,
|
|
708
|
+
options: {
|
|
709
|
+
apiHost,
|
|
710
|
+
loginUrl: loginUrl.toString(),
|
|
711
|
+
callbackUrl,
|
|
712
|
+
customProviders,
|
|
713
|
+
providedToken,
|
|
714
|
+
clientFactory,
|
|
715
|
+
initialLocationHref,
|
|
716
|
+
storageKey: result.storageKey,
|
|
717
|
+
storageArea: result.storageArea,
|
|
718
|
+
authMethod: result.authMethod
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
},
|
|
722
|
+
initialize(context) {
|
|
723
|
+
let logger = getAuthLogger(context.instance), initialLocationHref = context.state.get().options?.initialLocationHref ?? getDefaultLocation(), mode = resolveAuthMode(context.instance.config, initialLocationHref);
|
|
724
|
+
logger.debug("Setting up auth subscriptions", { mode });
|
|
725
|
+
let initResult;
|
|
726
|
+
switch (mode) {
|
|
727
|
+
case "studio":
|
|
728
|
+
initResult = initializeStudioAuth(context, tokenRefresherRunning);
|
|
729
|
+
break;
|
|
730
|
+
case "dashboard":
|
|
731
|
+
initResult = initializeDashboardAuth(context, tokenRefresherRunning);
|
|
732
|
+
break;
|
|
733
|
+
case "standalone": initResult = initializeStandaloneAuth(context, tokenRefresherRunning);
|
|
734
|
+
}
|
|
735
|
+
return initResult.tokenRefresherStarted && (tokenRefresherRunning = !0), () => {
|
|
736
|
+
logger.debug("Cleaning up auth subscriptions"), initResult.dispose();
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
}), getCurrentUserState = bindActionGlobally(authStore, createStateSourceAction(({ state: { authState } }) => authState.type === "logged-in" ? authState.currentUser : null)), getTokenState = bindActionGlobally(authStore, createStateSourceAction(({ state: { authState } }) => authState.type === "logged-in" ? authState.token : null)), getAuthMethodState = bindActionGlobally(authStore, createStateSourceAction(({ state: { options } }) => options.authMethod)), getLoginUrlState = bindActionGlobally(authStore, createStateSourceAction(({ state: { options } }) => options.loginUrl)), getAuthState = bindActionGlobally(authStore, createStateSourceAction(({ state: { authState } }) => authState)), getDashboardOrganizationId = bindActionGlobally(authStore, createStateSourceAction(({ state: { dashboardContext } }) => dashboardContext?.orgId)), getIsInDashboardState = bindActionGlobally(authStore, createStateSourceAction(({ state: { dashboardContext } }) => !!dashboardContext && Object.keys(dashboardContext).length > 0)), setAuthToken = bindActionGlobally(authStore, ({ state, instance }, token) => {
|
|
740
|
+
let logger = getAuthLogger(instance), currentAuthState = state.get().authState;
|
|
741
|
+
if (token) {
|
|
742
|
+
if (currentAuthState.type !== "logged-in" || currentAuthState.token !== token) {
|
|
743
|
+
logger.info("Setting auth token");
|
|
744
|
+
let currentUser = currentAuthState.type === "logged-in" ? currentAuthState.currentUser : null, preservedLastTokenRefresh = currentAuthState.type === "logged-in" ? currentAuthState.lastTokenRefresh : void 0;
|
|
745
|
+
state.set("setToken", { authState: createLoggedInAuthState(token, currentUser, preservedLastTokenRefresh) });
|
|
746
|
+
}
|
|
747
|
+
} else currentAuthState.type !== "logged-out" && (logger.info("Clearing auth token"), state.set("setToken", { authState: {
|
|
748
|
+
type: "logged-out",
|
|
749
|
+
isDestroyingSession: !1
|
|
750
|
+
} }));
|
|
751
|
+
});
|
|
752
|
+
export { REQUEST_TAG_PREFIX as C, DEFAULT_API_VERSION as S, getStagingApiHost as T, getDefaultLocation as _, getCurrentUserState as a, AuthStateType as b, getLoginUrlState as c, createLoggedInAuthState as d, getAuthCode as f, getClientErrorApiType as g, getClientErrorApiDescription as h, getAuthState as i, getTokenState as l, getClientErrorApiBody as m, authStore_exports as n, getDashboardOrganizationId as o, getCleanedUrl as p, getAuthMethodState as r, getIsInDashboardState as s, authStore as t, setAuthToken as u, getTokenFromLocation as v, getAuthLogger as w, isStudioConfig as x, isProjectUserNotFoundClientError as y };
|
|
753
|
+
|
|
754
|
+
//# sourceMappingURL=authStore-CtE9bLHW.js.map
|