@sanity/sdk 0.0.0-rc.5 → 0.0.0-rc.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +11 -0
- package/dist/index.js +76 -44
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/auth/Auth Guide.md +165 -0
- package/src/auth/authStore.test.ts +84 -0
- package/src/auth/authStore.ts +33 -1
- package/src/auth/studioModeAuth.test.ts +122 -0
- package/src/auth/studioModeAuth.ts +50 -0
- package/src/client/clientStore.test.ts +12 -2
- package/src/client/clientStore.ts +25 -4
- package/src/config/sanityConfig.ts +7 -0
- package/src/document/documentStore.test.ts +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -260,6 +260,8 @@ export declare interface AuthConfig {
|
|
|
260
260
|
token?: string
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
+
declare type AuthMethodOptions = 'localstorage' | 'cookie' | undefined
|
|
264
|
+
|
|
263
265
|
/**
|
|
264
266
|
* Configuration for an authentication provider
|
|
265
267
|
* @public
|
|
@@ -322,6 +324,7 @@ export declare interface AuthStoreState {
|
|
|
322
324
|
loginUrl: string
|
|
323
325
|
callbackUrl: string | undefined
|
|
324
326
|
providedToken: string | undefined
|
|
327
|
+
authMethod: AuthMethodOptions
|
|
325
328
|
}
|
|
326
329
|
dashboardContext?: DashboardContext
|
|
327
330
|
}
|
|
@@ -391,6 +394,7 @@ export declare interface ClientState {
|
|
|
391
394
|
clients: {
|
|
392
395
|
[TKey in string]?: SanityClient
|
|
393
396
|
}
|
|
397
|
+
authMethod?: 'localstorage' | 'cookie'
|
|
394
398
|
}
|
|
395
399
|
|
|
396
400
|
/**
|
|
@@ -1865,6 +1869,13 @@ export declare interface SanityConfig extends DatasetHandle {
|
|
|
1865
1869
|
* @remarks Merged with parent configurations when using createChild
|
|
1866
1870
|
*/
|
|
1867
1871
|
auth?: AuthConfig
|
|
1872
|
+
/**
|
|
1873
|
+
* Studio mode configuration for use of the SDK in a Sanity Studio
|
|
1874
|
+
* @remarks Controls whether studio mode features are enabled
|
|
1875
|
+
*/
|
|
1876
|
+
studioMode?: {
|
|
1877
|
+
enabled: boolean
|
|
1878
|
+
}
|
|
1868
1879
|
}
|
|
1869
1880
|
|
|
1870
1881
|
export {SanityDocument}
|
package/dist/index.js
CHANGED
|
@@ -277,41 +277,6 @@ const refreshStampedToken = ({ state }) => {
|
|
|
277
277
|
state.set("setRefreshStampedTokenError", { authState: { type: AuthStateType.ERROR, error } });
|
|
278
278
|
}
|
|
279
279
|
});
|
|
280
|
-
}, subscribeToStateAndFetchCurrentUser = ({
|
|
281
|
-
state
|
|
282
|
-
}) => {
|
|
283
|
-
const { clientFactory, apiHost } = state.get().options;
|
|
284
|
-
return state.observable.pipe(
|
|
285
|
-
map(({ authState }) => authState),
|
|
286
|
-
filter(
|
|
287
|
-
(authState) => authState.type === AuthStateType.LOGGED_IN && !authState.currentUser
|
|
288
|
-
),
|
|
289
|
-
map((authState) => authState.token),
|
|
290
|
-
distinctUntilChanged()
|
|
291
|
-
).pipe(
|
|
292
|
-
map(
|
|
293
|
-
(token) => clientFactory({
|
|
294
|
-
apiVersion: DEFAULT_API_VERSION$1,
|
|
295
|
-
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
296
|
-
token,
|
|
297
|
-
ignoreBrowserTokenWarning: !0,
|
|
298
|
-
useProjectHostname: !1,
|
|
299
|
-
...apiHost && { apiHost }
|
|
300
|
-
})
|
|
301
|
-
),
|
|
302
|
-
switchMap(
|
|
303
|
-
(client) => client.observable.request({ uri: "/users/me", method: "GET" })
|
|
304
|
-
)
|
|
305
|
-
).subscribe({
|
|
306
|
-
next: (currentUser) => {
|
|
307
|
-
state.set("setCurrentUser", (prev) => ({
|
|
308
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? { ...prev.authState, currentUser } : prev.authState
|
|
309
|
-
}));
|
|
310
|
-
},
|
|
311
|
-
error: (error) => {
|
|
312
|
-
state.set("setError", { authState: { type: AuthStateType.ERROR, error } });
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
280
|
};
|
|
316
281
|
function getAuthCode(callbackUrl, locationHref) {
|
|
317
282
|
const loc = new URL(locationHref, DEFAULT_BASE), callbackLocation = callbackUrl ? new URL(callbackUrl, DEFAULT_BASE) : void 0, callbackLocationMatches = callbackLocation ? loc.pathname.toLowerCase().startsWith(callbackLocation.pathname.toLowerCase()) : !0;
|
|
@@ -365,7 +330,61 @@ function getCleanedUrl(locationUrl) {
|
|
|
365
330
|
const loc = new URL(locationUrl);
|
|
366
331
|
return loc.hash = "", loc.searchParams.delete("sid"), loc.searchParams.delete("url"), loc.toString();
|
|
367
332
|
}
|
|
368
|
-
|
|
333
|
+
async function checkForCookieAuth(projectId, clientFactory) {
|
|
334
|
+
if (!projectId) return !1;
|
|
335
|
+
try {
|
|
336
|
+
return typeof (await clientFactory({
|
|
337
|
+
projectId
|
|
338
|
+
}).request({
|
|
339
|
+
uri: "/users/me",
|
|
340
|
+
withCredentials: !0,
|
|
341
|
+
tag: "users.get-current"
|
|
342
|
+
}))?.id == "string";
|
|
343
|
+
} catch {
|
|
344
|
+
return !1;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
function getStudioTokenFromLocalStorage(storageArea, projectId) {
|
|
348
|
+
if (!storageArea || !projectId) return null;
|
|
349
|
+
const studioStorageKey = `__studio_auth_token_${projectId}`;
|
|
350
|
+
return getTokenFromStorage(storageArea, studioStorageKey) || null;
|
|
351
|
+
}
|
|
352
|
+
const subscribeToStateAndFetchCurrentUser = ({
|
|
353
|
+
state
|
|
354
|
+
}) => {
|
|
355
|
+
const { clientFactory, apiHost } = state.get().options;
|
|
356
|
+
return state.observable.pipe(
|
|
357
|
+
map(({ authState }) => authState),
|
|
358
|
+
filter(
|
|
359
|
+
(authState) => authState.type === AuthStateType.LOGGED_IN && !authState.currentUser
|
|
360
|
+
),
|
|
361
|
+
map((authState) => authState.token),
|
|
362
|
+
distinctUntilChanged()
|
|
363
|
+
).pipe(
|
|
364
|
+
map(
|
|
365
|
+
(token) => clientFactory({
|
|
366
|
+
apiVersion: DEFAULT_API_VERSION$1,
|
|
367
|
+
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
368
|
+
token,
|
|
369
|
+
ignoreBrowserTokenWarning: !0,
|
|
370
|
+
useProjectHostname: !1,
|
|
371
|
+
...apiHost && { apiHost }
|
|
372
|
+
})
|
|
373
|
+
),
|
|
374
|
+
switchMap(
|
|
375
|
+
(client) => client.observable.request({ uri: "/users/me", method: "GET" })
|
|
376
|
+
)
|
|
377
|
+
).subscribe({
|
|
378
|
+
next: (currentUser) => {
|
|
379
|
+
state.set("setCurrentUser", (prev) => ({
|
|
380
|
+
authState: prev.authState.type === AuthStateType.LOGGED_IN ? { ...prev.authState, currentUser } : prev.authState
|
|
381
|
+
}));
|
|
382
|
+
},
|
|
383
|
+
error: (error) => {
|
|
384
|
+
state.set("setError", { authState: { type: AuthStateType.ERROR, error } });
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
}, subscribeToStorageEventsAndSetToken = ({
|
|
369
388
|
state
|
|
370
389
|
}) => {
|
|
371
390
|
const { storageArea, storageKey } = state.get().options;
|
|
@@ -413,7 +432,10 @@ const authStore = {
|
|
|
413
432
|
console.error("Failed to parse dashboard context from initial location:", err);
|
|
414
433
|
}
|
|
415
434
|
isInDashboard || (storageArea = storageArea ?? getDefaultStorage());
|
|
416
|
-
|
|
435
|
+
let token, authMethod;
|
|
436
|
+
instance.config.studioMode?.enabled ? (token = getStudioTokenFromLocalStorage(storageArea, instance.config.projectId), token ? authMethod = "localstorage" : checkForCookieAuth(instance.config.projectId, clientFactory).then((isCookieAuthEnabled) => {
|
|
437
|
+
isCookieAuthEnabled && (authMethod = "cookie");
|
|
438
|
+
})) : (token = getTokenFromStorage(storageArea, storageKey), token && (authMethod = "localstorage"));
|
|
417
439
|
let authState;
|
|
418
440
|
return providedToken ? authState = { type: AuthStateType.LOGGED_IN, token: providedToken, currentUser: null } : getAuthCode(callbackUrl, initialLocationHref) || getTokenFromLocation(initialLocationHref) ? authState = { type: AuthStateType.LOGGING_IN, isExchangingToken: !1 } : token && !isInDashboard ? authState = { type: AuthStateType.LOGGED_IN, token, currentUser: null } : authState = { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }, {
|
|
419
441
|
authState,
|
|
@@ -427,7 +449,8 @@ const authStore = {
|
|
|
427
449
|
clientFactory,
|
|
428
450
|
initialLocationHref,
|
|
429
451
|
storageKey,
|
|
430
|
-
storageArea
|
|
452
|
+
storageArea,
|
|
453
|
+
authMethod
|
|
431
454
|
}
|
|
432
455
|
};
|
|
433
456
|
},
|
|
@@ -448,6 +471,9 @@ const authStore = {
|
|
|
448
471
|
createStateSourceAction(
|
|
449
472
|
({ state: { authState } }) => authState.type === AuthStateType.LOGGED_IN ? authState.token : null
|
|
450
473
|
)
|
|
474
|
+
), getAuthMethodState = bindActionGlobally(
|
|
475
|
+
authStore,
|
|
476
|
+
createStateSourceAction(({ state: { options } }) => options.authMethod)
|
|
451
477
|
), getLoginUrlState = bindActionGlobally(
|
|
452
478
|
authStore,
|
|
453
479
|
createStateSourceAction(({ state: { options } }) => options.loginUrl)
|
|
@@ -552,11 +578,15 @@ const authStore = {
|
|
|
552
578
|
token: getTokenState(instance).getCurrent()
|
|
553
579
|
}),
|
|
554
580
|
initialize(context) {
|
|
555
|
-
const subscription = listenToToken(context);
|
|
556
|
-
return () =>
|
|
581
|
+
const subscription = listenToToken(context), authMethodSubscription = listenToAuthMethod(context);
|
|
582
|
+
return () => {
|
|
583
|
+
subscription.unsubscribe(), authMethodSubscription.unsubscribe();
|
|
584
|
+
};
|
|
557
585
|
}
|
|
558
586
|
}, listenToToken = ({ instance, state }) => getTokenState(instance).observable.subscribe((token) => {
|
|
559
587
|
state.set("setTokenAndResetClients", { token, clients: {} });
|
|
588
|
+
}), listenToAuthMethod = ({ instance, state }) => getAuthMethodState(instance).observable.subscribe((authMethod) => {
|
|
589
|
+
state.set("setAuthMethod", { authMethod });
|
|
560
590
|
}), getClientConfigKey = (options) => JSON.stringify(pick(options, ...allowedKeys)), getClient = bindActionGlobally(
|
|
561
591
|
clientStore,
|
|
562
592
|
({ state, instance }, options) => {
|
|
@@ -567,15 +597,17 @@ const authStore = {
|
|
|
567
597
|
`The client options provided contains unsupported properties: ${listFormatter.format(disallowedKeys)}. Allowed keys are: ${listFormatter.format(allowedKeys)}.`
|
|
568
598
|
);
|
|
569
599
|
}
|
|
570
|
-
const
|
|
600
|
+
const tokenFromState = state.get().token, { clients, authMethod } = state.get(), projectId = options.projectId ?? instance.config.projectId, dataset = options.dataset ?? instance.config.dataset, apiHost = options.apiHost ?? instance.config.auth?.apiHost, effectiveOptions = {
|
|
571
601
|
...DEFAULT_CLIENT_CONFIG,
|
|
572
602
|
...(options.scope === "global" || !projectId) && { useProjectHostname: !1 },
|
|
573
|
-
|
|
603
|
+
token: authMethod === "cookie" ? void 0 : tokenFromState ?? void 0,
|
|
574
604
|
...options,
|
|
575
605
|
...projectId && { projectId },
|
|
576
606
|
...dataset && { dataset },
|
|
577
607
|
...apiHost && { apiHost }
|
|
578
|
-
}
|
|
608
|
+
};
|
|
609
|
+
effectiveOptions.token === null || typeof effectiveOptions.token > "u" ? (delete effectiveOptions.token, authMethod === "cookie" && (effectiveOptions.withCredentials = !0)) : delete effectiveOptions.withCredentials;
|
|
610
|
+
const key = getClientConfigKey(effectiveOptions);
|
|
579
611
|
if (clients[key]) return clients[key];
|
|
580
612
|
const client = createClient(effectiveOptions);
|
|
581
613
|
return state.set("addClient", (prev) => ({ clients: { ...prev.clients, [key]: client } })), client;
|
|
@@ -5105,7 +5137,7 @@ function createGroqSearchFilter(query) {
|
|
|
5105
5137
|
`${finalIncrementalToken}${WILDCARD_TOKEN}`
|
|
5106
5138
|
), `[@] match text::query("${processedTokens.join(" ").replace(/"/g, '\\"')}")`;
|
|
5107
5139
|
}
|
|
5108
|
-
var version = "0.0.0-rc.
|
|
5140
|
+
var version = "0.0.0-rc.6";
|
|
5109
5141
|
const CORE_SDK_VERSION = getEnv("PKG_VERSION") || `${version}-development`;
|
|
5110
5142
|
export {
|
|
5111
5143
|
AuthStateType,
|