@sanity/sdk 2.10.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks-dts/utils.d.ts +200 -28
- package/dist/_chunks-es/_internal.js +3 -14
- package/dist/_chunks-es/_internal.js.map +1 -1
- package/dist/_chunks-es/createGroqSearchFilter.js +7 -14
- package/dist/_chunks-es/createGroqSearchFilter.js.map +1 -1
- package/dist/_chunks-es/version.js +1 -1
- package/dist/_exports/_internal.d.ts +16 -2
- package/dist/_exports/_internal.js +3 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +168 -88
- package/dist/index.js.map +1 -1
- package/package.json +7 -9
- package/src/_exports/_internal.ts +1 -0
- package/src/_exports/index.ts +25 -2
- package/src/agent/agentActions.ts +21 -25
- package/src/client/clientStore.test.ts +10 -46
- package/src/client/clientStore.ts +7 -14
- package/src/comlink/node/actions/getOrCreateNode.test.ts +5 -2
- package/src/comlink/node/actions/releaseNode.test.ts +3 -3
- package/src/config/sanityConfig.ts +0 -1
- package/src/document/documentStore.ts +2 -7
- package/src/document/sharedListener.ts +3 -5
- package/src/organization/organization.test-d.ts +102 -0
- package/src/organization/organization.test.ts +138 -0
- package/src/organization/organization.ts +166 -0
- package/src/organizations/organizations.test-d.ts +77 -0
- package/src/organizations/organizations.test.ts +150 -0
- package/src/organizations/organizations.ts +132 -0
- package/src/presence/presenceStore.test.ts +5 -5
- package/src/preview/previewProjectionUtils.ts +2 -3
- package/src/project/project.test-d.ts +93 -0
- package/src/project/project.test.ts +108 -10
- package/src/project/project.ts +152 -26
- package/src/projection/subscribeToStateAndFetchBatches.ts +4 -9
- package/src/projects/projects.test-d.ts +38 -0
- package/src/projects/projects.test.ts +104 -38
- package/src/projects/projects.ts +74 -14
- package/src/query/queryStore.ts +2 -3
- package/src/releases/releasesStore.test.ts +1 -1
- package/src/releases/releasesStore.ts +2 -2
- package/src/store/createSanityInstance.ts +3 -3
- package/src/telemetry/devMode.test.ts +8 -0
- package/src/telemetry/devMode.ts +10 -9
- package/src/telemetry/initTelemetry.test.ts +0 -17
- package/src/telemetry/initTelemetry.ts +2 -12
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _sanity_client4 from "@sanity/client";
|
|
2
2
|
import { ClientConfig, ClientError, ClientPerspective, ListenEvent, MultipleMutationResult, ResponseQueryOptions, SanityClient, SanityDocument, SanityProject, StackablePerspective } from "@sanity/client";
|
|
3
3
|
import { CurrentUser, CurrentUser as CurrentUser$1, Mutation, PatchOperations, Role, SanityDocument as SanityDocument$1, SanityDocument as SanityDocument$3, SanityDocumentLike } from "@sanity/types";
|
|
4
4
|
import { Observable, Subject } from "rxjs";
|
|
@@ -186,7 +186,6 @@ interface DocumentHandle<TDocumentType extends string = string, TDataset extends
|
|
|
186
186
|
interface SanityConfig extends DatasetHandle, PerspectiveHandle {
|
|
187
187
|
/**
|
|
188
188
|
* Authentication configuration for the instance
|
|
189
|
-
* @remarks Merged with parent configurations when using createChild
|
|
190
189
|
*/
|
|
191
190
|
auth?: AuthConfig;
|
|
192
191
|
/**
|
|
@@ -301,7 +300,6 @@ declare function isCanvasSource(source: DocumentSource): source is CanvasSource;
|
|
|
301
300
|
declare function isStudioConfig(config: SanityConfig): boolean;
|
|
302
301
|
/**
|
|
303
302
|
* Represents a Sanity.io resource instance with its own configuration and lifecycle
|
|
304
|
-
* @remarks Instances form a hierarchy through parent/child relationships
|
|
305
303
|
*
|
|
306
304
|
* @public
|
|
307
305
|
*/
|
|
@@ -313,7 +311,6 @@ interface SanityInstance {
|
|
|
313
311
|
readonly instanceId: string;
|
|
314
312
|
/**
|
|
315
313
|
* Resolved configuration for this instance
|
|
316
|
-
* @remarks Merges values from parent instances where appropriate
|
|
317
314
|
*/
|
|
318
315
|
readonly config: SanityConfig;
|
|
319
316
|
/**
|
|
@@ -335,12 +332,13 @@ interface SanityInstance {
|
|
|
335
332
|
/**
|
|
336
333
|
* Gets the parent instance in the hierarchy
|
|
337
334
|
* @returns Parent instance or undefined if this is the root
|
|
335
|
+
* @deprecated The parent/child instance hierarchy is deprecated. Use a single SanityInstance instead.
|
|
338
336
|
*/
|
|
339
337
|
getParent(): SanityInstance | undefined;
|
|
340
338
|
/**
|
|
341
339
|
* Creates a child instance with merged configuration
|
|
342
340
|
* @param config - Configuration to merge with parent values
|
|
343
|
-
* @
|
|
341
|
+
* @deprecated The parent/child instance hierarchy is deprecated. Use a single SanityInstance instead.
|
|
344
342
|
*/
|
|
345
343
|
createChild(config: SanityConfig): SanityInstance;
|
|
346
344
|
/**
|
|
@@ -348,6 +346,7 @@ interface SanityInstance {
|
|
|
348
346
|
* matches the given target config using a shallow comparison.
|
|
349
347
|
* @param targetConfig - A partial configuration object containing key-value pairs to match.
|
|
350
348
|
* @returns The first matching instance or undefined if no match is found.
|
|
349
|
+
* @deprecated The parent/child instance hierarchy is deprecated. Use a single SanityInstance instead.
|
|
351
350
|
*/
|
|
352
351
|
match(targetConfig: Partial<SanityConfig>): SanityInstance | undefined;
|
|
353
352
|
}
|
|
@@ -441,7 +440,7 @@ type AgentPatchResult = Awaited<ReturnType<SanityClient['agent']['action']['patc
|
|
|
441
440
|
* @returns An Observable emitting the result of the agent generate action.
|
|
442
441
|
* @alpha
|
|
443
442
|
*/
|
|
444
|
-
declare function agentGenerate(instance: SanityInstance, options: AgentGenerateOptions): AgentGenerateResult;
|
|
443
|
+
declare function agentGenerate(instance: SanityInstance, options: AgentGenerateOptions, resource?: DocumentResource): AgentGenerateResult;
|
|
445
444
|
/**
|
|
446
445
|
* Transforms a document using the agent.
|
|
447
446
|
* @param instance - The Sanity instance.
|
|
@@ -449,7 +448,7 @@ declare function agentGenerate(instance: SanityInstance, options: AgentGenerateO
|
|
|
449
448
|
* @returns An Observable emitting the result of the agent transform action.
|
|
450
449
|
* @alpha
|
|
451
450
|
*/
|
|
452
|
-
declare function agentTransform(instance: SanityInstance, options: AgentTransformOptions): AgentTransformResult;
|
|
451
|
+
declare function agentTransform(instance: SanityInstance, options: AgentTransformOptions, resource?: DocumentResource): AgentTransformResult;
|
|
453
452
|
/**
|
|
454
453
|
* Translates a document using the agent.
|
|
455
454
|
* @param instance - The Sanity instance.
|
|
@@ -457,7 +456,7 @@ declare function agentTransform(instance: SanityInstance, options: AgentTransfor
|
|
|
457
456
|
* @returns An Observable emitting the result of the agent translate action.
|
|
458
457
|
* @alpha
|
|
459
458
|
*/
|
|
460
|
-
declare function agentTranslate(instance: SanityInstance, options: AgentTranslateOptions): AgentTranslateResult;
|
|
459
|
+
declare function agentTranslate(instance: SanityInstance, options: AgentTranslateOptions, resource?: DocumentResource): AgentTranslateResult;
|
|
461
460
|
/**
|
|
462
461
|
* Prompts the agent using the same instruction template format as the other actions, but returns text or json instead of acting on a document.
|
|
463
462
|
* @param instance - The Sanity instance.
|
|
@@ -465,7 +464,7 @@ declare function agentTranslate(instance: SanityInstance, options: AgentTranslat
|
|
|
465
464
|
* @returns An Observable emitting the result of the agent prompt action.
|
|
466
465
|
* @alpha
|
|
467
466
|
*/
|
|
468
|
-
declare function agentPrompt(instance: SanityInstance, options: AgentPromptOptions): Observable<AgentPromptResult>;
|
|
467
|
+
declare function agentPrompt(instance: SanityInstance, options: AgentPromptOptions, resource?: DocumentResource): Observable<AgentPromptResult>;
|
|
469
468
|
/**
|
|
470
469
|
* Patches a document using the agent.
|
|
471
470
|
* @param instance - The Sanity instance.
|
|
@@ -473,7 +472,7 @@ declare function agentPrompt(instance: SanityInstance, options: AgentPromptOptio
|
|
|
473
472
|
* @returns An Observable emitting the result of the agent patch action.
|
|
474
473
|
* @alpha
|
|
475
474
|
*/
|
|
476
|
-
declare function agentPatch(instance: SanityInstance, options: AgentPatchOptions): Observable<AgentPatchResult>;
|
|
475
|
+
declare function agentPatch(instance: SanityInstance, options: AgentPatchOptions, resource?: DocumentResource): Observable<AgentPatchResult>;
|
|
477
476
|
/**
|
|
478
477
|
* Represents the various states the authentication type can be in.
|
|
479
478
|
*
|
|
@@ -999,9 +998,9 @@ interface Logger {
|
|
|
999
998
|
*/
|
|
1000
999
|
declare function configureLogging(config: LoggerConfig): void;
|
|
1001
1000
|
/** @public */
|
|
1002
|
-
declare const getDatasetsState: BoundStoreAction<FetcherStoreState<[options?: ProjectHandle<string> | undefined],
|
|
1001
|
+
declare const getDatasetsState: BoundStoreAction<FetcherStoreState<[options?: ProjectHandle<string> | undefined], _sanity_client4.DatasetsResponse>, [options?: ProjectHandle<string> | undefined], StateSource<_sanity_client4.DatasetsResponse | undefined>>;
|
|
1003
1002
|
/** @public */
|
|
1004
|
-
declare const resolveDatasets: BoundStoreAction<FetcherStoreState<[options?: ProjectHandle<string> | undefined],
|
|
1003
|
+
declare const resolveDatasets: BoundStoreAction<FetcherStoreState<[options?: ProjectHandle<string> | undefined], _sanity_client4.DatasetsResponse>, [options?: ProjectHandle<string> | undefined], Promise<_sanity_client4.DatasetsResponse>>;
|
|
1005
1004
|
/**
|
|
1006
1005
|
* Represents an action to create a new document.
|
|
1007
1006
|
* Specifies the document type and optionally a document ID (which will be treated as the published ID).
|
|
@@ -1619,6 +1618,111 @@ declare const getFavoritesState: BoundStoreAction<FetcherStoreState<[FavoriteDoc
|
|
|
1619
1618
|
* @public
|
|
1620
1619
|
*/
|
|
1621
1620
|
declare const resolveFavoritesState: BoundStoreAction<FetcherStoreState<[FavoriteDocumentContext], FavoriteStatusResponse>, [FavoriteDocumentContext], Promise<FavoriteStatusResponse>>;
|
|
1621
|
+
/** @public */
|
|
1622
|
+
interface OrganizationMember {
|
|
1623
|
+
sanityUserId: string;
|
|
1624
|
+
isCurrentUser: boolean;
|
|
1625
|
+
user: {
|
|
1626
|
+
id: string;
|
|
1627
|
+
displayName: string;
|
|
1628
|
+
familyName: string;
|
|
1629
|
+
givenName: string;
|
|
1630
|
+
middleName: string | null;
|
|
1631
|
+
imageUrl: string | null;
|
|
1632
|
+
email: string;
|
|
1633
|
+
loginProvider: string;
|
|
1634
|
+
};
|
|
1635
|
+
roles: Array<{
|
|
1636
|
+
name: string;
|
|
1637
|
+
title: string;
|
|
1638
|
+
description?: string;
|
|
1639
|
+
}>;
|
|
1640
|
+
}
|
|
1641
|
+
/**
|
|
1642
|
+
* The base fields returned from `/organizations/<id>` for every organization.
|
|
1643
|
+
* @public
|
|
1644
|
+
*/
|
|
1645
|
+
interface OrganizationBase {
|
|
1646
|
+
id: string;
|
|
1647
|
+
name: string;
|
|
1648
|
+
slug: string | null;
|
|
1649
|
+
createdAt: string;
|
|
1650
|
+
createdByUserId: string;
|
|
1651
|
+
updatedAt: string;
|
|
1652
|
+
deletedAt: string | null;
|
|
1653
|
+
dashboardStatus: 'enabled' | 'disabled';
|
|
1654
|
+
aiFeaturesStatus: 'enabled' | 'disabled';
|
|
1655
|
+
mediaLibraryStatus: 'enabled' | 'disabled';
|
|
1656
|
+
requestAccessStatus: 'allowed' | 'disabled';
|
|
1657
|
+
telemetryConsentStatus: 'allowed' | 'msa_denied' | 'customer_denied';
|
|
1658
|
+
oauthAppsStatus: 'allowed' | 'blocked';
|
|
1659
|
+
defaultRoleName: string;
|
|
1660
|
+
domains: string[] | null;
|
|
1661
|
+
}
|
|
1662
|
+
/** @public */
|
|
1663
|
+
interface OrganizationOptions<IncludeMembers extends boolean = false, IncludeFeatures extends boolean = false> {
|
|
1664
|
+
includeMembers?: IncludeMembers;
|
|
1665
|
+
includeFeatures?: IncludeFeatures;
|
|
1666
|
+
organizationId: string;
|
|
1667
|
+
}
|
|
1668
|
+
/**
|
|
1669
|
+
* An `Organization` with `members` and/or `features` conditionally included
|
|
1670
|
+
* based on the query options used to fetch it.
|
|
1671
|
+
* @public
|
|
1672
|
+
*/
|
|
1673
|
+
type Organization<IncludeMembers extends boolean = false, IncludeFeatures extends boolean = false> = OrganizationBase & (boolean extends IncludeMembers ? {
|
|
1674
|
+
members?: OrganizationMember[];
|
|
1675
|
+
} : IncludeMembers extends true ? {
|
|
1676
|
+
members: OrganizationMember[];
|
|
1677
|
+
} : unknown) & (boolean extends IncludeFeatures ? {
|
|
1678
|
+
features?: string[];
|
|
1679
|
+
} : IncludeFeatures extends true ? {
|
|
1680
|
+
features: string[];
|
|
1681
|
+
} : unknown);
|
|
1682
|
+
/**
|
|
1683
|
+
* Public signature for the organization state source. The conditional generics
|
|
1684
|
+
* cannot flow through `BoundStoreAction`, so we declare the signature here
|
|
1685
|
+
* and assign the (already-correct) runtime function to it.
|
|
1686
|
+
*/
|
|
1687
|
+
type GetOrganizationState = <IncludeMembers extends boolean = false, IncludeFeatures extends boolean = false>(instance: SanityInstance, options: OrganizationOptions<IncludeMembers, IncludeFeatures>) => StateSource<Organization<IncludeMembers, IncludeFeatures> | undefined>;
|
|
1688
|
+
type ResolveOrganization = <IncludeMembers extends boolean = false, IncludeFeatures extends boolean = false>(instance: SanityInstance, options: OrganizationOptions<IncludeMembers, IncludeFeatures>) => Promise<Organization<IncludeMembers, IncludeFeatures>>;
|
|
1689
|
+
/** @public */
|
|
1690
|
+
declare const getOrganizationState: GetOrganizationState;
|
|
1691
|
+
/** @public */
|
|
1692
|
+
declare const resolveOrganization: ResolveOrganization;
|
|
1693
|
+
/**
|
|
1694
|
+
* The list shape returned from `/organizations`, with `members` and/or
|
|
1695
|
+
* `features` conditionally included based on the query options used.
|
|
1696
|
+
* @public
|
|
1697
|
+
*/
|
|
1698
|
+
type Organizations<IncludeMembers extends boolean = false, IncludeFeatures extends boolean = false> = (Pick<OrganizationBase, 'id' | 'name' | 'slug' | 'createdAt' | 'updatedAt' | 'defaultRoleName' | 'dashboardStatus' | 'aiFeaturesStatus'> & (boolean extends IncludeMembers ? {
|
|
1699
|
+
members?: OrganizationMember[];
|
|
1700
|
+
} : IncludeMembers extends true ? {
|
|
1701
|
+
members: OrganizationMember[];
|
|
1702
|
+
} : unknown) & (boolean extends IncludeFeatures ? {
|
|
1703
|
+
features?: string[];
|
|
1704
|
+
} : IncludeFeatures extends true ? {
|
|
1705
|
+
features: string[];
|
|
1706
|
+
} : unknown))[];
|
|
1707
|
+
/** @public */
|
|
1708
|
+
interface OrganizationsOptions<IncludeMembers extends boolean = false, IncludeFeatures extends boolean = false> extends Omit<OrganizationOptions<IncludeMembers, IncludeFeatures>, 'organizationId'> {
|
|
1709
|
+
/**
|
|
1710
|
+
* When `true`, includes organisations the user has access to via
|
|
1711
|
+
* project-level grants, not just direct organisation memberships.
|
|
1712
|
+
*/
|
|
1713
|
+
includeImplicitMemberships?: boolean;
|
|
1714
|
+
}
|
|
1715
|
+
/**
|
|
1716
|
+
* Public signature for the organization state source. The conditional generics
|
|
1717
|
+
* cannot flow through `BoundStoreAction`, so we declare the signature here
|
|
1718
|
+
* and assign the (already-correct) runtime function to it.
|
|
1719
|
+
*/
|
|
1720
|
+
type GetOrganizationsState = <IncludeMembers extends boolean = false, IncludeFeatures extends boolean = false>(instance: SanityInstance, options?: OrganizationsOptions<IncludeMembers, IncludeFeatures>) => StateSource<Organizations<IncludeMembers, IncludeFeatures> | undefined>;
|
|
1721
|
+
type ResolveOrganizations = <IncludeMembers extends boolean = false, IncludeFeatures extends boolean = false>(instance: SanityInstance, options?: OrganizationsOptions<IncludeMembers, IncludeFeatures>) => Promise<Organizations<IncludeMembers, IncludeFeatures>>;
|
|
1722
|
+
/** @public */
|
|
1723
|
+
declare const getOrganizationsState: GetOrganizationsState;
|
|
1724
|
+
/** @public */
|
|
1725
|
+
declare const resolveOrganizations: ResolveOrganizations;
|
|
1622
1726
|
/**
|
|
1623
1727
|
* @public
|
|
1624
1728
|
*/
|
|
@@ -1890,9 +1994,75 @@ type ResolvePreviewOptions = DocumentHandle;
|
|
|
1890
1994
|
*/
|
|
1891
1995
|
declare function resolvePreview(instance: SanityInstance, options: ResolvePreviewOptions): Promise<ValuePending<PreviewValue>>;
|
|
1892
1996
|
/** @public */
|
|
1893
|
-
|
|
1997
|
+
interface ProjectMemberRole {
|
|
1998
|
+
name: string;
|
|
1999
|
+
title: string;
|
|
2000
|
+
description: string;
|
|
2001
|
+
}
|
|
2002
|
+
/** @public */
|
|
2003
|
+
interface ProjectMember {
|
|
2004
|
+
id: string;
|
|
2005
|
+
createdAt: string;
|
|
2006
|
+
updatedAt: string;
|
|
2007
|
+
isCurrentUser: boolean;
|
|
2008
|
+
isRobot: boolean;
|
|
2009
|
+
roles: ProjectMemberRole[];
|
|
2010
|
+
}
|
|
2011
|
+
/** @public */
|
|
2012
|
+
interface ProjectMetadata {
|
|
2013
|
+
color?: string;
|
|
2014
|
+
externalStudioHost?: string;
|
|
2015
|
+
initialTemplate?: string;
|
|
2016
|
+
cliInitializedAt?: string;
|
|
2017
|
+
integration: 'manage' | 'cli';
|
|
2018
|
+
}
|
|
2019
|
+
/**
|
|
2020
|
+
* The base fields returned from `/projects` for every project.
|
|
2021
|
+
* @public
|
|
2022
|
+
*/
|
|
2023
|
+
interface ProjectBase {
|
|
2024
|
+
id: string;
|
|
2025
|
+
displayName: string;
|
|
2026
|
+
studioHost: string | null;
|
|
2027
|
+
organizationId: string;
|
|
2028
|
+
metadata: ProjectMetadata;
|
|
2029
|
+
isBlocked: boolean;
|
|
2030
|
+
isDisabled: boolean;
|
|
2031
|
+
isDisabledByUser: boolean;
|
|
2032
|
+
activityFeedEnabled: boolean;
|
|
2033
|
+
createdAt: string;
|
|
2034
|
+
updatedAt: string;
|
|
2035
|
+
}
|
|
2036
|
+
/**
|
|
2037
|
+
* A `Project` with `members` and/or `features` conditionally included
|
|
2038
|
+
* based on the query options used to fetch it.
|
|
2039
|
+
* @public
|
|
2040
|
+
*/
|
|
2041
|
+
type Project<IncludeMembers extends boolean = true, IncludeFeatures extends boolean = true> = ProjectBase & (boolean extends IncludeMembers ? {
|
|
2042
|
+
members?: ProjectMember[];
|
|
2043
|
+
} : IncludeMembers extends true ? {
|
|
2044
|
+
members: ProjectMember[];
|
|
2045
|
+
} : unknown) & (boolean extends IncludeFeatures ? {
|
|
2046
|
+
features?: string[];
|
|
2047
|
+
} : IncludeFeatures extends true ? {
|
|
2048
|
+
features: string[];
|
|
2049
|
+
} : unknown);
|
|
2050
|
+
/** @public */
|
|
2051
|
+
interface ProjectOptions<IncludeMembers extends boolean = true, IncludeFeatures extends boolean = true> extends ProjectHandle {
|
|
2052
|
+
includeMembers?: IncludeMembers;
|
|
2053
|
+
includeFeatures?: IncludeFeatures;
|
|
2054
|
+
}
|
|
2055
|
+
/**
|
|
2056
|
+
* Public signature for the project state source. The conditional generics
|
|
2057
|
+
* cannot flow through `BoundStoreAction`, so we declare the signature here
|
|
2058
|
+
* and assign the (already-correct) runtime function to it.
|
|
2059
|
+
*/
|
|
2060
|
+
type GetProjectState = <IncludeMembers extends boolean = true, IncludeFeatures extends boolean = true>(instance: SanityInstance, options?: ProjectOptions<IncludeMembers, IncludeFeatures>) => StateSource<Project<IncludeMembers, IncludeFeatures> | undefined>;
|
|
2061
|
+
type ResolveProject = <IncludeMembers extends boolean = true, IncludeFeatures extends boolean = true>(instance: SanityInstance, options?: ProjectOptions<IncludeMembers, IncludeFeatures>) => Promise<Project<IncludeMembers, IncludeFeatures>>;
|
|
2062
|
+
/** @public */
|
|
2063
|
+
declare const getProjectState: GetProjectState;
|
|
1894
2064
|
/** @public */
|
|
1895
|
-
declare const resolveProject:
|
|
2065
|
+
declare const resolveProject: ResolveProject;
|
|
1896
2066
|
interface ProjectionOptions<TProjection extends string = string, TDocumentType extends string = string, TDataset extends string = string, TProjectId extends string = string> extends DocumentHandle<TDocumentType, TDataset, TProjectId> {
|
|
1897
2067
|
projection: TProjection;
|
|
1898
2068
|
}
|
|
@@ -1913,21 +2083,23 @@ declare function resolveProjection<TProjection extends string = string, TDocumen
|
|
|
1913
2083
|
/** @beta */
|
|
1914
2084
|
declare function resolveProjection<TData extends object>(instance: SanityInstance, options: ProjectionOptions): Promise<ProjectionValuePending<TData>>;
|
|
1915
2085
|
/** @public */
|
|
1916
|
-
|
|
1917
|
-
organizationId?: string;
|
|
1918
|
-
includeMembers?: boolean;
|
|
1919
|
-
} | undefined], Omit<_sanity_client20.SanityProject, never>[]>, [options?: {
|
|
2086
|
+
interface ProjectsOptions<IncludeMembers extends boolean = false, IncludeFeatures extends boolean = true> {
|
|
1920
2087
|
organizationId?: string;
|
|
1921
|
-
includeMembers?:
|
|
1922
|
-
|
|
2088
|
+
includeMembers?: IncludeMembers;
|
|
2089
|
+
includeFeatures?: IncludeFeatures;
|
|
2090
|
+
onlyExplicitMembership?: boolean;
|
|
2091
|
+
}
|
|
2092
|
+
/**
|
|
2093
|
+
* Public signature for the projects state source. The conditional generics
|
|
2094
|
+
* cannot flow through `BoundStoreAction`, so we declare the signature here
|
|
2095
|
+
* and assign the (already-correct) runtime function to it.
|
|
2096
|
+
*/
|
|
2097
|
+
type GetProjectsState = <IncludeMembers extends boolean = false, IncludeFeatures extends boolean = true>(instance: SanityInstance, options?: ProjectsOptions<IncludeMembers, IncludeFeatures>) => StateSource<Project<IncludeMembers, IncludeFeatures>[] | undefined>;
|
|
2098
|
+
type ResolveProjects = <IncludeMembers extends boolean = false, IncludeFeatures extends boolean = true>(instance: SanityInstance, options?: ProjectsOptions<IncludeMembers, IncludeFeatures>) => Promise<Project<IncludeMembers, IncludeFeatures>[]>;
|
|
1923
2099
|
/** @public */
|
|
1924
|
-
declare const
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
} | undefined], Omit<_sanity_client20.SanityProject, never>[]>, [options?: {
|
|
1928
|
-
organizationId?: string;
|
|
1929
|
-
includeMembers?: boolean;
|
|
1930
|
-
} | undefined], Promise<Omit<_sanity_client20.SanityProject, never>[]>>;
|
|
2100
|
+
declare const getProjectsState: GetProjectsState;
|
|
2101
|
+
/** @public */
|
|
2102
|
+
declare const resolveProjects: ResolveProjects;
|
|
1931
2103
|
/**
|
|
1932
2104
|
* @beta
|
|
1933
2105
|
*/
|
|
@@ -2447,4 +2619,4 @@ declare function getClientErrorApiType(error: ClientError): string | undefined;
|
|
|
2447
2619
|
declare function getClientErrorApiDescription(error: ClientError): string | undefined;
|
|
2448
2620
|
/** @internal True if the error represents a projectUserNotFoundError. */
|
|
2449
2621
|
declare function isProjectUserNotFoundClientError(error: ClientError): boolean;
|
|
2450
|
-
export {
|
|
2622
|
+
export { ProjectsOptions as $, NodeState as $n, ReleasePerspective as $r, getFavoritesState as $t, isImportError as A, DocumentAction as An, AgentTranslateOptions as Ar, TransportEvent as At, loadMoreUsers as B, getDatasetsState as Bn, CanvasResource$1 as Br, UsersGroupState as Bt, getIndexForKey as C, PermissionDeniedReason as Cn, AgentGenerateResult as Cr, ProjectionValuePending as Ct, slicePath as D, CreateDocumentAction as Dn, AgentPromptResult as Dr, PresenceLocation as Dt, jsonMatch as E, StateSource as En, AgentPromptOptions as Er, DisconnectEvent as Et, createGroqSearchFilter as F, deleteDocument as Fn, agentTransform as Fr, ResolveUserOptions as Ft, getPerspectiveState as G, LogLevel as Gn, DocumentHandle as Gr, resolveOrganizations as Gt, resolveUsers as H, configureLogging as Hn, DatasetHandle as Hr, Organizations as Ht, FetcherStore as I, discardDocument as In, agentTranslate as Ir, ResolveUsersOptions as It, QueryOptions as J, LoggerConfig as Jn, DocumentTypeHandle as Jr, OrganizationMember as Jt, ReleaseDocument as K, LogNamespace as Kn, DocumentResource as Kr, Organization as Kt, FetcherStoreState as L, editDocument as Ln, SanityInstance as Lr, SanityUser as Lt, Intent as M, PublishDocumentAction as Mn, agentGenerate as Mr, GetUserOptions as Mt, IntentFilter as N, UnpublishDocumentAction as Nn, agentPatch as Nr, GetUsersOptions as Nt, stringifyPath as O, DeleteDocumentAction as On, AgentTransformOptions as Or, RollCallEvent as Ot, defineIntent as P, createDocument as Pn, agentPrompt as Pr, Membership as Pt, resolveQuery as Q, createProjectHandle as Qn, ProjectHandle as Qr, FavoriteStatusResponse as Qt, getUserState as R, publishDocument as Rn, createSanityInstance as Rr, SanityUserResponse as Rt, SanityProject$1 as S, DocumentPermissionsResult as Sn, AgentGenerateOptions as Sr, ValuePending as St, joinPaths as T, Selector as Tn, AgentPatchResult as Tr, getPresence as Tt, getUsersKey as U, InstanceContext as Un, DatasetResource as Ur, OrganizationsOptions as Ut, resolveUser as V, resolveDatasets as Vn, CanvasSource as Vr, UsersStoreState as Vt, parseUsersKey as W, LogContext as Wn, DatasetSource as Wr, getOrganizationsState as Wt, getQueryState as X, createDocumentHandle as Xn, MediaLibrarySource as Xr, getOrganizationState as Xt, getQueryKey as Y, createDatasetHandle as Yn, MediaLibraryResource as Yr, OrganizationOptions as Yt, parseQueryKey as Z, createDocumentTypeHandle as Zn, PerspectiveHandle as Zr, resolveOrganization as Zt, getTokenState as _, getDocumentSyncStatus as _n, logout as _r, getPreviewState as _t, isProjectUserNotFoundClientError as a, isDatasetResource as ai, DocumentCreatedEvent as an, destroyController as ar, ProjectBase as at, Role as b, resolvePermissions as bn, OrgVerificationResult as br, PreviewStoreState as bt, ErrorAuthState as c, isMediaLibrarySource as ci, DocumentEditedEvent as cn, releaseChannel as cr, ProjectMetadata as ct, LoggingInAuthState as d, DocumentTransactionSubmissionResult as dn, RequestNewTokenMessage as dr, resolveProject as dt, SanityConfig as ei, resolveFavoritesState as en, getNodeState as er, getProjectsState as et, getAuthState as f, DocumentUnpublishedEvent as fn, WindowMessage as fr, ResolvePreviewOptions as ft, getLoginUrlState as g, getDocumentState as gn, getClientState as gr, GetPreviewStateOptions as gt, getIsInDashboardState as h, DocumentOptions as hn, getClient as hr, PREVIEW_PROJECTION as ht, getClientErrorApiType as i, isCanvasSource as ii, ActionErrorEvent as in, ComlinkControllerState as ir, Project as it, getCorsErrorProjectId as j, EditDocumentAction as jn, AgentTranslateResult as jr, UserPresence as jt, CORE_SDK_VERSION as k, DiscardDocumentAction as kn, AgentTransformResult as kr, StateEvent as kt, LoggedInAuthState as l, AuthConfig as li, DocumentEvent as ln, FrameMessage as lr, ProjectOptions as lt, getDashboardOrganizationId as m, TransactionRevertedEvent as mn, ClientStoreState as mr, transformProjectionToPreview as mt, getClientErrorApiBody as n, TokenSource as ni, ApplyDocumentActionsOptions as nn, getOrCreateNode as nr, resolveProjection as nt, AuthState as o, isDatasetSource as oi, DocumentDeletedEvent as on, getOrCreateChannel as or, ProjectMember as ot, getCurrentUserState as p, TransactionAcceptedEvent as pn, ClientOptions as pr, resolvePreview as pt, getActiveReleasesState as q, Logger as qn, DocumentSource as qr, OrganizationBase as qt, getClientErrorApiDescription as r, isCanvasResource as ri, applyDocumentActions as rn, releaseNode as rr, getProjectionState as rt, AuthStoreState as s, isMediaLibraryResource as si, DocumentDiscardedEvent as sn, getOrCreateController as sr, ProjectMemberRole as st, ApiErrorBody as t, StudioConfig as ti, ActionsResult as tn, ComlinkNodeState as tr, resolveProjects as tt, LoggedOutAuthState as u, AuthProvider as ui, DocumentPublishedEvent as un, NewTokenResponseMessage as ur, getProjectState as ut, setAuthToken as v, getPermissionsState as vn, handleAuthCallback as vr, PreviewMedia as vt, getPathDepth as w, JsonMatch as wn, AgentPatchOptions as wr, ValidProjection as wt, SanityDocument$3 as x, subscribeDocumentEvents as xn, AuthStateType as xr, PreviewValue as xt, CurrentUser$1 as y, resolveDocument as yn, observeOrganizationVerificationState as yr, PreviewQueryResult as yt, getUsersState as z, unpublishDocument as zn, isStudioConfig as zr, UserProfile as zt };
|
|
@@ -5,7 +5,7 @@ function isLocalUrl(win) {
|
|
|
5
5
|
return url ? url.startsWith("http://localhost") || url.startsWith("https://localhost") || url.startsWith("http://127.0.0.1") || url.startsWith("https://127.0.0.1") : !1;
|
|
6
6
|
}
|
|
7
7
|
function isDevMode() {
|
|
8
|
-
return typeof
|
|
8
|
+
return typeof window < "u" ? isLocalUrl(window) : typeof process < "u" && process.env?.NODE_ENV === "development";
|
|
9
9
|
}
|
|
10
10
|
const SDKDevSessionStarted = defineEvent({
|
|
11
11
|
name: "SDK Dev Session Started",
|
|
@@ -99,23 +99,12 @@ function trackHookMounted(instance, hookName) {
|
|
|
99
99
|
logger.trace("hook mounted (logged)", { hookName, internal: !0 }), manager.logHookFirstUsed(hookName);
|
|
100
100
|
return;
|
|
101
101
|
}
|
|
102
|
-
const root =
|
|
102
|
+
const root = instance;
|
|
103
103
|
let hooks = pendingHooks.get(root);
|
|
104
104
|
hooks || (hooks = /* @__PURE__ */ new Set(), pendingHooks.set(root, hooks)), hooks.has(hookName) || logger.trace("hook mounted (buffered)", { hookName, internal: !0 }), hooks.add(hookName);
|
|
105
105
|
}
|
|
106
106
|
function findManager(instance) {
|
|
107
|
-
|
|
108
|
-
for (; current; ) {
|
|
109
|
-
const manager = telemetryManagers.get(current);
|
|
110
|
-
if (manager) return manager;
|
|
111
|
-
current = typeof current.getParent == "function" ? current.getParent() : void 0;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
function getRootInstance(instance) {
|
|
115
|
-
let current = instance;
|
|
116
|
-
for (; typeof current.getParent == "function" && current.getParent(); )
|
|
117
|
-
current = current.getParent();
|
|
118
|
-
return current;
|
|
107
|
+
return telemetryManagers.get(instance);
|
|
119
108
|
}
|
|
120
109
|
export {
|
|
121
110
|
SDKDevError,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_internal.js","sources":["../../src/telemetry/devMode.ts","../../src/telemetry/__telemetry__/sdk.telemetry.ts","../../src/telemetry/initTelemetry.ts"],"sourcesContent":["/**\n * Checks whether the current URL points to a local development server.\n *\n * @param win - The window object to check\n * @returns True if running on localhost or 127.0.0.1\n * @internal\n */\nfunction isLocalUrl(win: Window): boolean {\n const url = win.location?.href\n if (!url) return false\n return (\n url.startsWith('http://localhost') ||\n url.startsWith('https://localhost') ||\n url.startsWith('http://127.0.0.1') ||\n url.startsWith('https://127.0.0.1')\n )\n}\n\n/**\n * Determines whether the SDK should enable dev-mode telemetry.\n *\n * Combines a browser URL check (localhost/127.0.0.1) with a Node.js\n * environment variable check (`NODE_ENV === 'development'`). Returns\n * false in production environments so bundlers can tree-shake the\n * telemetry code path entirely.\n *\n * @returns True if the SDK is running in a development environment\n * @internal\n */\nexport function isDevMode(): boolean {\n if (typeof process !== 'undefined' && process.env?.['NODE_ENV'] === 'production') {\n return false\n }\n\n if (typeof window !== 'undefined') {\n return isLocalUrl(window)\n }\n\n return typeof process !== 'undefined' && process.env?.['NODE_ENV'] === 'development'\n}\n","import {defineEvent} from '@sanity/telemetry'\n\n/** @internal */\nexport const SDKDevSessionStarted = defineEvent<{\n version: string\n projectId: string\n perspective: string\n authMethod: string\n}>({\n name: 'SDK Dev Session Started',\n version: 1,\n description: 'SDK instance created in development mode',\n})\n\n/** @internal */\nexport const SDKHookMounted = defineEvent<{\n hookName: string\n}>({\n name: 'SDK Hook Mounted',\n version: 1,\n description: 'An SDK hook was mounted for the first time in this session',\n})\n\n/** @internal */\nexport const SDKDevSessionEnded = defineEvent<{\n durationSeconds: number\n hooksUsed: string[]\n}>({\n name: 'SDK Dev Session Ended',\n version: 1,\n description: 'SDK instance disposed in development mode',\n})\n\n/** @internal */\nexport const SDKDevError = defineEvent<{\n errorType: string\n hookName: string\n}>({\n name: 'SDK Dev Error',\n version: 1,\n description: 'Runtime error caught during SDK development',\n})\n","import {type SanityInstance} from '../store/createSanityInstance'\nimport {createLogger} from '../utils/logger'\nimport {isDevMode} from './devMode'\nimport {type TelemetryManager} from './telemetryManager'\n\nconst DEFAULT_TELEMETRY_API_VERSION = '2024-11-12'\n\nconst logger = createLogger('telemetry')\n\n/**\n * Per-instance map of active telemetry managers. Allows the React\n * package (and other consumers) to look up the manager for a given\n * instance and log hook usage / errors without importing the full\n * telemetry module themselves.\n *\n * @internal\n */\nconst telemetryManagers = new WeakMap<SanityInstance, TelemetryManager>()\nconst pendingHooks = new WeakMap<SanityInstance, Set<string>>()\nconst initInFlight = new WeakSet<SanityInstance>()\n\n/**\n * Initializes dev-mode telemetry for a SDK instance if the environment\n * qualifies. Both `telemetryManager` and `clientStore` are dynamically\n * imported to avoid circular dependencies and to keep telemetry code\n * out of production bundles via code splitting.\n *\n * The `projectId` must be passed explicitly because the resource\n * configuration is typically set by the React layer after the\n * instance has already been created.\n *\n * @internal\n */\nexport function initTelemetry(instance: SanityInstance, projectId: string): void {\n if (!isDevMode()) {\n logger.trace('initTelemetry skipped: not dev mode', {internal: true})\n return\n }\n if (!projectId) {\n logger.trace('initTelemetry skipped: no projectId', {internal: true})\n return\n }\n if (telemetryManagers.has(instance) || initInFlight.has(instance)) {\n return\n }\n initInFlight.add(instance)\n\n logger.debug('initializing telemetry', {projectId})\n\n Promise.all([\n import('./telemetryManager'),\n import('../client/clientStore'),\n import('../auth/authStore'),\n ])\n .then(async ([{createTelemetryManager}, {getClient}, {getTokenState}]) => {\n if (instance.isDisposed()) {\n initInFlight.delete(instance)\n logger.debug('telemetry skipped: instance disposed before imports resolved')\n return\n }\n\n // Wait for the auth store to resolve a token. The client needs a\n // Bearer token for the consent check and batch POSTs. If the token\n // is already available (e.g. static token config), this resolves\n // immediately. For OAuth/localStorage discovery it waits for the\n // first emission. For unauthenticated apps the promise never\n // resolves, which is fine since telemetry requires auth anyway.\n const token = getTokenState(instance).getCurrent()\n logger.trace('auth token check', {tokenPresent: !!token, internal: true})\n\n if (!token) {\n logger.debug('waiting for auth token')\n const hasToken = await new Promise<boolean>((resolve) => {\n if (instance.isDisposed()) return resolve(false)\n const cleanup = {unsubscribe: () => {}}\n const unsub = instance.onDispose(() => {\n cleanup.unsubscribe()\n resolve(false)\n })\n const sub = getTokenState(instance).observable.subscribe((t) => {\n if (t) {\n logger.debug('auth token received')\n sub.unsubscribe()\n unsub()\n resolve(true)\n }\n })\n cleanup.unsubscribe = () => sub.unsubscribe()\n })\n if (!hasToken || instance.isDisposed()) {\n initInFlight.delete(instance)\n logger.debug('telemetry skipped: no token resolved or instance disposed')\n return\n }\n }\n\n const manager = createTelemetryManager({\n sessionId: instance.instanceId,\n getClient: () => getClient(instance, {apiVersion: DEFAULT_TELEMETRY_API_VERSION}),\n projectId,\n })\n\n const consented = await manager.checkConsent()\n logger.debug('consent check complete', {consented})\n if (!consented || instance.isDisposed()) {\n initInFlight.delete(instance)\n manager.dispose()\n return\n }\n\n initInFlight.delete(instance)\n telemetryManagers.set(instance, manager)\n\n const buffered = pendingHooks.get(instance)\n if (buffered) {\n logger.debug('flushing buffered hooks', {hooks: Array.from(buffered)})\n for (const hookName of buffered) {\n manager.logHookFirstUsed(hookName)\n }\n pendingHooks.delete(instance)\n }\n\n const config = instance.config\n const perspective = typeof config.perspective === 'string' ? config.perspective : 'published'\n const authMethod = config.auth?.token\n ? 'token'\n : config.studio?.auth?.token\n ? 'studio'\n : 'default'\n\n logger.info('telemetry session started', {projectId, perspective, authMethod})\n manager.logSessionStarted({\n projectId,\n perspective,\n authMethod,\n })\n\n instance.onDispose(() => {\n manager.endSession()\n telemetryManagers.delete(instance)\n logger.debug('telemetry session ended')\n })\n })\n .catch((err) => {\n initInFlight.delete(instance)\n logger.warn('telemetry init failed', {error: err})\n })\n}\n\n/**\n * Retrieves the telemetry manager for an instance, if one exists.\n * Returns undefined when telemetry is disabled or not yet initialized.\n *\n * @internal\n */\nexport function getTelemetryManager(instance: SanityInstance): TelemetryManager | undefined {\n return telemetryManagers.get(instance)\n}\n\n/**\n * Record a hook name for an instance. If the telemetry manager is\n * already initialized the event is logged immediately. Otherwise\n * the name is buffered and flushed when init completes.\n *\n * @internal\n */\nexport function trackHookMounted(instance: SanityInstance, hookName: string): void {\n if (!isDevMode()) return\n\n const manager = findManager(instance)\n if (manager) {\n logger.trace('hook mounted (logged)', {hookName, internal: true})\n manager.logHookFirstUsed(hookName)\n return\n }\n\n const root = getRootInstance(instance)\n let hooks = pendingHooks.get(root)\n if (!hooks) {\n hooks = new Set()\n pendingHooks.set(root, hooks)\n }\n if (!hooks.has(hookName)) {\n logger.trace('hook mounted (buffered)', {hookName, internal: true})\n }\n hooks.add(hookName)\n}\n\nfunction findManager(instance: SanityInstance): TelemetryManager | undefined {\n let current: SanityInstance | undefined = instance\n while (current) {\n const manager = telemetryManagers.get(current)\n if (manager) return manager\n current = typeof current.getParent === 'function' ? current.getParent() : undefined\n }\n return undefined\n}\n\nfunction getRootInstance(instance: SanityInstance): SanityInstance {\n let current = instance\n while (typeof current.getParent === 'function' && current.getParent()) {\n current = current.getParent()!\n }\n return current\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"_internal.js","sources":["../../src/telemetry/devMode.ts","../../src/telemetry/__telemetry__/sdk.telemetry.ts","../../src/telemetry/initTelemetry.ts"],"sourcesContent":["/**\n * Checks whether the current URL points to a local development server.\n *\n * @param win - The window object to check\n * @returns True if running on localhost or 127.0.0.1\n * @internal\n */\nfunction isLocalUrl(win: Window): boolean {\n const url = win.location?.href\n if (!url) return false\n return (\n url.startsWith('http://localhost') ||\n url.startsWith('https://localhost') ||\n url.startsWith('http://127.0.0.1') ||\n url.startsWith('https://127.0.0.1')\n )\n}\n\n/**\n * Determines whether the SDK should enable dev-mode telemetry for the\n * SDK consumer (i.e. a developer building an app with `@sanity/sdk`).\n *\n * Browser: returns true only when the URL is `localhost` or `127.0.0.1`.\n * The URL check is the primary signal because consumer bundlers may or\n * may not forward `NODE_ENV` to the browser reliably.\n *\n * Node (scripts / non-browser): falls back to `NODE_ENV === 'development'`.\n *\n * Bracket-notation `process.env['NODE_ENV']` is used to avoid bundler\n * dead-code replacement.\n *\n * @returns True if the SDK is running in a development environment\n * @internal\n */\nexport function isDevMode(): boolean {\n if (typeof window !== 'undefined') {\n return isLocalUrl(window)\n }\n\n return typeof process !== 'undefined' && process.env?.['NODE_ENV'] === 'development'\n}\n","import {defineEvent} from '@sanity/telemetry'\n\n/** @internal */\nexport const SDKDevSessionStarted = defineEvent<{\n version: string\n projectId: string\n perspective: string\n authMethod: string\n}>({\n name: 'SDK Dev Session Started',\n version: 1,\n description: 'SDK instance created in development mode',\n})\n\n/** @internal */\nexport const SDKHookMounted = defineEvent<{\n hookName: string\n}>({\n name: 'SDK Hook Mounted',\n version: 1,\n description: 'An SDK hook was mounted for the first time in this session',\n})\n\n/** @internal */\nexport const SDKDevSessionEnded = defineEvent<{\n durationSeconds: number\n hooksUsed: string[]\n}>({\n name: 'SDK Dev Session Ended',\n version: 1,\n description: 'SDK instance disposed in development mode',\n})\n\n/** @internal */\nexport const SDKDevError = defineEvent<{\n errorType: string\n hookName: string\n}>({\n name: 'SDK Dev Error',\n version: 1,\n description: 'Runtime error caught during SDK development',\n})\n","import {type SanityInstance} from '../store/createSanityInstance'\nimport {createLogger} from '../utils/logger'\nimport {isDevMode} from './devMode'\nimport {type TelemetryManager} from './telemetryManager'\n\nconst DEFAULT_TELEMETRY_API_VERSION = '2024-11-12'\n\nconst logger = createLogger('telemetry')\n\n/**\n * Per-instance map of active telemetry managers. Allows the React\n * package (and other consumers) to look up the manager for a given\n * instance and log hook usage / errors without importing the full\n * telemetry module themselves.\n *\n * @internal\n */\nconst telemetryManagers = new WeakMap<SanityInstance, TelemetryManager>()\nconst pendingHooks = new WeakMap<SanityInstance, Set<string>>()\nconst initInFlight = new WeakSet<SanityInstance>()\n\n/**\n * Initializes dev-mode telemetry for a SDK instance if the environment\n * qualifies. Both `telemetryManager` and `clientStore` are dynamically\n * imported to avoid circular dependencies and to keep telemetry code\n * out of production bundles via code splitting.\n *\n * The `projectId` must be passed explicitly because the resource\n * configuration is typically set by the React layer after the\n * instance has already been created.\n *\n * @internal\n */\nexport function initTelemetry(instance: SanityInstance, projectId: string): void {\n if (!isDevMode()) {\n logger.trace('initTelemetry skipped: not dev mode', {internal: true})\n return\n }\n if (!projectId) {\n logger.trace('initTelemetry skipped: no projectId', {internal: true})\n return\n }\n if (telemetryManagers.has(instance) || initInFlight.has(instance)) {\n return\n }\n initInFlight.add(instance)\n\n logger.debug('initializing telemetry', {projectId})\n\n Promise.all([\n import('./telemetryManager'),\n import('../client/clientStore'),\n import('../auth/authStore'),\n ])\n .then(async ([{createTelemetryManager}, {getClient}, {getTokenState}]) => {\n if (instance.isDisposed()) {\n initInFlight.delete(instance)\n logger.debug('telemetry skipped: instance disposed before imports resolved')\n return\n }\n\n // Wait for the auth store to resolve a token. The client needs a\n // Bearer token for the consent check and batch POSTs. If the token\n // is already available (e.g. static token config), this resolves\n // immediately. For OAuth/localStorage discovery it waits for the\n // first emission. For unauthenticated apps the promise never\n // resolves, which is fine since telemetry requires auth anyway.\n const token = getTokenState(instance).getCurrent()\n logger.trace('auth token check', {tokenPresent: !!token, internal: true})\n\n if (!token) {\n logger.debug('waiting for auth token')\n const hasToken = await new Promise<boolean>((resolve) => {\n if (instance.isDisposed()) return resolve(false)\n const cleanup = {unsubscribe: () => {}}\n const unsub = instance.onDispose(() => {\n cleanup.unsubscribe()\n resolve(false)\n })\n const sub = getTokenState(instance).observable.subscribe((t) => {\n if (t) {\n logger.debug('auth token received')\n sub.unsubscribe()\n unsub()\n resolve(true)\n }\n })\n cleanup.unsubscribe = () => sub.unsubscribe()\n })\n if (!hasToken || instance.isDisposed()) {\n initInFlight.delete(instance)\n logger.debug('telemetry skipped: no token resolved or instance disposed')\n return\n }\n }\n\n const manager = createTelemetryManager({\n sessionId: instance.instanceId,\n getClient: () => getClient(instance, {apiVersion: DEFAULT_TELEMETRY_API_VERSION}),\n projectId,\n })\n\n const consented = await manager.checkConsent()\n logger.debug('consent check complete', {consented})\n if (!consented || instance.isDisposed()) {\n initInFlight.delete(instance)\n manager.dispose()\n return\n }\n\n initInFlight.delete(instance)\n telemetryManagers.set(instance, manager)\n\n const buffered = pendingHooks.get(instance)\n if (buffered) {\n logger.debug('flushing buffered hooks', {hooks: Array.from(buffered)})\n for (const hookName of buffered) {\n manager.logHookFirstUsed(hookName)\n }\n pendingHooks.delete(instance)\n }\n\n const config = instance.config\n const perspective = typeof config.perspective === 'string' ? config.perspective : 'published'\n const authMethod = config.auth?.token\n ? 'token'\n : config.studio?.auth?.token\n ? 'studio'\n : 'default'\n\n logger.info('telemetry session started', {projectId, perspective, authMethod})\n manager.logSessionStarted({\n projectId,\n perspective,\n authMethod,\n })\n\n instance.onDispose(() => {\n manager.endSession()\n telemetryManagers.delete(instance)\n logger.debug('telemetry session ended')\n })\n })\n .catch((err) => {\n initInFlight.delete(instance)\n logger.warn('telemetry init failed', {error: err})\n })\n}\n\n/**\n * Retrieves the telemetry manager for an instance, if one exists.\n * Returns undefined when telemetry is disabled or not yet initialized.\n *\n * @internal\n */\nexport function getTelemetryManager(instance: SanityInstance): TelemetryManager | undefined {\n return telemetryManagers.get(instance)\n}\n\n/**\n * Record a hook name for an instance. If the telemetry manager is\n * already initialized the event is logged immediately. Otherwise\n * the name is buffered and flushed when init completes.\n *\n * @internal\n */\nexport function trackHookMounted(instance: SanityInstance, hookName: string): void {\n if (!isDevMode()) return\n\n const manager = findManager(instance)\n if (manager) {\n logger.trace('hook mounted (logged)', {hookName, internal: true})\n manager.logHookFirstUsed(hookName)\n return\n }\n\n const root = getRootInstance(instance)\n let hooks = pendingHooks.get(root)\n if (!hooks) {\n hooks = new Set()\n pendingHooks.set(root, hooks)\n }\n if (!hooks.has(hookName)) {\n logger.trace('hook mounted (buffered)', {hookName, internal: true})\n }\n hooks.add(hookName)\n}\n\nfunction findManager(instance: SanityInstance): TelemetryManager | undefined {\n return telemetryManagers.get(instance)\n}\n\nfunction getRootInstance(instance: SanityInstance): SanityInstance {\n return instance\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1039,12 +1039,9 @@ const DEFAULT_API_VERSION = "2024-11-12", DEFAULT_REQUEST_TAG_PREFIX = "sanity.s
|
|
|
1039
1039
|
);
|
|
1040
1040
|
}
|
|
1041
1041
|
const tokenFromState = state.get().token, { clients, authMethod } = state.get();
|
|
1042
|
-
let resource;
|
|
1043
|
-
options.resource && (
|
|
1044
|
-
|
|
1045
|
-
id: `${options.resource.projectId}.${options.resource.dataset}`
|
|
1046
|
-
} : isMediaLibraryResource(options.resource) ? resource = { type: "media-library", id: options.resource.mediaLibraryId } : isCanvasResource(options.resource) && (resource = { type: "canvas", id: options.resource.canvasId }));
|
|
1047
|
-
const projectId = options.projectId ?? instance.config.projectId, dataset = options.dataset ?? instance.config.dataset, apiHost = options.apiHost ?? instance.config.auth?.apiHost ?? getStagingApiHost(), effectiveOptions = {
|
|
1042
|
+
let projectId = options.projectId ?? instance.config.projectId, dataset = options.dataset ?? instance.config.dataset, resource;
|
|
1043
|
+
options.resource && (isMediaLibraryResource(options.resource) ? resource = { type: "media-library", id: options.resource.mediaLibraryId } : isCanvasResource(options.resource) ? resource = { type: "canvas", id: options.resource.canvasId } : isDatasetResource(options.resource) && (projectId = options.resource.projectId, dataset = options.resource.dataset));
|
|
1044
|
+
const apiHost = options.apiHost ?? instance.config.auth?.apiHost ?? getStagingApiHost(), effectiveOptions = {
|
|
1048
1045
|
...DEFAULT_CLIENT_CONFIG,
|
|
1049
1046
|
...(options.scope === "global" || !projectId || resource) && { useProjectHostname: !1 },
|
|
1050
1047
|
token: authMethod === "cookie" ? void 0 : tokenFromState ?? void 0,
|
|
@@ -1054,9 +1051,7 @@ const DEFAULT_API_VERSION = "2024-11-12", DEFAULT_REQUEST_TAG_PREFIX = "sanity.s
|
|
|
1054
1051
|
...resource ? { resource } : { resource: void 0 },
|
|
1055
1052
|
...apiHost && { apiHost }
|
|
1056
1053
|
};
|
|
1057
|
-
resource && (
|
|
1058
|
-
"Both resource and explicit projectId/dataset are provided. The resource will be used and projectId/dataset will be ignored."
|
|
1059
|
-
), delete effectiveOptions.projectId, delete effectiveOptions.dataset), effectiveOptions.token === null || typeof effectiveOptions.token > "u" ? (delete effectiveOptions.token, authMethod === "cookie" && (effectiveOptions.withCredentials = !0)) : delete effectiveOptions.withCredentials;
|
|
1054
|
+
resource && (delete effectiveOptions.projectId, delete effectiveOptions.dataset), effectiveOptions.token === null || typeof effectiveOptions.token > "u" ? (delete effectiveOptions.token, authMethod === "cookie" && (effectiveOptions.withCredentials = !0)) : delete effectiveOptions.withCredentials;
|
|
1060
1055
|
const key = getClientConfigKey(effectiveOptions);
|
|
1061
1056
|
if (clients[key]) return clients[key];
|
|
1062
1057
|
const client = createClient(effectiveOptions);
|
|
@@ -1153,7 +1148,7 @@ const ARCHIVED_RELEASE_STATES = ["archived", "published"], STABLE_EMPTY_RELEASES
|
|
|
1153
1148
|
const { observable: releases$ } = getQueryState(instance, {
|
|
1154
1149
|
query: RELEASES_QUERY,
|
|
1155
1150
|
perspective: "raw",
|
|
1156
|
-
resource
|
|
1151
|
+
resource,
|
|
1157
1152
|
tag: "releases"
|
|
1158
1153
|
});
|
|
1159
1154
|
return releases$.pipe(
|
|
@@ -1304,8 +1299,7 @@ const queryStore = {
|
|
|
1304
1299
|
}) => {
|
|
1305
1300
|
const liveMessages$ = getClientState(instance, {
|
|
1306
1301
|
apiVersion: QUERY_STORE_API_VERSION,
|
|
1307
|
-
|
|
1308
|
-
...resource && !isDatasetResource(resource) ? { resource } : {}
|
|
1302
|
+
resource
|
|
1309
1303
|
}).observable.pipe(
|
|
1310
1304
|
switchMap(
|
|
1311
1305
|
(client) => defer(
|
|
@@ -1433,8 +1427,7 @@ function findFirstDefined(fieldsToSearch, candidates, exclude) {
|
|
|
1433
1427
|
function transformProjectionToPreview(instance, projectionResult, resource) {
|
|
1434
1428
|
const title = findFirstDefined(TITLE_CANDIDATES, projectionResult.titleCandidates), subtitle = findFirstDefined(SUBTITLE_CANDIDATES, projectionResult.subtitleCandidates, title), client = getClient(instance, {
|
|
1435
1429
|
apiVersion: API_VERSION,
|
|
1436
|
-
|
|
1437
|
-
resource: resource && !isDatasetResource(resource) ? resource : void 0
|
|
1430
|
+
resource
|
|
1438
1431
|
});
|
|
1439
1432
|
return {
|
|
1440
1433
|
title: String(title || `${projectionResult._type}: ${projectionResult._id}`),
|