@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
|
@@ -1,1864 +0,0 @@
|
|
|
1
|
-
import { createClient, CorsOriginError, DisconnectError, ConnectionFailedError } from "@sanity/client";
|
|
2
|
-
import { createImageUrlBuilder } from "@sanity/image-url";
|
|
3
|
-
import "groq";
|
|
4
|
-
import { Observable, map, distinctUntilChanged, shareReplay, skip, defer, finalize, filter, exhaustMap, timer, switchMap, takeWhile, catchError, EMPTY, fromEvent, retry, BehaviorSubject, combineLatest, startWith, tap, pairwise, mergeMap, groupBy, of, share, NEVER, first, firstValueFrom, race, Subscription } from "rxjs";
|
|
5
|
-
import "@sanity/types";
|
|
6
|
-
import { devtools } from "zustand/middleware";
|
|
7
|
-
import { createStore } from "zustand/vanilla";
|
|
8
|
-
import { createSelector } from "reselect";
|
|
9
|
-
function isDatasetResource(resource) {
|
|
10
|
-
return "projectId" in resource && "dataset" in resource;
|
|
11
|
-
}
|
|
12
|
-
function isMediaLibraryResource(resource) {
|
|
13
|
-
return "mediaLibraryId" in resource;
|
|
14
|
-
}
|
|
15
|
-
function isCanvasResource(resource) {
|
|
16
|
-
return "canvasId" in resource;
|
|
17
|
-
}
|
|
18
|
-
function isDatasetSource(source) {
|
|
19
|
-
return isDatasetResource(source);
|
|
20
|
-
}
|
|
21
|
-
function isMediaLibrarySource(source) {
|
|
22
|
-
return isMediaLibraryResource(source);
|
|
23
|
-
}
|
|
24
|
-
function isCanvasSource(source) {
|
|
25
|
-
return isCanvasResource(source);
|
|
26
|
-
}
|
|
27
|
-
const DEFAULT_BASE = "http://localhost", AUTH_CODE_PARAM = "sid", DEFAULT_API_VERSION$1 = "2021-06-07", REQUEST_TAG_PREFIX = "sanity.sdk.auth";
|
|
28
|
-
function resolveAuthMode(config, locationHref) {
|
|
29
|
-
return isStudioConfig(config) ? "studio" : detectDashboardContext(locationHref) ? "dashboard" : "standalone";
|
|
30
|
-
}
|
|
31
|
-
function isStudioConfig(config) {
|
|
32
|
-
return !!config.studio || !!config.studioMode?.enabled;
|
|
33
|
-
}
|
|
34
|
-
function detectDashboardContext(locationHref) {
|
|
35
|
-
try {
|
|
36
|
-
const contextParam = new URL(locationHref, DEFAULT_BASE).searchParams.get("_context");
|
|
37
|
-
if (!contextParam) return !1;
|
|
38
|
-
const parsed = JSON.parse(contextParam);
|
|
39
|
-
return typeof parsed == "object" && parsed !== null && !Array.isArray(parsed) && Object.keys(parsed).length > 0;
|
|
40
|
-
} catch (err) {
|
|
41
|
-
return console.error("Failed to parse dashboard context from initial location:", err), !1;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
var AuthStateType = /* @__PURE__ */ ((AuthStateType2) => (AuthStateType2.LOGGED_IN = "logged-in", AuthStateType2.LOGGING_IN = "logging-in", AuthStateType2.ERROR = "error", AuthStateType2.LOGGED_OUT = "logged-out", AuthStateType2))(AuthStateType || {});
|
|
45
|
-
const isReleasePerspective = (perspective) => typeof perspective == "object" && perspective !== null && "releaseName" in perspective;
|
|
46
|
-
function insecureRandomId() {
|
|
47
|
-
return Array.from({ length: 16 }, () => Math.floor(Math.random() * 16).toString(16)).join("");
|
|
48
|
-
}
|
|
49
|
-
const LOG_LEVEL_PRIORITY = {
|
|
50
|
-
error: 0,
|
|
51
|
-
warn: 1,
|
|
52
|
-
info: 2,
|
|
53
|
-
debug: 3,
|
|
54
|
-
trace: 4
|
|
55
|
-
}, DEFAULT_CONFIG = {
|
|
56
|
-
level: "warn",
|
|
57
|
-
namespaces: [],
|
|
58
|
-
internal: !1,
|
|
59
|
-
timestamps: !0,
|
|
60
|
-
enableInProduction: !1,
|
|
61
|
-
handler: {
|
|
62
|
-
// eslint-disable-next-line no-console
|
|
63
|
-
error: console.error.bind(console),
|
|
64
|
-
// eslint-disable-next-line no-console
|
|
65
|
-
warn: console.warn.bind(console),
|
|
66
|
-
// eslint-disable-next-line no-console
|
|
67
|
-
info: console.info.bind(console),
|
|
68
|
-
// eslint-disable-next-line no-console
|
|
69
|
-
debug: console.debug.bind(console),
|
|
70
|
-
// eslint-disable-next-line no-console
|
|
71
|
-
trace: console.debug.bind(console)
|
|
72
|
-
// trace uses console.debug
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
function parseDebugEnvVar() {
|
|
76
|
-
if (typeof process > "u" || !process.env?.DEBUG)
|
|
77
|
-
return null;
|
|
78
|
-
const debug = process.env.DEBUG;
|
|
79
|
-
if (!debug.includes("sanity"))
|
|
80
|
-
return null;
|
|
81
|
-
const config = {}, levelMatch = debug.match(/sanity:(trace|debug|info|warn|error):/), hasLevelSpecifier = !!levelMatch;
|
|
82
|
-
if (levelMatch ? config.level = levelMatch[1] : config.level = "debug", debug === "sanity")
|
|
83
|
-
config.namespaces = ["*"];
|
|
84
|
-
else if (hasLevelSpecifier && debug.match(/sanity:(trace|debug|info|warn|error):\*/))
|
|
85
|
-
config.namespaces = ["*"];
|
|
86
|
-
else if (!hasLevelSpecifier && debug.includes("sanity:*"))
|
|
87
|
-
config.namespaces = ["*"];
|
|
88
|
-
else {
|
|
89
|
-
const namespaces = debug.split(",").filter((s) => s.includes("sanity:")).map((s) => {
|
|
90
|
-
const cleaned = s.replace(/^sanity:/, "");
|
|
91
|
-
return hasLevelSpecifier && cleaned.match(/^(trace|debug|info|warn|error):/) ? cleaned.split(":").slice(1).join(":") : cleaned.split(":")[0];
|
|
92
|
-
}).filter(Boolean).filter((ns) => ns !== "*");
|
|
93
|
-
namespaces.length > 0 && (config.namespaces = namespaces);
|
|
94
|
-
}
|
|
95
|
-
return debug.includes(":internal") && (config.internal = !0), config;
|
|
96
|
-
}
|
|
97
|
-
const envConfig = parseDebugEnvVar();
|
|
98
|
-
let globalConfig = {
|
|
99
|
-
...DEFAULT_CONFIG,
|
|
100
|
-
...envConfig ?? {}
|
|
101
|
-
};
|
|
102
|
-
envConfig && (["info", "debug", "trace"].includes(globalConfig.level) || globalConfig.level === "warn") && console.info(
|
|
103
|
-
`[${(/* @__PURE__ */ new Date()).toISOString()}] [INFO] [sdk] Logging auto-configured from DEBUG environment variable`,
|
|
104
|
-
{
|
|
105
|
-
level: globalConfig.level,
|
|
106
|
-
namespaces: globalConfig.namespaces,
|
|
107
|
-
internal: globalConfig.internal,
|
|
108
|
-
source: "env:DEBUG",
|
|
109
|
-
value: typeof process < "u" ? process.env?.DEBUG : void 0
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
|
-
function configureLogging(config) {
|
|
113
|
-
globalConfig = {
|
|
114
|
-
...globalConfig,
|
|
115
|
-
...config,
|
|
116
|
-
handler: config.handler ?? globalConfig.handler
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
function isLoggingEnabled() {
|
|
120
|
-
return typeof process < "u" && process.env?.NODE_ENV === "production" ? globalConfig.enableInProduction : !0;
|
|
121
|
-
}
|
|
122
|
-
function isNamespaceEnabled(namespace) {
|
|
123
|
-
return isLoggingEnabled() ? globalConfig.namespaces.includes("*") ? !0 : globalConfig.namespaces.includes(namespace) : !1;
|
|
124
|
-
}
|
|
125
|
-
function isLevelEnabled(level) {
|
|
126
|
-
return isLoggingEnabled() ? LOG_LEVEL_PRIORITY[level] <= LOG_LEVEL_PRIORITY[globalConfig.level] : !1;
|
|
127
|
-
}
|
|
128
|
-
function formatMessage(namespace, level, message, context) {
|
|
129
|
-
const parts = [];
|
|
130
|
-
if (globalConfig.timestamps) {
|
|
131
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
132
|
-
parts.push(`[${timestamp}]`);
|
|
133
|
-
}
|
|
134
|
-
parts.push(`[${level.toUpperCase()}]`), parts.push(`[${namespace}]`);
|
|
135
|
-
const instanceContext = context?.instanceContext;
|
|
136
|
-
return instanceContext && (instanceContext.projectId && parts.push(`[project:${instanceContext.projectId}]`), instanceContext.dataset && parts.push(`[dataset:${instanceContext.dataset}]`), instanceContext.instanceId && parts.push(`[instance:${instanceContext.instanceId.slice(0, 8)}]`)), parts.push(message), [parts.join(" "), context];
|
|
137
|
-
}
|
|
138
|
-
function sanitizeContext(context) {
|
|
139
|
-
if (!context || Object.keys(context).length === 0) return;
|
|
140
|
-
const sanitized = { ...context }, sensitiveKeys = ["token", "password", "secret", "apiKey", "authorization"];
|
|
141
|
-
for (const key of Object.keys(sanitized))
|
|
142
|
-
sensitiveKeys.some((sensitive) => key.toLowerCase().includes(sensitive)) && (sanitized[key] = "[REDACTED]");
|
|
143
|
-
return sanitized;
|
|
144
|
-
}
|
|
145
|
-
function createLogger(namespace, baseContext) {
|
|
146
|
-
const logAtLevel = (level, message, context) => {
|
|
147
|
-
if (!isNamespaceEnabled(namespace) || !isLevelEnabled(level) || context?.internal && !globalConfig.internal) return;
|
|
148
|
-
const mergedContext = { ...baseContext, ...context }, sanitized = sanitizeContext(mergedContext), [formatted, finalContext] = formatMessage(namespace, level, message, sanitized);
|
|
149
|
-
globalConfig.handler[level](formatted, finalContext);
|
|
150
|
-
};
|
|
151
|
-
return {
|
|
152
|
-
namespace,
|
|
153
|
-
error: (message, context) => logAtLevel("error", message, context),
|
|
154
|
-
warn: (message, context) => logAtLevel("warn", message, context),
|
|
155
|
-
info: (message, context) => logAtLevel("info", message, context),
|
|
156
|
-
debug: (message, context) => logAtLevel("debug", message, context),
|
|
157
|
-
trace: (message, context) => logAtLevel("trace", message, { ...context, internal: !0 }),
|
|
158
|
-
isLevelEnabled: (level) => isNamespaceEnabled(namespace) && isLevelEnabled(level),
|
|
159
|
-
child: (childContext) => createLogger(namespace, { ...baseContext, ...childContext }),
|
|
160
|
-
getInstanceContext: () => baseContext?.instanceContext
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
function isObject(value) {
|
|
164
|
-
return typeof value == "object" && value !== null;
|
|
165
|
-
}
|
|
166
|
-
const hasOwn = (value, key) => Object.prototype.hasOwnProperty.call(value, key), isPlainObject = (value) => {
|
|
167
|
-
if (!isObject(value)) return !1;
|
|
168
|
-
const prototype = Object.getPrototypeOf(value);
|
|
169
|
-
return prototype === Object.prototype || prototype === null;
|
|
170
|
-
};
|
|
171
|
-
function omitProperty(value, key) {
|
|
172
|
-
if (!value) return {};
|
|
173
|
-
const { [key]: _omitted, ...rest } = value;
|
|
174
|
-
return rest;
|
|
175
|
-
}
|
|
176
|
-
function pickProperties(value, keys) {
|
|
177
|
-
const result = {};
|
|
178
|
-
for (const key of keys)
|
|
179
|
-
hasOwn(value, key) && (result[key] = value[key]);
|
|
180
|
-
return result;
|
|
181
|
-
}
|
|
182
|
-
const areSetsEqual = (left, right) => {
|
|
183
|
-
if (left.size !== right.size) return !1;
|
|
184
|
-
const unmatched = [...right];
|
|
185
|
-
outer: for (const leftValue of left) {
|
|
186
|
-
for (let index = 0; index < unmatched.length; index++)
|
|
187
|
-
if (isDeepEqual(leftValue, unmatched[index])) {
|
|
188
|
-
unmatched.splice(index, 1);
|
|
189
|
-
continue outer;
|
|
190
|
-
}
|
|
191
|
-
return !1;
|
|
192
|
-
}
|
|
193
|
-
return unmatched.length === 0;
|
|
194
|
-
}, areMapsEqual = (left, right) => {
|
|
195
|
-
if (left.size !== right.size) return !1;
|
|
196
|
-
const unmatched = [...right.entries()];
|
|
197
|
-
outer: for (const [leftKey, leftValue] of left) {
|
|
198
|
-
for (let index = 0; index < unmatched.length; index++) {
|
|
199
|
-
const [rightKey, rightValue] = unmatched[index];
|
|
200
|
-
if (isDeepEqual(leftKey, rightKey) && isDeepEqual(leftValue, rightValue)) {
|
|
201
|
-
unmatched.splice(index, 1);
|
|
202
|
-
continue outer;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return !1;
|
|
206
|
-
}
|
|
207
|
-
return unmatched.length === 0;
|
|
208
|
-
};
|
|
209
|
-
function isDeepEqual(left, right) {
|
|
210
|
-
if (Object.is(left, right)) return !0;
|
|
211
|
-
if (!isObject(left) || !isObject(right)) return !1;
|
|
212
|
-
if (left instanceof Date && right instanceof Date)
|
|
213
|
-
return left.getTime() === right.getTime();
|
|
214
|
-
if (left instanceof RegExp && right instanceof RegExp)
|
|
215
|
-
return left.source === right.source && left.flags === right.flags;
|
|
216
|
-
if (left instanceof Set && right instanceof Set)
|
|
217
|
-
return areSetsEqual(left, right);
|
|
218
|
-
if (left instanceof Map && right instanceof Map)
|
|
219
|
-
return areMapsEqual(left, right);
|
|
220
|
-
if (Array.isArray(left) || Array.isArray(right))
|
|
221
|
-
return !Array.isArray(left) || !Array.isArray(right) || left.length !== right.length ? !1 : left.every((value, index) => isDeepEqual(value, right[index]));
|
|
222
|
-
if (!isPlainObject(left) || !isPlainObject(right)) return !1;
|
|
223
|
-
const leftKeys = Object.keys(left), rightKeys = Object.keys(right);
|
|
224
|
-
if (leftKeys.length !== rightKeys.length) return !1;
|
|
225
|
-
for (const key of leftKeys)
|
|
226
|
-
if (!hasOwn(right, key) || !isDeepEqual(left[key], right[key]))
|
|
227
|
-
return !1;
|
|
228
|
-
return !0;
|
|
229
|
-
}
|
|
230
|
-
function getEnv(key) {
|
|
231
|
-
if (typeof import.meta < "u" && import.meta.env)
|
|
232
|
-
return import.meta.env[key];
|
|
233
|
-
if (typeof process < "u" && process.env)
|
|
234
|
-
return process.env[key];
|
|
235
|
-
if (typeof window < "u" && window.ENV)
|
|
236
|
-
return window.ENV?.[key];
|
|
237
|
-
}
|
|
238
|
-
function createStoreState(initialState, devToolsOptions) {
|
|
239
|
-
const store = createStore()(devtools(() => initialState, devToolsOptions));
|
|
240
|
-
return {
|
|
241
|
-
get: store.getState,
|
|
242
|
-
set: (actionKey, updatedState) => {
|
|
243
|
-
const currentState = store.getState(), nextState = typeof updatedState == "function" ? updatedState(currentState) : updatedState;
|
|
244
|
-
currentState !== nextState && store.setState(nextState, !1, actionKey);
|
|
245
|
-
},
|
|
246
|
-
observable: new Observable((observer) => {
|
|
247
|
-
const emit = () => observer.next(store.getState());
|
|
248
|
-
emit();
|
|
249
|
-
const unsubscribe = store.subscribe(emit);
|
|
250
|
-
return () => unsubscribe();
|
|
251
|
-
})
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
function defineStore(storeDefinition) {
|
|
255
|
-
return storeDefinition;
|
|
256
|
-
}
|
|
257
|
-
function createStoreInstance(instance, key, { name, getInitialState, initialize }) {
|
|
258
|
-
const state = createStoreState(getInitialState(instance, key), {
|
|
259
|
-
enabled: !!getEnv("DEV"),
|
|
260
|
-
name: `${name}-${key.name}`
|
|
261
|
-
}), dispose = initialize?.({ state, instance, key }), disposed = { current: !1 };
|
|
262
|
-
return {
|
|
263
|
-
state,
|
|
264
|
-
dispose: () => {
|
|
265
|
-
disposed.current || (disposed.current = !0, dispose?.());
|
|
266
|
-
},
|
|
267
|
-
isDisposed: () => disposed.current
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
function createActionBinder(keyFn) {
|
|
271
|
-
const instanceRegistry = /* @__PURE__ */ new Map(), storeRegistry = /* @__PURE__ */ new Map();
|
|
272
|
-
return function(storeDefinition, action) {
|
|
273
|
-
return function(instance, ...params) {
|
|
274
|
-
const key = keyFn(instance, ...params), compositeKey = storeDefinition.name + (key.name ? `:${key.name}` : "");
|
|
275
|
-
let instances = instanceRegistry.get(compositeKey);
|
|
276
|
-
instances || (instances = /* @__PURE__ */ new Set(), instanceRegistry.set(compositeKey, instances)), instances.has(instance.instanceId) || (instances.add(instance.instanceId), instance.onDispose(() => {
|
|
277
|
-
instances.delete(instance.instanceId), instances.size === 0 && (storeRegistry.get(compositeKey)?.dispose(), storeRegistry.delete(compositeKey), instanceRegistry.delete(compositeKey));
|
|
278
|
-
}));
|
|
279
|
-
let storeInstance = storeRegistry.get(compositeKey);
|
|
280
|
-
return storeInstance || (storeInstance = createStoreInstance(instance, key, storeDefinition), storeRegistry.set(compositeKey, storeInstance)), action({ instance, state: storeInstance.state, key }, ...params);
|
|
281
|
-
};
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
const createResourceKey = (instance, resource) => {
|
|
285
|
-
let name, resourceForKey;
|
|
286
|
-
if (resource) {
|
|
287
|
-
if (resourceForKey = resource, isDatasetResource(resource))
|
|
288
|
-
name = `${resource.projectId}.${resource.dataset}`;
|
|
289
|
-
else if (isMediaLibraryResource(resource))
|
|
290
|
-
name = `media-library:${resource.mediaLibraryId}`;
|
|
291
|
-
else if (isCanvasResource(resource))
|
|
292
|
-
name = `canvas:${resource.canvasId}`;
|
|
293
|
-
else
|
|
294
|
-
throw new Error(`Received invalid resource: ${JSON.stringify(resource)}`);
|
|
295
|
-
return { name, resource: resourceForKey };
|
|
296
|
-
}
|
|
297
|
-
const { projectId, dataset } = instance.config;
|
|
298
|
-
if (!projectId || !dataset)
|
|
299
|
-
throw new Error("This API requires a project ID and dataset configured.");
|
|
300
|
-
return { name: `${projectId}.${dataset}`, resource: { projectId, dataset } };
|
|
301
|
-
}, bindActionByResource = createActionBinder((instance, { resource }) => createResourceKey(instance, resource)), bindActionByResourceAndPerspective = createActionBinder((instance, options) => {
|
|
302
|
-
const { resource, perspective } = options, utilizedPerspective = perspective ?? instance.config.perspective ?? "drafts";
|
|
303
|
-
let perspectiveKey;
|
|
304
|
-
isReleasePerspective(utilizedPerspective) ? perspectiveKey = utilizedPerspective.releaseName : typeof utilizedPerspective == "string" ? perspectiveKey = utilizedPerspective : perspectiveKey = JSON.stringify(utilizedPerspective);
|
|
305
|
-
const sourceKey = createResourceKey(instance, resource);
|
|
306
|
-
return {
|
|
307
|
-
name: `${sourceKey.name}:${perspectiveKey}`,
|
|
308
|
-
resource: sourceKey.resource,
|
|
309
|
-
perspective: utilizedPerspective
|
|
310
|
-
};
|
|
311
|
-
}), bindActionGlobally = createActionBinder((..._rest) => ({ name: "global" }));
|
|
312
|
-
function createStateSourceAction(options) {
|
|
313
|
-
const selector = typeof options == "function" ? options : options.selector, subscribeHandler = options && "onSubscribe" in options ? options.onSubscribe : void 0, isEqual = options && "isEqual" in options ? options.isEqual ?? Object.is : Object.is, selectorContextCache = /* @__PURE__ */ new WeakMap();
|
|
314
|
-
function stateSourceAction(context, ...params) {
|
|
315
|
-
const { state, instance } = context, getCurrent = (currentState) => {
|
|
316
|
-
if (typeof currentState != "object" || currentState === null)
|
|
317
|
-
throw new Error(
|
|
318
|
-
`Expected store state to be an object but got "${typeof currentState}" instead`
|
|
319
|
-
);
|
|
320
|
-
let instanceCache = selectorContextCache.get(currentState);
|
|
321
|
-
instanceCache || (instanceCache = /* @__PURE__ */ new WeakMap(), selectorContextCache.set(currentState, instanceCache));
|
|
322
|
-
let selectorContext = instanceCache.get(instance);
|
|
323
|
-
return selectorContext || (selectorContext = { state: currentState, instance }, instanceCache.set(instance, selectorContext)), selector(selectorContext, ...params);
|
|
324
|
-
};
|
|
325
|
-
let values = state.observable.pipe(map(getCurrent), distinctUntilChanged(isEqual));
|
|
326
|
-
subscribeHandler && (values = withSubscribeHook(values, () => subscribeHandler(context, ...params)));
|
|
327
|
-
const sharedValues = values.pipe(shareReplay({ bufferSize: 1, refCount: !0 }));
|
|
328
|
-
return {
|
|
329
|
-
getCurrent: () => getCurrent(state.get()),
|
|
330
|
-
subscribe: (onStoreChanged) => {
|
|
331
|
-
const subscription = sharedValues.pipe(skip(1)).subscribe({
|
|
332
|
-
next: () => onStoreChanged?.(),
|
|
333
|
-
// Propagate selector errors to both subscription types
|
|
334
|
-
error: () => onStoreChanged?.()
|
|
335
|
-
});
|
|
336
|
-
return () => {
|
|
337
|
-
subscription.unsubscribe();
|
|
338
|
-
};
|
|
339
|
-
},
|
|
340
|
-
observable: sharedValues
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
return stateSourceAction;
|
|
344
|
-
}
|
|
345
|
-
function withSubscribeHook(obs, fn) {
|
|
346
|
-
return defer(() => {
|
|
347
|
-
const cleanup = fn();
|
|
348
|
-
return cleanup ? obs.pipe(finalize(() => cleanup())) : obs;
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
function getStagingApiHost() {
|
|
352
|
-
if (typeof __SANITY_STAGING__ < "u" && __SANITY_STAGING__ === !0)
|
|
353
|
-
return "https://api.sanity.work";
|
|
354
|
-
}
|
|
355
|
-
const loggers = /* @__PURE__ */ new WeakMap();
|
|
356
|
-
function getAuthLogger(instance) {
|
|
357
|
-
let logger = loggers.get(instance);
|
|
358
|
-
return logger || (logger = createLogger("auth", {
|
|
359
|
-
instanceContext: {
|
|
360
|
-
instanceId: instance.instanceId,
|
|
361
|
-
projectId: instance.config.projectId,
|
|
362
|
-
dataset: instance.config.dataset
|
|
363
|
-
}
|
|
364
|
-
}), loggers.set(instance, logger)), logger;
|
|
365
|
-
}
|
|
366
|
-
const REFRESH_INTERVAL = 720 * 60 * 1e3;
|
|
367
|
-
function createTokenRefreshStream(token, clientFactory, apiHost) {
|
|
368
|
-
return new Observable((subscriber) => {
|
|
369
|
-
const subscription = clientFactory({
|
|
370
|
-
apiVersion: DEFAULT_API_VERSION$1,
|
|
371
|
-
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
372
|
-
useProjectHostname: !1,
|
|
373
|
-
useCdn: !1,
|
|
374
|
-
token,
|
|
375
|
-
ignoreBrowserTokenWarning: !0,
|
|
376
|
-
...apiHost && { apiHost }
|
|
377
|
-
}).observable.request({
|
|
378
|
-
uri: "auth/refresh-token",
|
|
379
|
-
method: "POST",
|
|
380
|
-
tag: "refresh-token",
|
|
381
|
-
body: {
|
|
382
|
-
token
|
|
383
|
-
}
|
|
384
|
-
}).subscribe(subscriber);
|
|
385
|
-
return () => subscription.unsubscribe();
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
function shouldRefreshToken(lastRefresh) {
|
|
389
|
-
return lastRefresh ? Date.now() - lastRefresh >= REFRESH_INTERVAL : !0;
|
|
390
|
-
}
|
|
391
|
-
const refreshStampedToken = ({
|
|
392
|
-
state,
|
|
393
|
-
instance
|
|
394
|
-
}) => {
|
|
395
|
-
const logger = getAuthLogger(instance), { clientFactory, apiHost, storageArea, storageKey } = state.get().options;
|
|
396
|
-
return state.observable.pipe(
|
|
397
|
-
map((storeState) => storeState.authState),
|
|
398
|
-
filter(
|
|
399
|
-
(authState) => authState.type === AuthStateType.LOGGED_IN
|
|
400
|
-
),
|
|
401
|
-
distinctUntilChanged((prev, curr) => prev.token === curr.token),
|
|
402
|
-
filter((authState) => authState.token.includes("-st")),
|
|
403
|
-
// Ensure we only try to refresh stamped tokens
|
|
404
|
-
exhaustMap(
|
|
405
|
-
() => new Observable((subscriber) => {
|
|
406
|
-
const visibilityHandler = () => {
|
|
407
|
-
const currentState = state.get();
|
|
408
|
-
document.visibilityState === "visible" && currentState.authState.type === AuthStateType.LOGGED_IN && shouldRefreshToken(currentState.authState.lastTokenRefresh) && createTokenRefreshStream(
|
|
409
|
-
currentState.authState.token,
|
|
410
|
-
clientFactory,
|
|
411
|
-
apiHost
|
|
412
|
-
).subscribe({
|
|
413
|
-
next: (response) => {
|
|
414
|
-
state.set("setRefreshStampedToken", (prev) => ({
|
|
415
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? {
|
|
416
|
-
...prev.authState,
|
|
417
|
-
token: response.token,
|
|
418
|
-
lastTokenRefresh: Date.now()
|
|
419
|
-
} : prev.authState
|
|
420
|
-
})), subscriber.next(response);
|
|
421
|
-
},
|
|
422
|
-
error: (error) => subscriber.error(error)
|
|
423
|
-
});
|
|
424
|
-
}, timerSubscription = timer(REFRESH_INTERVAL, REFRESH_INTERVAL).pipe(
|
|
425
|
-
filter(() => document.visibilityState === "visible"),
|
|
426
|
-
switchMap(() => {
|
|
427
|
-
const currentState = state.get().authState;
|
|
428
|
-
if (currentState.type !== AuthStateType.LOGGED_IN)
|
|
429
|
-
throw new Error("User logged out before refresh could complete");
|
|
430
|
-
return createTokenRefreshStream(currentState.token, clientFactory, apiHost);
|
|
431
|
-
})
|
|
432
|
-
).subscribe({
|
|
433
|
-
next: (response) => {
|
|
434
|
-
state.set("setRefreshStampedToken", (prev) => ({
|
|
435
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? {
|
|
436
|
-
...prev.authState,
|
|
437
|
-
token: response.token,
|
|
438
|
-
lastTokenRefresh: Date.now()
|
|
439
|
-
} : prev.authState
|
|
440
|
-
})), subscriber.next(response);
|
|
441
|
-
},
|
|
442
|
-
error: (error) => subscriber.error(error)
|
|
443
|
-
});
|
|
444
|
-
return document.addEventListener("visibilitychange", visibilityHandler), () => {
|
|
445
|
-
document.removeEventListener("visibilitychange", visibilityHandler), timerSubscription.unsubscribe();
|
|
446
|
-
};
|
|
447
|
-
}).pipe(
|
|
448
|
-
takeWhile(() => state.get().authState.type === AuthStateType.LOGGED_IN),
|
|
449
|
-
map((response) => ({ token: response.token }))
|
|
450
|
-
)
|
|
451
|
-
)
|
|
452
|
-
).subscribe({
|
|
453
|
-
next: (response) => {
|
|
454
|
-
logger.debug("Token refresh completed, updating state"), state.set("setRefreshStampedToken", (prev) => ({
|
|
455
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? {
|
|
456
|
-
...prev.authState,
|
|
457
|
-
token: response.token,
|
|
458
|
-
lastTokenRefresh: Date.now()
|
|
459
|
-
} : prev.authState
|
|
460
|
-
})), storageArea?.setItem(storageKey, JSON.stringify({ token: response.token }));
|
|
461
|
-
},
|
|
462
|
-
error: (error) => {
|
|
463
|
-
logger.error("Token refresh failed", { error }), state.set("setRefreshStampedTokenError", { authState: { type: AuthStateType.ERROR, error } });
|
|
464
|
-
}
|
|
465
|
-
});
|
|
466
|
-
}, subscribeToStateAndFetchCurrentUser = ({ state, instance }, fetchOptions) => {
|
|
467
|
-
const logger = getAuthLogger(instance), { clientFactory, apiHost } = state.get().options, useProjectHostname = fetchOptions?.useProjectHostname ?? isStudioConfig(instance.config), projectId = instance.config.projectId;
|
|
468
|
-
return state.observable.pipe(
|
|
469
|
-
map(({ authState, options: storeOptions }) => ({
|
|
470
|
-
authState,
|
|
471
|
-
authMethod: storeOptions.authMethod
|
|
472
|
-
})),
|
|
473
|
-
filter(
|
|
474
|
-
(value) => value.authState.type === AuthStateType.LOGGED_IN && !value.authState.currentUser
|
|
475
|
-
),
|
|
476
|
-
map((value) => ({ token: value.authState.token, authMethod: value.authMethod })),
|
|
477
|
-
distinctUntilChanged(
|
|
478
|
-
(prev, curr) => prev.token === curr.token && prev.authMethod === curr.authMethod
|
|
479
|
-
)
|
|
480
|
-
).pipe(
|
|
481
|
-
map(
|
|
482
|
-
({ token, authMethod }) => clientFactory({
|
|
483
|
-
apiVersion: DEFAULT_API_VERSION$1,
|
|
484
|
-
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
485
|
-
token: authMethod === "cookie" ? void 0 : token,
|
|
486
|
-
ignoreBrowserTokenWarning: !0,
|
|
487
|
-
useProjectHostname,
|
|
488
|
-
useCdn: !1,
|
|
489
|
-
...authMethod === "cookie" ? { withCredentials: !0 } : {},
|
|
490
|
-
...useProjectHostname && projectId ? { projectId } : {},
|
|
491
|
-
...apiHost && { apiHost }
|
|
492
|
-
})
|
|
493
|
-
),
|
|
494
|
-
switchMap(
|
|
495
|
-
(client) => client.observable.request({
|
|
496
|
-
uri: "/users/me",
|
|
497
|
-
method: "GET",
|
|
498
|
-
tag: "users.get-current"
|
|
499
|
-
}).pipe(
|
|
500
|
-
/**
|
|
501
|
-
* Catch inside switchMap so the outer subscription survives.
|
|
502
|
-
* Without this, a 401 terminates the subscription permanently
|
|
503
|
-
* and subsequent token refreshes via comlink never re-fetch /users/me.
|
|
504
|
-
* @see SDK-1409
|
|
505
|
-
*/
|
|
506
|
-
catchError((error) => (logger.error("Failed to fetch current user", { error }), state.set("setError", { authState: { type: AuthStateType.ERROR, error } }), EMPTY))
|
|
507
|
-
)
|
|
508
|
-
)
|
|
509
|
-
).subscribe({
|
|
510
|
-
next: (currentUser) => {
|
|
511
|
-
logger.info("Current user fetched successfully", {
|
|
512
|
-
hasEmail: !!currentUser.email
|
|
513
|
-
}), logger.debug("Current user details", { userId: currentUser.id }), state.set("setCurrentUser", (prev) => ({
|
|
514
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? { ...prev.authState, currentUser } : prev.authState
|
|
515
|
-
}));
|
|
516
|
-
}
|
|
517
|
-
});
|
|
518
|
-
};
|
|
519
|
-
function parseDashboardContext(locationHref) {
|
|
520
|
-
try {
|
|
521
|
-
const contextParam = new URL(locationHref, DEFAULT_BASE).searchParams.get("_context");
|
|
522
|
-
if (contextParam) {
|
|
523
|
-
const parsedContext = JSON.parse(contextParam);
|
|
524
|
-
if (parsedContext && typeof parsedContext == "object" && !Array.isArray(parsedContext) && Object.keys(parsedContext).length > 0)
|
|
525
|
-
return delete parsedContext.sid, parsedContext;
|
|
526
|
-
}
|
|
527
|
-
} catch (err) {
|
|
528
|
-
console.error("Failed to parse dashboard context from initial location:", err);
|
|
529
|
-
}
|
|
530
|
-
return {};
|
|
531
|
-
}
|
|
532
|
-
function getDashboardInitialState(options) {
|
|
533
|
-
const { authConfig, initialLocationHref } = options, providedToken = authConfig.token, callbackUrl = authConfig.callbackUrl, storageKey = "__sanity_auth_token", dashboardContext = parseDashboardContext(initialLocationHref), storageArea = void 0;
|
|
534
|
-
return providedToken ? {
|
|
535
|
-
authState: createLoggedInAuthState(providedToken, null),
|
|
536
|
-
storageKey,
|
|
537
|
-
storageArea,
|
|
538
|
-
authMethod: void 0,
|
|
539
|
-
dashboardContext
|
|
540
|
-
} : getAuthCode(callbackUrl, initialLocationHref) || getTokenFromLocation(initialLocationHref) ? {
|
|
541
|
-
authState: { type: AuthStateType.LOGGING_IN, isExchangingToken: !1 },
|
|
542
|
-
storageKey,
|
|
543
|
-
storageArea,
|
|
544
|
-
authMethod: void 0,
|
|
545
|
-
dashboardContext
|
|
546
|
-
} : {
|
|
547
|
-
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 },
|
|
548
|
-
storageKey,
|
|
549
|
-
storageArea,
|
|
550
|
-
authMethod: void 0,
|
|
551
|
-
dashboardContext
|
|
552
|
-
};
|
|
553
|
-
}
|
|
554
|
-
function initializeDashboardAuth(context, tokenRefresherRunning2) {
|
|
555
|
-
const subscriptions = [];
|
|
556
|
-
let startedRefresher = !1;
|
|
557
|
-
return subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !1 })), tokenRefresherRunning2 || (startedRefresher = !0, subscriptions.push(refreshStampedToken(context))), {
|
|
558
|
-
dispose: () => {
|
|
559
|
-
for (const subscription of subscriptions)
|
|
560
|
-
subscription.unsubscribe();
|
|
561
|
-
},
|
|
562
|
-
tokenRefresherStarted: startedRefresher
|
|
563
|
-
};
|
|
564
|
-
}
|
|
565
|
-
const subscribeToStorageEventsAndSetToken = ({
|
|
566
|
-
state
|
|
567
|
-
}) => {
|
|
568
|
-
const { storageArea, storageKey } = state.get().options;
|
|
569
|
-
return defer(getStorageEvents).pipe(
|
|
570
|
-
filter(
|
|
571
|
-
(e) => e.storageArea === storageArea && e.key === storageKey
|
|
572
|
-
),
|
|
573
|
-
map(() => getTokenFromStorage(storageArea, storageKey)),
|
|
574
|
-
distinctUntilChanged()
|
|
575
|
-
).subscribe((token) => {
|
|
576
|
-
state.set("updateTokenFromStorageEvent", {
|
|
577
|
-
authState: token ? createLoggedInAuthState(token, null) : { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
|
|
578
|
-
});
|
|
579
|
-
});
|
|
580
|
-
};
|
|
581
|
-
function getStandaloneInitialState(options) {
|
|
582
|
-
const { authConfig, initialLocationHref } = options, providedToken = authConfig.token, callbackUrl = authConfig.callbackUrl, storageKey = "__sanity_auth_token", storageArea = authConfig.storageArea ?? getDefaultStorage();
|
|
583
|
-
if (providedToken)
|
|
584
|
-
return {
|
|
585
|
-
authState: createLoggedInAuthState(providedToken, null),
|
|
586
|
-
storageKey,
|
|
587
|
-
storageArea,
|
|
588
|
-
authMethod: void 0,
|
|
589
|
-
dashboardContext: {}
|
|
590
|
-
};
|
|
591
|
-
if (getAuthCode(callbackUrl, initialLocationHref) || getTokenFromLocation(initialLocationHref))
|
|
592
|
-
return {
|
|
593
|
-
authState: { type: AuthStateType.LOGGING_IN, isExchangingToken: !1 },
|
|
594
|
-
storageKey,
|
|
595
|
-
storageArea,
|
|
596
|
-
authMethod: void 0,
|
|
597
|
-
dashboardContext: {}
|
|
598
|
-
};
|
|
599
|
-
const token = getTokenFromStorage(storageArea, storageKey);
|
|
600
|
-
return token ? {
|
|
601
|
-
authState: createLoggedInAuthState(token, null),
|
|
602
|
-
storageKey,
|
|
603
|
-
storageArea,
|
|
604
|
-
authMethod: "localstorage",
|
|
605
|
-
dashboardContext: {}
|
|
606
|
-
} : {
|
|
607
|
-
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 },
|
|
608
|
-
storageKey,
|
|
609
|
-
storageArea,
|
|
610
|
-
authMethod: void 0,
|
|
611
|
-
dashboardContext: {}
|
|
612
|
-
};
|
|
613
|
-
}
|
|
614
|
-
function initializeStandaloneAuth(context, tokenRefresherRunning2) {
|
|
615
|
-
const subscriptions = [];
|
|
616
|
-
let startedRefresher = !1;
|
|
617
|
-
return subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !1 })), context.state.get().options?.storageArea && subscriptions.push(subscribeToStorageEventsAndSetToken(context)), tokenRefresherRunning2 || (startedRefresher = !0, subscriptions.push(refreshStampedToken(context))), {
|
|
618
|
-
dispose: () => {
|
|
619
|
-
for (const subscription of subscriptions)
|
|
620
|
-
subscription.unsubscribe();
|
|
621
|
-
},
|
|
622
|
-
tokenRefresherStarted: startedRefresher
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
const COOKIE_AUTH_TIMEOUT_MS = 1e4;
|
|
626
|
-
async function checkForCookieAuth(projectId, clientFactory) {
|
|
627
|
-
if (!projectId) return !1;
|
|
628
|
-
try {
|
|
629
|
-
const user = await clientFactory({
|
|
630
|
-
projectId,
|
|
631
|
-
useCdn: !1,
|
|
632
|
-
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
633
|
-
timeout: COOKIE_AUTH_TIMEOUT_MS
|
|
634
|
-
}).request({
|
|
635
|
-
uri: "/users/me",
|
|
636
|
-
withCredentials: !0,
|
|
637
|
-
tag: "users.get-current"
|
|
638
|
-
});
|
|
639
|
-
return user != null && typeof user == "object" && typeof user.id == "string";
|
|
640
|
-
} catch {
|
|
641
|
-
return !1;
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
function getStudioTokenFromLocalStorage(storageArea, storageKey) {
|
|
645
|
-
return !storageArea || !storageKey ? null : getTokenFromStorage(storageArea, storageKey) || null;
|
|
646
|
-
}
|
|
647
|
-
function getStudioInitialState(options) {
|
|
648
|
-
const { authConfig, projectId, tokenSource } = options, storageArea = authConfig.storageArea ?? getDefaultStorage(), studioStorageKey = `__studio_auth_token_${projectId ?? ""}`;
|
|
649
|
-
if (tokenSource)
|
|
650
|
-
return {
|
|
651
|
-
authState: { type: AuthStateType.LOGGING_IN, isExchangingToken: !1 },
|
|
652
|
-
storageKey: studioStorageKey,
|
|
653
|
-
storageArea,
|
|
654
|
-
authMethod: void 0,
|
|
655
|
-
dashboardContext: {}
|
|
656
|
-
};
|
|
657
|
-
const providedToken = authConfig.token;
|
|
658
|
-
let authMethod;
|
|
659
|
-
const token = getStudioTokenFromLocalStorage(storageArea, studioStorageKey);
|
|
660
|
-
return token && (authMethod = "localstorage"), providedToken ? {
|
|
661
|
-
authState: createLoggedInAuthState(providedToken, null),
|
|
662
|
-
storageKey: studioStorageKey,
|
|
663
|
-
storageArea,
|
|
664
|
-
authMethod,
|
|
665
|
-
dashboardContext: {}
|
|
666
|
-
} : token ? {
|
|
667
|
-
authState: createLoggedInAuthState(token, null),
|
|
668
|
-
storageKey: studioStorageKey,
|
|
669
|
-
storageArea,
|
|
670
|
-
authMethod: "localstorage",
|
|
671
|
-
dashboardContext: {}
|
|
672
|
-
} : {
|
|
673
|
-
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 },
|
|
674
|
-
storageKey: studioStorageKey,
|
|
675
|
-
storageArea,
|
|
676
|
-
authMethod: void 0,
|
|
677
|
-
dashboardContext: {}
|
|
678
|
-
};
|
|
679
|
-
}
|
|
680
|
-
function initializeStudioAuth(context, tokenRefresherRunning2) {
|
|
681
|
-
const tokenSource = context.instance.config.studio?.auth?.token;
|
|
682
|
-
return tokenSource ? initializeWithTokenSource(context, tokenSource) : initializeWithFallback(context, tokenRefresherRunning2);
|
|
683
|
-
}
|
|
684
|
-
function initializeWithTokenSource(context, tokenSource) {
|
|
685
|
-
const subscriptions = [], studioAuthenticated = context.instance.config.studio?.authenticated === !0;
|
|
686
|
-
subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !0 }));
|
|
687
|
-
const tokenSub = tokenSource.subscribe({
|
|
688
|
-
next: (token) => {
|
|
689
|
-
const { state } = context;
|
|
690
|
-
token ? state.set("studioTokenSource", (prev) => ({
|
|
691
|
-
options: { ...prev.options, authMethod: void 0 },
|
|
692
|
-
authState: createLoggedInAuthState(token, null)
|
|
693
|
-
})) : studioAuthenticated ? state.set("studioTokenSourceCookieAuth", (prev) => ({
|
|
694
|
-
options: { ...prev.options, authMethod: "cookie" },
|
|
695
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? prev.authState : createLoggedInAuthState("", null)
|
|
696
|
-
})) : state.set("studioTokenSourceLoggedOut", (prev) => ({
|
|
697
|
-
options: { ...prev.options, authMethod: void 0 },
|
|
698
|
-
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
|
|
699
|
-
}));
|
|
700
|
-
}
|
|
701
|
-
});
|
|
702
|
-
return {
|
|
703
|
-
dispose: () => {
|
|
704
|
-
tokenSub.unsubscribe();
|
|
705
|
-
for (const subscription of subscriptions)
|
|
706
|
-
subscription.unsubscribe();
|
|
707
|
-
},
|
|
708
|
-
// Studio handles token refresh — do not start the SDK's refresher
|
|
709
|
-
tokenRefresherStarted: !1
|
|
710
|
-
};
|
|
711
|
-
}
|
|
712
|
-
function initializeWithFallback(context, tokenRefresherRunning2) {
|
|
713
|
-
const subscriptions = [];
|
|
714
|
-
let startedRefresher = !1;
|
|
715
|
-
subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !0 })), context.state.get().options?.storageArea && subscriptions.push(subscribeToStorageEventsAndSetToken(context));
|
|
716
|
-
try {
|
|
717
|
-
const { instance, state } = context;
|
|
718
|
-
if (!(state.get().authState?.type === AuthStateType.LOGGED_IN && state.get().authState.token)) {
|
|
719
|
-
const projectIdValue = instance.config.projectId, clientFactory = state.get().options.clientFactory;
|
|
720
|
-
checkForCookieAuth(projectIdValue, clientFactory).then((isCookieAuthEnabled) => {
|
|
721
|
-
isCookieAuthEnabled && state.set("enableCookieAuth", (prev) => ({
|
|
722
|
-
options: { ...prev.options, authMethod: "cookie" },
|
|
723
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? prev.authState : createLoggedInAuthState("", null)
|
|
724
|
-
}));
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
|
-
} catch {
|
|
728
|
-
}
|
|
729
|
-
return tokenRefresherRunning2 || (startedRefresher = !0, subscriptions.push(refreshStampedToken(context))), {
|
|
730
|
-
dispose: () => {
|
|
731
|
-
for (const subscription of subscriptions)
|
|
732
|
-
subscription.unsubscribe();
|
|
733
|
-
},
|
|
734
|
-
tokenRefresherStarted: startedRefresher
|
|
735
|
-
};
|
|
736
|
-
}
|
|
737
|
-
let tokenRefresherRunning = !1;
|
|
738
|
-
const authStore = {
|
|
739
|
-
name: "Auth",
|
|
740
|
-
getInitialState(instance) {
|
|
741
|
-
const logger = getAuthLogger(instance);
|
|
742
|
-
logger.debug("Initializing auth store", {
|
|
743
|
-
hasProvidedToken: !!instance.config.auth?.token,
|
|
744
|
-
hasCustomProviders: !!(instance.config.auth?.providers && instance.config.auth.providers.length > 0),
|
|
745
|
-
studioMode: instance.config.studioMode?.enabled ?? !1
|
|
746
|
-
});
|
|
747
|
-
const {
|
|
748
|
-
apiHost: configApiHost,
|
|
749
|
-
callbackUrl,
|
|
750
|
-
providers: customProviders,
|
|
751
|
-
token: providedToken,
|
|
752
|
-
clientFactory = createClient,
|
|
753
|
-
initialLocationHref = getDefaultLocation()
|
|
754
|
-
} = instance.config.auth ?? {}, apiHost = configApiHost ?? getStagingApiHost(), authConfig = instance.config.auth ?? {};
|
|
755
|
-
let loginDomain = "https://www.sanity.io";
|
|
756
|
-
try {
|
|
757
|
-
apiHost && new URL(apiHost).hostname.endsWith(".sanity.work") && (loginDomain = "https://www.sanity.work");
|
|
758
|
-
} catch {
|
|
759
|
-
}
|
|
760
|
-
const loginUrl = new URL("/login", loginDomain);
|
|
761
|
-
loginUrl.searchParams.set("origin", getCleanedUrl(initialLocationHref)), loginUrl.searchParams.set("type", "stampedToken"), loginUrl.searchParams.set("withSid", "true");
|
|
762
|
-
const mode = resolveAuthMode(instance.config, initialLocationHref), strategyOptions = {
|
|
763
|
-
authConfig,
|
|
764
|
-
projectId: instance.config.projectId,
|
|
765
|
-
initialLocationHref,
|
|
766
|
-
tokenSource: instance.config.studio?.auth?.token
|
|
767
|
-
};
|
|
768
|
-
let result;
|
|
769
|
-
switch (mode) {
|
|
770
|
-
case "studio":
|
|
771
|
-
result = getStudioInitialState(strategyOptions);
|
|
772
|
-
break;
|
|
773
|
-
case "dashboard":
|
|
774
|
-
result = getDashboardInitialState(strategyOptions);
|
|
775
|
-
break;
|
|
776
|
-
case "standalone":
|
|
777
|
-
result = getStandaloneInitialState(strategyOptions);
|
|
778
|
-
break;
|
|
779
|
-
}
|
|
780
|
-
return logger.debug("Auth state initialized", {
|
|
781
|
-
authStateType: result.authState.type,
|
|
782
|
-
mode,
|
|
783
|
-
authMethod: result.authMethod
|
|
784
|
-
}), {
|
|
785
|
-
authState: result.authState,
|
|
786
|
-
dashboardContext: result.dashboardContext,
|
|
787
|
-
options: {
|
|
788
|
-
apiHost,
|
|
789
|
-
loginUrl: loginUrl.toString(),
|
|
790
|
-
callbackUrl,
|
|
791
|
-
customProviders,
|
|
792
|
-
providedToken,
|
|
793
|
-
clientFactory,
|
|
794
|
-
initialLocationHref,
|
|
795
|
-
storageKey: result.storageKey,
|
|
796
|
-
storageArea: result.storageArea,
|
|
797
|
-
authMethod: result.authMethod
|
|
798
|
-
}
|
|
799
|
-
};
|
|
800
|
-
},
|
|
801
|
-
initialize(context) {
|
|
802
|
-
const logger = getAuthLogger(context.instance), initialLocationHref = context.state.get().options?.initialLocationHref ?? getDefaultLocation(), mode = resolveAuthMode(context.instance.config, initialLocationHref);
|
|
803
|
-
logger.debug("Setting up auth subscriptions", { mode });
|
|
804
|
-
let initResult;
|
|
805
|
-
switch (mode) {
|
|
806
|
-
case "studio":
|
|
807
|
-
initResult = initializeStudioAuth(context, tokenRefresherRunning);
|
|
808
|
-
break;
|
|
809
|
-
case "dashboard":
|
|
810
|
-
initResult = initializeDashboardAuth(context, tokenRefresherRunning);
|
|
811
|
-
break;
|
|
812
|
-
case "standalone":
|
|
813
|
-
initResult = initializeStandaloneAuth(context, tokenRefresherRunning);
|
|
814
|
-
break;
|
|
815
|
-
}
|
|
816
|
-
return initResult.tokenRefresherStarted && (tokenRefresherRunning = !0), () => {
|
|
817
|
-
logger.debug("Cleaning up auth subscriptions"), initResult.dispose();
|
|
818
|
-
};
|
|
819
|
-
}
|
|
820
|
-
}, getCurrentUserState = bindActionGlobally(
|
|
821
|
-
authStore,
|
|
822
|
-
createStateSourceAction(
|
|
823
|
-
({ state: { authState } }) => authState.type === AuthStateType.LOGGED_IN ? authState.currentUser : null
|
|
824
|
-
)
|
|
825
|
-
), getTokenState = bindActionGlobally(
|
|
826
|
-
authStore,
|
|
827
|
-
createStateSourceAction(
|
|
828
|
-
({ state: { authState } }) => authState.type === AuthStateType.LOGGED_IN ? authState.token : null
|
|
829
|
-
)
|
|
830
|
-
), getAuthMethodState = bindActionGlobally(
|
|
831
|
-
authStore,
|
|
832
|
-
createStateSourceAction(({ state: { options } }) => options.authMethod)
|
|
833
|
-
), getLoginUrlState = bindActionGlobally(
|
|
834
|
-
authStore,
|
|
835
|
-
createStateSourceAction(({ state: { options } }) => options.loginUrl)
|
|
836
|
-
), getAuthState = bindActionGlobally(
|
|
837
|
-
authStore,
|
|
838
|
-
createStateSourceAction(({ state: { authState } }) => authState)
|
|
839
|
-
), getDashboardOrganizationId = bindActionGlobally(
|
|
840
|
-
authStore,
|
|
841
|
-
createStateSourceAction(({ state: { dashboardContext } }) => dashboardContext?.orgId)
|
|
842
|
-
), getIsInDashboardState = bindActionGlobally(
|
|
843
|
-
authStore,
|
|
844
|
-
createStateSourceAction(
|
|
845
|
-
({ state: { dashboardContext } }) => (
|
|
846
|
-
// Check if dashboardContext exists and is not empty
|
|
847
|
-
!!dashboardContext && Object.keys(dashboardContext).length > 0
|
|
848
|
-
)
|
|
849
|
-
)
|
|
850
|
-
), setAuthToken = bindActionGlobally(
|
|
851
|
-
authStore,
|
|
852
|
-
({ state, instance }, token) => {
|
|
853
|
-
const logger = getAuthLogger(instance), currentAuthState = state.get().authState;
|
|
854
|
-
if (token) {
|
|
855
|
-
if (currentAuthState.type !== AuthStateType.LOGGED_IN || currentAuthState.token !== token) {
|
|
856
|
-
logger.info("Setting auth token");
|
|
857
|
-
const currentUser = currentAuthState.type === AuthStateType.LOGGED_IN ? currentAuthState.currentUser : null, preservedLastTokenRefresh = currentAuthState.type === AuthStateType.LOGGED_IN ? currentAuthState.lastTokenRefresh : void 0;
|
|
858
|
-
state.set("setToken", {
|
|
859
|
-
authState: createLoggedInAuthState(token, currentUser, preservedLastTokenRefresh)
|
|
860
|
-
});
|
|
861
|
-
}
|
|
862
|
-
} else
|
|
863
|
-
currentAuthState.type !== AuthStateType.LOGGED_OUT && (logger.info("Clearing auth token"), state.set("setToken", {
|
|
864
|
-
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
|
|
865
|
-
}));
|
|
866
|
-
}
|
|
867
|
-
);
|
|
868
|
-
var authStore$1 = /* @__PURE__ */ Object.freeze({
|
|
869
|
-
__proto__: null,
|
|
870
|
-
authStore,
|
|
871
|
-
getAuthMethodState,
|
|
872
|
-
getAuthState,
|
|
873
|
-
getCurrentUserState,
|
|
874
|
-
getDashboardOrganizationId,
|
|
875
|
-
getIsInDashboardState,
|
|
876
|
-
getLoginUrlState,
|
|
877
|
-
getTokenState,
|
|
878
|
-
setAuthToken
|
|
879
|
-
});
|
|
880
|
-
function createLoggedInAuthState(token, currentUser, existingLastTokenRefresh) {
|
|
881
|
-
const isStampedToken = token.includes("-st"), lastTokenRefresh = existingLastTokenRefresh ?? (isStampedToken ? Date.now() : void 0);
|
|
882
|
-
return {
|
|
883
|
-
type: AuthStateType.LOGGED_IN,
|
|
884
|
-
token,
|
|
885
|
-
currentUser,
|
|
886
|
-
...lastTokenRefresh !== void 0 && { lastTokenRefresh }
|
|
887
|
-
};
|
|
888
|
-
}
|
|
889
|
-
function getAuthCode(callbackUrl, locationHref) {
|
|
890
|
-
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;
|
|
891
|
-
let authCode = new URLSearchParams(loc.hash.slice(1)).get(AUTH_CODE_PARAM) || new URLSearchParams(loc.search).get(AUTH_CODE_PARAM);
|
|
892
|
-
if (!authCode) {
|
|
893
|
-
const contextParam = new URLSearchParams(loc.search).get("_context");
|
|
894
|
-
if (contextParam)
|
|
895
|
-
try {
|
|
896
|
-
const parsedContext = JSON.parse(contextParam);
|
|
897
|
-
parsedContext && typeof parsedContext == "object" && typeof parsedContext.sid == "string" && parsedContext.sid && (authCode = parsedContext.sid);
|
|
898
|
-
} catch {
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
return authCode && callbackLocationMatches ? authCode : null;
|
|
902
|
-
}
|
|
903
|
-
function getTokenFromLocation(locationHref) {
|
|
904
|
-
const loc = new URL(locationHref);
|
|
905
|
-
return new URLSearchParams(loc.hash.slice(1)).get("token") || null;
|
|
906
|
-
}
|
|
907
|
-
function getTokenFromStorage(storageArea, storageKey) {
|
|
908
|
-
if (!storageArea) return null;
|
|
909
|
-
const item = storageArea.getItem(storageKey);
|
|
910
|
-
if (item === null) return null;
|
|
911
|
-
try {
|
|
912
|
-
const parsed = JSON.parse(item);
|
|
913
|
-
if (typeof parsed != "object" || parsed === null || !("token" in parsed) || typeof parsed.token != "string")
|
|
914
|
-
throw new Error("Invalid stored auth data structure");
|
|
915
|
-
return parsed.token;
|
|
916
|
-
} catch {
|
|
917
|
-
return storageArea.removeItem(storageKey), null;
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
function getStorageEvents() {
|
|
921
|
-
return typeof window < "u" && typeof window.addEventListener == "function" ? fromEvent(window, "storage") : EMPTY;
|
|
922
|
-
}
|
|
923
|
-
function getDefaultStorage() {
|
|
924
|
-
try {
|
|
925
|
-
return typeof localStorage < "u" && typeof localStorage.getItem == "function" ? localStorage : void 0;
|
|
926
|
-
} catch {
|
|
927
|
-
return;
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
function getDefaultLocation() {
|
|
931
|
-
try {
|
|
932
|
-
return typeof location > "u" ? DEFAULT_BASE : typeof location.href == "string" ? location.href : DEFAULT_BASE;
|
|
933
|
-
} catch {
|
|
934
|
-
return DEFAULT_BASE;
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
function getCleanedUrl(locationUrl) {
|
|
938
|
-
const loc = new URL(locationUrl), rawHash = loc.hash.startsWith("#") ? loc.hash.slice(1) : loc.hash;
|
|
939
|
-
if (rawHash && rawHash.includes("=")) {
|
|
940
|
-
const hashParams = new URLSearchParams(rawHash);
|
|
941
|
-
hashParams.delete("token"), hashParams.delete("withSid");
|
|
942
|
-
const nextHash = hashParams.toString();
|
|
943
|
-
loc.hash = nextHash ? `#${nextHash}` : "";
|
|
944
|
-
}
|
|
945
|
-
return loc.searchParams.delete("sid"), loc.searchParams.delete("url"), loc.toString();
|
|
946
|
-
}
|
|
947
|
-
function getClientErrorApiBody(error) {
|
|
948
|
-
const body = error.response?.body;
|
|
949
|
-
return body && typeof body == "object" ? body : void 0;
|
|
950
|
-
}
|
|
951
|
-
function getClientErrorApiType(error) {
|
|
952
|
-
const body = getClientErrorApiBody(error);
|
|
953
|
-
return body?.error?.type ?? body?.type;
|
|
954
|
-
}
|
|
955
|
-
function getClientErrorApiDescription(error) {
|
|
956
|
-
const body = getClientErrorApiBody(error);
|
|
957
|
-
return body?.error?.description ?? body?.description;
|
|
958
|
-
}
|
|
959
|
-
function isProjectUserNotFoundClientError(error) {
|
|
960
|
-
return getClientErrorApiType(error) === "projectUserNotFoundError";
|
|
961
|
-
}
|
|
962
|
-
const TITLE_CANDIDATES = ["title", "name", "label", "heading", "header", "caption"], SUBTITLE_CANDIDATES = ["description", "subtitle", ...TITLE_CANDIDATES], PREVIEW_PROJECTION = `{
|
|
963
|
-
// Get all potential title fields
|
|
964
|
-
"titleCandidates": {
|
|
965
|
-
${TITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(`,
|
|
966
|
-
`)}
|
|
967
|
-
},
|
|
968
|
-
// Get all potential subtitle fields
|
|
969
|
-
"subtitleCandidates": {
|
|
970
|
-
${SUBTITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(`,
|
|
971
|
-
`)}
|
|
972
|
-
},
|
|
973
|
-
"media": coalesce(
|
|
974
|
-
select(
|
|
975
|
-
defined(asset) => {"type": "image-asset", "_ref": asset._ref},
|
|
976
|
-
defined(image.asset) => {"type": "image-asset", "_ref": image.asset._ref},
|
|
977
|
-
defined(mainImage.asset) => {"type": "image-asset", "_ref": mainImage.asset._ref},
|
|
978
|
-
null
|
|
979
|
-
)
|
|
980
|
-
),
|
|
981
|
-
_type,
|
|
982
|
-
_id,
|
|
983
|
-
_updatedAt
|
|
984
|
-
}`, DEFAULT_API_VERSION = "2024-11-12", DEFAULT_REQUEST_TAG_PREFIX = "sanity.sdk", allowedKeys = Object.keys({
|
|
985
|
-
apiHost: null,
|
|
986
|
-
useCdn: null,
|
|
987
|
-
token: null,
|
|
988
|
-
perspective: null,
|
|
989
|
-
proxy: null,
|
|
990
|
-
withCredentials: null,
|
|
991
|
-
timeout: null,
|
|
992
|
-
maxRetries: null,
|
|
993
|
-
dataset: null,
|
|
994
|
-
projectId: null,
|
|
995
|
-
scope: null,
|
|
996
|
-
apiVersion: null,
|
|
997
|
-
requestTagPrefix: null,
|
|
998
|
-
useProjectHostname: null,
|
|
999
|
-
resource: null
|
|
1000
|
-
}), DEFAULT_CLIENT_CONFIG = {
|
|
1001
|
-
apiVersion: DEFAULT_API_VERSION,
|
|
1002
|
-
useCdn: !1,
|
|
1003
|
-
ignoreBrowserTokenWarning: !0,
|
|
1004
|
-
allowReconfigure: !1,
|
|
1005
|
-
requestTagPrefix: DEFAULT_REQUEST_TAG_PREFIX
|
|
1006
|
-
}, clientStore = {
|
|
1007
|
-
name: "clientStore",
|
|
1008
|
-
getInitialState: (instance) => ({
|
|
1009
|
-
clients: {},
|
|
1010
|
-
token: getTokenState(instance).getCurrent()
|
|
1011
|
-
}),
|
|
1012
|
-
initialize(context) {
|
|
1013
|
-
const subscription = listenToToken(context), authMethodSubscription = listenToAuthMethod(context);
|
|
1014
|
-
return () => {
|
|
1015
|
-
subscription.unsubscribe(), authMethodSubscription.unsubscribe();
|
|
1016
|
-
};
|
|
1017
|
-
}
|
|
1018
|
-
}, listenToToken = ({ instance, state }) => getTokenState(instance).observable.subscribe((token) => {
|
|
1019
|
-
state.set("setTokenAndResetClients", { token, clients: {} });
|
|
1020
|
-
}), listenToAuthMethod = ({ instance, state }) => getAuthMethodState(instance).observable.subscribe((authMethod) => {
|
|
1021
|
-
state.set("setAuthMethod", { authMethod });
|
|
1022
|
-
}), getClientConfigKey = (options) => JSON.stringify(pickProperties(options, allowedKeys)), getClient = bindActionGlobally(
|
|
1023
|
-
clientStore,
|
|
1024
|
-
({ state, instance }, options) => {
|
|
1025
|
-
if (!options || typeof options != "object")
|
|
1026
|
-
throw new Error(
|
|
1027
|
-
'getClient() requires a configuration object with at least an "apiVersion" property. Example: getClient(instance, { apiVersion: "2024-11-12" })'
|
|
1028
|
-
);
|
|
1029
|
-
const disallowedKeys = Object.keys(options).filter((key2) => !allowedKeys.includes(key2));
|
|
1030
|
-
if (disallowedKeys.length > 0) {
|
|
1031
|
-
const listFormatter = new Intl.ListFormat("en", { style: "long", type: "conjunction" });
|
|
1032
|
-
throw new Error(
|
|
1033
|
-
`The client options provided contains unsupported properties: ${listFormatter.format(disallowedKeys)}. Allowed keys are: ${listFormatter.format(allowedKeys)}.`
|
|
1034
|
-
);
|
|
1035
|
-
}
|
|
1036
|
-
const tokenFromState = state.get().token, { clients, authMethod } = state.get();
|
|
1037
|
-
let projectId = options.projectId ?? instance.config.projectId, dataset = options.dataset ?? instance.config.dataset, resource;
|
|
1038
|
-
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));
|
|
1039
|
-
const apiHost = options.apiHost ?? instance.config.auth?.apiHost ?? getStagingApiHost(), effectiveOptions = {
|
|
1040
|
-
...DEFAULT_CLIENT_CONFIG,
|
|
1041
|
-
...(options.scope === "global" || !projectId || resource) && { useProjectHostname: !1 },
|
|
1042
|
-
token: authMethod === "cookie" ? void 0 : tokenFromState ?? void 0,
|
|
1043
|
-
...options,
|
|
1044
|
-
...projectId && { projectId },
|
|
1045
|
-
...dataset && { dataset },
|
|
1046
|
-
...resource ? { resource } : { resource: void 0 },
|
|
1047
|
-
...apiHost && { apiHost }
|
|
1048
|
-
};
|
|
1049
|
-
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;
|
|
1050
|
-
const key = getClientConfigKey(effectiveOptions);
|
|
1051
|
-
if (clients[key]) return clients[key];
|
|
1052
|
-
const client = createClient(effectiveOptions);
|
|
1053
|
-
return state.set("addClient", (prev) => ({ clients: { ...prev.clients, [key]: client } })), client;
|
|
1054
|
-
}
|
|
1055
|
-
), getClientState = bindActionGlobally(
|
|
1056
|
-
clientStore,
|
|
1057
|
-
createStateSourceAction(({ instance }, options) => getClient(instance, options))
|
|
1058
|
-
);
|
|
1059
|
-
var clientStore$1 = /* @__PURE__ */ Object.freeze({
|
|
1060
|
-
__proto__: null,
|
|
1061
|
-
getClient,
|
|
1062
|
-
getClientState
|
|
1063
|
-
});
|
|
1064
|
-
const API_VERSION$1 = "v2025-05-06";
|
|
1065
|
-
function hasImageRef(value) {
|
|
1066
|
-
return isObject(value) && "_ref" in value && typeof value._ref == "string";
|
|
1067
|
-
}
|
|
1068
|
-
function normalizeMedia(media, client) {
|
|
1069
|
-
if (!media || !hasImageRef(media)) return null;
|
|
1070
|
-
const url = createImageUrlBuilder(client).image({ _ref: media._ref }).url();
|
|
1071
|
-
return {
|
|
1072
|
-
type: "image-asset",
|
|
1073
|
-
_ref: media._ref,
|
|
1074
|
-
url
|
|
1075
|
-
};
|
|
1076
|
-
}
|
|
1077
|
-
function findFirstDefined(fieldsToSearch, candidates, exclude) {
|
|
1078
|
-
if (candidates)
|
|
1079
|
-
for (const field of fieldsToSearch) {
|
|
1080
|
-
const value = candidates[field];
|
|
1081
|
-
if (typeof value == "string" && value.trim() !== "" && value !== exclude)
|
|
1082
|
-
return value;
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
function transformProjectionToPreview(instance, projectionResult, resource) {
|
|
1086
|
-
const title = findFirstDefined(TITLE_CANDIDATES, projectionResult.titleCandidates), subtitle = findFirstDefined(SUBTITLE_CANDIDATES, projectionResult.subtitleCandidates, title), client = getClient(instance, {
|
|
1087
|
-
apiVersion: API_VERSION$1,
|
|
1088
|
-
resource
|
|
1089
|
-
});
|
|
1090
|
-
return {
|
|
1091
|
-
title: String(title || `${projectionResult._type}: ${projectionResult._id}`),
|
|
1092
|
-
subtitle: subtitle || void 0,
|
|
1093
|
-
media: normalizeMedia(projectionResult.media, client),
|
|
1094
|
-
...projectionResult._status && { _status: projectionResult._status }
|
|
1095
|
-
};
|
|
1096
|
-
}
|
|
1097
|
-
const LIVE_EVENTS_API_VERSION = "v2025-05-06", LIVE_EVENTS_RETRY_DELAY = 1e3;
|
|
1098
|
-
function observeLiveEvents(instance, { resource, onCorsError }) {
|
|
1099
|
-
return getClientState(instance, {
|
|
1100
|
-
apiVersion: LIVE_EVENTS_API_VERSION,
|
|
1101
|
-
resource
|
|
1102
|
-
}).observable.pipe(
|
|
1103
|
-
switchMap(
|
|
1104
|
-
(client) => defer(
|
|
1105
|
-
() => client.live.events({ includeDrafts: !!client.config().token, tag: "live-events" })
|
|
1106
|
-
).pipe(
|
|
1107
|
-
catchError((error) => {
|
|
1108
|
-
if (error instanceof CorsOriginError)
|
|
1109
|
-
return onCorsError(error), EMPTY;
|
|
1110
|
-
if (error instanceof DisconnectError)
|
|
1111
|
-
return EMPTY;
|
|
1112
|
-
if (error instanceof ConnectionFailedError && typeof error.status == "number" && error.status >= 400 && error.status < 500)
|
|
1113
|
-
return EMPTY;
|
|
1114
|
-
throw error;
|
|
1115
|
-
}),
|
|
1116
|
-
// Server-initiated live errors (e.g. ChannelError, MessageError) are
|
|
1117
|
-
// retried, not surfaced. Dropped connections are already reconnected
|
|
1118
|
-
// inside @sanity/client.
|
|
1119
|
-
retry({ delay: LIVE_EVENTS_RETRY_DELAY })
|
|
1120
|
-
)
|
|
1121
|
-
),
|
|
1122
|
-
filter((e) => e.type === "message")
|
|
1123
|
-
);
|
|
1124
|
-
}
|
|
1125
|
-
const RELEASES_QUERY = "releases::all()", RELEASES_API_VERSION = "v2025-05-06";
|
|
1126
|
-
function observeReleases(instance, { resource, onCorsError }) {
|
|
1127
|
-
return getClientState(instance, {
|
|
1128
|
-
apiVersion: RELEASES_API_VERSION,
|
|
1129
|
-
resource
|
|
1130
|
-
}).observable.pipe(
|
|
1131
|
-
switchMap((client) => {
|
|
1132
|
-
const syncTags$ = new BehaviorSubject(void 0);
|
|
1133
|
-
return combineLatest([
|
|
1134
|
-
observeLiveEvents(instance, { resource, onCorsError }).pipe(startWith(void 0)),
|
|
1135
|
-
syncTags$
|
|
1136
|
-
]).pipe(
|
|
1137
|
-
filter(
|
|
1138
|
-
([message, syncTags]) => message === void 0 || message.tags.some((tag) => syncTags?.includes(tag))
|
|
1139
|
-
),
|
|
1140
|
-
map(([message]) => message?.id),
|
|
1141
|
-
distinctUntilChanged()
|
|
1142
|
-
).pipe(
|
|
1143
|
-
switchMap(
|
|
1144
|
-
(lastLiveEventId) => client.observable.fetch(
|
|
1145
|
-
RELEASES_QUERY,
|
|
1146
|
-
{},
|
|
1147
|
-
{
|
|
1148
|
-
perspective: "raw",
|
|
1149
|
-
filterResponse: !1,
|
|
1150
|
-
returnQuery: !1,
|
|
1151
|
-
lastLiveEventId,
|
|
1152
|
-
tag: "releases"
|
|
1153
|
-
}
|
|
1154
|
-
)
|
|
1155
|
-
),
|
|
1156
|
-
tap((response) => {
|
|
1157
|
-
syncTags$.next(response.syncTags);
|
|
1158
|
-
}),
|
|
1159
|
-
map((response) => response.result)
|
|
1160
|
-
);
|
|
1161
|
-
}),
|
|
1162
|
-
// Emit synchronously on subscribe (mirroring StateSource semantics, which
|
|
1163
|
-
// the releases store previously consumed) so the store can immediately
|
|
1164
|
-
// record an empty list: consumers distinguish "no releases yet" from
|
|
1165
|
-
// "never loaded", and the React hooks don't suspend on first load.
|
|
1166
|
-
startWith(void 0)
|
|
1167
|
-
);
|
|
1168
|
-
}
|
|
1169
|
-
function sortReleases(releases = []) {
|
|
1170
|
-
return [...releases].sort((a, b) => {
|
|
1171
|
-
const aType = a.metadata?.releaseType, bType = b.metadata?.releaseType;
|
|
1172
|
-
if (aType === "undecided" && bType !== "undecided")
|
|
1173
|
-
return -1;
|
|
1174
|
-
if (aType !== "undecided" && bType === "undecided")
|
|
1175
|
-
return 1;
|
|
1176
|
-
if (aType === "undecided" && bType === "undecided")
|
|
1177
|
-
return new Date(b._createdAt).getTime() - new Date(a._createdAt).getTime();
|
|
1178
|
-
if (aType === "scheduled" && bType === "scheduled") {
|
|
1179
|
-
const aPublishAt = a.publishAt || a.metadata?.intendedPublishAt;
|
|
1180
|
-
if (!aPublishAt)
|
|
1181
|
-
return 1;
|
|
1182
|
-
const bPublishAt = b.publishAt || b.metadata?.intendedPublishAt;
|
|
1183
|
-
return bPublishAt ? new Date(bPublishAt).getTime() - new Date(aPublishAt).getTime() : -1;
|
|
1184
|
-
}
|
|
1185
|
-
return aType === "asap" && bType !== "asap" ? 1 : aType !== "asap" && bType === "asap" ? -1 : aType === "asap" && bType === "asap" ? new Date(b._createdAt).getTime() - new Date(a._createdAt).getTime() : 0;
|
|
1186
|
-
});
|
|
1187
|
-
}
|
|
1188
|
-
const ARCHIVED_RELEASE_STATES = ["archived", "published"], STABLE_EMPTY_RELEASES = [], releasesStore = {
|
|
1189
|
-
name: "Releases",
|
|
1190
|
-
getInitialState: () => ({
|
|
1191
|
-
activeReleases: void 0,
|
|
1192
|
-
allReleases: void 0
|
|
1193
|
-
}),
|
|
1194
|
-
initialize: (context) => {
|
|
1195
|
-
const subscription = subscribeToReleases(context);
|
|
1196
|
-
return () => subscription.unsubscribe();
|
|
1197
|
-
}
|
|
1198
|
-
}, _getActiveReleasesState = bindActionByResource(
|
|
1199
|
-
releasesStore,
|
|
1200
|
-
createStateSourceAction({
|
|
1201
|
-
selector: ({ state }) => {
|
|
1202
|
-
if (state.error) throw state.error;
|
|
1203
|
-
return state.activeReleases;
|
|
1204
|
-
}
|
|
1205
|
-
})
|
|
1206
|
-
), getActiveReleasesState = (instance, options) => (
|
|
1207
|
-
// bindActionByResource keyFn destructures { resource } from the first param, so pass {} when no options
|
|
1208
|
-
_getActiveReleasesState(instance, options ?? {})
|
|
1209
|
-
), _getAllReleasesState = bindActionByResource(
|
|
1210
|
-
releasesStore,
|
|
1211
|
-
createStateSourceAction({
|
|
1212
|
-
selector: ({ state }) => {
|
|
1213
|
-
if (state.error) throw state.error;
|
|
1214
|
-
return state.allReleases;
|
|
1215
|
-
}
|
|
1216
|
-
})
|
|
1217
|
-
), getAllReleasesState = (instance, options) => _getAllReleasesState(instance, options ?? {}), subscribeToReleases = ({
|
|
1218
|
-
instance,
|
|
1219
|
-
state,
|
|
1220
|
-
key: { resource }
|
|
1221
|
-
}) => observeReleases(instance, {
|
|
1222
|
-
resource,
|
|
1223
|
-
// Surface CORS errors as store state instead of erroring the stream so
|
|
1224
|
-
// they can be handled by the Cors Error component
|
|
1225
|
-
onCorsError: (error) => state.set("setError", { error })
|
|
1226
|
-
}).pipe(
|
|
1227
|
-
map((releases) => {
|
|
1228
|
-
const sorted = sortReleases(releases ?? STABLE_EMPTY_RELEASES).reverse();
|
|
1229
|
-
state.set("setReleases", {
|
|
1230
|
-
allReleases: sorted,
|
|
1231
|
-
activeReleases: sorted.filter(
|
|
1232
|
-
(release) => !ARCHIVED_RELEASE_STATES.includes(release.state)
|
|
1233
|
-
)
|
|
1234
|
-
});
|
|
1235
|
-
})
|
|
1236
|
-
).subscribe({ error: (error) => state.set("setError", { error }) }), DEFAULT_PERSPECTIVE = "drafts", optionsCache = /* @__PURE__ */ new Map(), selectInstancePerspective = (context, _) => context.instance.config.perspective, selectActiveReleases = (context) => context.state.activeReleases, selectOptions = (_context, options) => options, memoizedOptionsSelector = createSelector(
|
|
1237
|
-
[selectActiveReleases, selectOptions],
|
|
1238
|
-
(activeReleases, options) => {
|
|
1239
|
-
if (!options || !activeReleases) return options;
|
|
1240
|
-
const releaseIds = activeReleases.map((release) => release._id).join(",");
|
|
1241
|
-
let nestedCache = optionsCache.get(releaseIds);
|
|
1242
|
-
nestedCache || (nestedCache = /* @__PURE__ */ new Map(), optionsCache.set(releaseIds, nestedCache));
|
|
1243
|
-
const optionsKey = JSON.stringify(options);
|
|
1244
|
-
let cachedOptions = nestedCache.get(optionsKey);
|
|
1245
|
-
return cachedOptions || (cachedOptions = options, nestedCache.set(optionsKey, cachedOptions)), cachedOptions;
|
|
1246
|
-
}
|
|
1247
|
-
), _getPerspectiveStateSelector = createStateSourceAction({
|
|
1248
|
-
selector: createSelector(
|
|
1249
|
-
[selectInstancePerspective, selectActiveReleases, memoizedOptionsSelector],
|
|
1250
|
-
(instancePerspective, activeReleases, memoizedOptions) => {
|
|
1251
|
-
const perspective = memoizedOptions?.perspective ?? instancePerspective ?? DEFAULT_PERSPECTIVE;
|
|
1252
|
-
if (!isReleasePerspective(perspective)) return perspective;
|
|
1253
|
-
if (!activeReleases || activeReleases.length === 0) return;
|
|
1254
|
-
const releaseNames = sortReleases(activeReleases).map((release) => release.name), index = releaseNames.findIndex((name) => name === perspective.releaseName);
|
|
1255
|
-
if (index < 0)
|
|
1256
|
-
throw new Error(`Release "${perspective.releaseName}" not found in active releases`);
|
|
1257
|
-
return ["drafts", ...releaseNames.slice(0, index + 1)].filter((name) => !perspective.excludedPerspectives?.includes(name)).reverse();
|
|
1258
|
-
}
|
|
1259
|
-
)
|
|
1260
|
-
}), _boundGetPerspectiveState = bindActionByResource(
|
|
1261
|
-
releasesStore,
|
|
1262
|
-
_getPerspectiveStateSelector
|
|
1263
|
-
), getPerspectiveState = (instance, ...rest) => (
|
|
1264
|
-
// bindActionByResource keyFn destructures { resource } from the first param, so pass {} when no options
|
|
1265
|
-
_boundGetPerspectiveState(instance, ...rest.length ? rest : [{}])
|
|
1266
|
-
);
|
|
1267
|
-
function unref(timer2) {
|
|
1268
|
-
const t = timer2;
|
|
1269
|
-
typeof t == "object" && t !== null && "unref" in t && typeof t.unref == "function" && t.unref();
|
|
1270
|
-
}
|
|
1271
|
-
function setCleanupTimeout(fn, delay) {
|
|
1272
|
-
const timer2 = setTimeout(fn, delay);
|
|
1273
|
-
return unref(timer2), timer2;
|
|
1274
|
-
}
|
|
1275
|
-
function setCleanupInterval(fn, delay) {
|
|
1276
|
-
const timer2 = setInterval(fn, delay);
|
|
1277
|
-
return unref(timer2), timer2;
|
|
1278
|
-
}
|
|
1279
|
-
const QUERY_STATE_CLEAR_DELAY = 1e3, QUERY_STORE_API_VERSION = "v2025-05-06", QUERY_STORE_DEFAULT_PERSPECTIVE = "drafts", setQueryError = (key, error) => (prev) => {
|
|
1280
|
-
const prevQuery = prev.queries[key];
|
|
1281
|
-
return prevQuery ? { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, error } } } : prev;
|
|
1282
|
-
}, setQueryData = (key, result, syncTags) => (prev) => {
|
|
1283
|
-
const prevQuery = prev.queries[key];
|
|
1284
|
-
return prevQuery ? {
|
|
1285
|
-
...prev,
|
|
1286
|
-
queries: { ...prev.queries, [key]: { ...prevQuery, result: result ?? null, syncTags } }
|
|
1287
|
-
} : prev;
|
|
1288
|
-
}, setLastLiveEventId = (key, lastLiveEventId) => (prev) => {
|
|
1289
|
-
const prevQuery = prev.queries[key];
|
|
1290
|
-
return prevQuery ? { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, lastLiveEventId } } } : prev;
|
|
1291
|
-
}, addSubscriber = (key, subscriptionId) => (prev) => {
|
|
1292
|
-
const prevQuery = prev.queries[key], subscribers = [...prevQuery?.subscribers ?? [], subscriptionId];
|
|
1293
|
-
return { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, subscribers } } };
|
|
1294
|
-
}, removeSubscriber = (key, subscriptionId) => (prev) => {
|
|
1295
|
-
const prevQuery = prev.queries[key];
|
|
1296
|
-
if (!prevQuery) return prev;
|
|
1297
|
-
const subscribers = prevQuery.subscribers.filter((id) => id !== subscriptionId);
|
|
1298
|
-
return subscribers.length ? { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, subscribers } } } : { ...prev, queries: omitProperty(prev.queries, key) };
|
|
1299
|
-
}, EMPTY_ARRAY = [], getQueryKey = (options) => JSON.stringify(options), parseQueryKey = (key) => JSON.parse(key);
|
|
1300
|
-
function normalizeOptionsWithPerspective(instance, options) {
|
|
1301
|
-
if (options.perspective !== void 0) return options;
|
|
1302
|
-
const instancePerspective = instance.config.perspective;
|
|
1303
|
-
return {
|
|
1304
|
-
...options,
|
|
1305
|
-
perspective: instancePerspective !== void 0 ? instancePerspective : QUERY_STORE_DEFAULT_PERSPECTIVE
|
|
1306
|
-
};
|
|
1307
|
-
}
|
|
1308
|
-
const queryStore = {
|
|
1309
|
-
name: "QueryStore",
|
|
1310
|
-
getInitialState: () => ({ queries: {} }),
|
|
1311
|
-
initialize(context) {
|
|
1312
|
-
const subscriptions = [
|
|
1313
|
-
listenForNewSubscribersAndFetch(context),
|
|
1314
|
-
listenToLiveClientAndSetLastLiveEventIds(context)
|
|
1315
|
-
];
|
|
1316
|
-
return () => {
|
|
1317
|
-
for (const subscription of subscriptions)
|
|
1318
|
-
subscription.unsubscribe();
|
|
1319
|
-
};
|
|
1320
|
-
}
|
|
1321
|
-
}, errorHandler = (state) => (error) => state.set("setError", { error }), listenForNewSubscribersAndFetch = ({ state, instance }) => state.observable.pipe(
|
|
1322
|
-
map((s) => new Set(Object.keys(s.queries))),
|
|
1323
|
-
distinctUntilChanged((curr, next) => curr.size !== next.size ? !1 : Array.from(next).every((i) => curr.has(i))),
|
|
1324
|
-
startWith(/* @__PURE__ */ new Set()),
|
|
1325
|
-
pairwise(),
|
|
1326
|
-
mergeMap(([curr, next]) => {
|
|
1327
|
-
const added = Array.from(next).filter((i) => !curr.has(i)), removed = Array.from(curr).filter((i) => !next.has(i));
|
|
1328
|
-
return [
|
|
1329
|
-
...added.map((key) => ({ key, added: !0 })),
|
|
1330
|
-
...removed.map((key) => ({ key, added: !1 }))
|
|
1331
|
-
];
|
|
1332
|
-
}),
|
|
1333
|
-
groupBy((i) => i.key),
|
|
1334
|
-
mergeMap(
|
|
1335
|
-
(group$) => group$.pipe(
|
|
1336
|
-
switchMap((e) => {
|
|
1337
|
-
if (!e.added) return EMPTY;
|
|
1338
|
-
const lastLiveEventId$ = state.observable.pipe(
|
|
1339
|
-
map((s) => s.queries[group$.key]?.lastLiveEventId),
|
|
1340
|
-
distinctUntilChanged()
|
|
1341
|
-
), {
|
|
1342
|
-
query,
|
|
1343
|
-
params,
|
|
1344
|
-
projectId,
|
|
1345
|
-
dataset,
|
|
1346
|
-
tag,
|
|
1347
|
-
resource,
|
|
1348
|
-
perspective: perspectiveFromOptions,
|
|
1349
|
-
...restOptions
|
|
1350
|
-
} = parseQueryKey(group$.key), perspective$ = isReleasePerspective(perspectiveFromOptions) ? getPerspectiveState(instance, {
|
|
1351
|
-
perspective: perspectiveFromOptions,
|
|
1352
|
-
resource
|
|
1353
|
-
}).observable.pipe(filter(Boolean)) : of(perspectiveFromOptions ?? QUERY_STORE_DEFAULT_PERSPECTIVE), client$ = getClientState(instance, {
|
|
1354
|
-
apiVersion: QUERY_STORE_API_VERSION,
|
|
1355
|
-
projectId,
|
|
1356
|
-
dataset,
|
|
1357
|
-
resource
|
|
1358
|
-
}).observable;
|
|
1359
|
-
return combineLatest({
|
|
1360
|
-
lastLiveEventId: lastLiveEventId$,
|
|
1361
|
-
client: client$,
|
|
1362
|
-
perspective: perspective$
|
|
1363
|
-
}).pipe(
|
|
1364
|
-
switchMap(
|
|
1365
|
-
({ lastLiveEventId, client, perspective }) => client.observable.fetch(query, params, {
|
|
1366
|
-
...restOptions,
|
|
1367
|
-
perspective,
|
|
1368
|
-
filterResponse: !1,
|
|
1369
|
-
returnQuery: !1,
|
|
1370
|
-
lastLiveEventId,
|
|
1371
|
-
tag
|
|
1372
|
-
})
|
|
1373
|
-
),
|
|
1374
|
-
tap(({ result, syncTags }) => {
|
|
1375
|
-
state.set("setQueryData", setQueryData(group$.key, result, syncTags));
|
|
1376
|
-
}),
|
|
1377
|
-
// Catch inside the per-event stream: erroring the group pipe would
|
|
1378
|
-
// complete the group's subscription, and since `groupBy` above never
|
|
1379
|
-
// removes its group subjects, re-adding the key would emit into a
|
|
1380
|
-
// subject with no subscribers — the key could never be fetched again.
|
|
1381
|
-
catchError((error) => (state.set("setQueryError", setQueryError(group$.key, error)), EMPTY))
|
|
1382
|
-
);
|
|
1383
|
-
})
|
|
1384
|
-
)
|
|
1385
|
-
)
|
|
1386
|
-
).subscribe({ error: errorHandler(state) }), listenToLiveClientAndSetLastLiveEventIds = ({
|
|
1387
|
-
state,
|
|
1388
|
-
instance,
|
|
1389
|
-
key: { resource }
|
|
1390
|
-
}) => {
|
|
1391
|
-
const liveMessages$ = observeLiveEvents(instance, {
|
|
1392
|
-
resource,
|
|
1393
|
-
// Surface CORS errors as store state (handled by the Cors Error
|
|
1394
|
-
// component) instead of erroring the stream: a stream error here would
|
|
1395
|
-
// reach the outer subscription's errorHandler, set the store-wide
|
|
1396
|
-
// `state.error`, and permanently brick every query selector.
|
|
1397
|
-
onCorsError: (error) => state.set("setError", { error })
|
|
1398
|
-
}).pipe(share());
|
|
1399
|
-
return state.observable.pipe(
|
|
1400
|
-
mergeMap((s) => Object.entries(s.queries)),
|
|
1401
|
-
groupBy(([key]) => key),
|
|
1402
|
-
mergeMap((group$) => {
|
|
1403
|
-
const syncTags$ = group$.pipe(
|
|
1404
|
-
map(([, queryState]) => queryState),
|
|
1405
|
-
map((i) => i?.syncTags ?? EMPTY_ARRAY),
|
|
1406
|
-
distinctUntilChanged()
|
|
1407
|
-
);
|
|
1408
|
-
return combineLatest([liveMessages$, syncTags$]).pipe(
|
|
1409
|
-
filter(([message, syncTags]) => message.tags.some((tag) => syncTags.includes(tag))),
|
|
1410
|
-
tap(([message]) => {
|
|
1411
|
-
state.set("setLastLiveEventId", setLastLiveEventId(group$.key, message.id));
|
|
1412
|
-
})
|
|
1413
|
-
);
|
|
1414
|
-
})
|
|
1415
|
-
).subscribe({ error: errorHandler(state) });
|
|
1416
|
-
};
|
|
1417
|
-
function getQueryState(...args) {
|
|
1418
|
-
return _getQueryState(...args);
|
|
1419
|
-
}
|
|
1420
|
-
const _getQueryState = bindActionByResource(
|
|
1421
|
-
queryStore,
|
|
1422
|
-
createStateSourceAction({
|
|
1423
|
-
selector: ({ state, instance }, options) => {
|
|
1424
|
-
if (state.error) throw state.error;
|
|
1425
|
-
const key = getQueryKey(normalizeOptionsWithPerspective(instance, options)), queryState = state.queries[key];
|
|
1426
|
-
if (queryState?.error) throw queryState.error;
|
|
1427
|
-
return queryState?.result;
|
|
1428
|
-
},
|
|
1429
|
-
onSubscribe: ({ state, instance }, options) => {
|
|
1430
|
-
const subscriptionId = insecureRandomId(), key = getQueryKey(normalizeOptionsWithPerspective(instance, options));
|
|
1431
|
-
return state.set("addSubscriber", addSubscriber(key, subscriptionId)), () => {
|
|
1432
|
-
setCleanupTimeout(
|
|
1433
|
-
() => state.set("removeSubscriber", removeSubscriber(key, subscriptionId)),
|
|
1434
|
-
QUERY_STATE_CLEAR_DELAY
|
|
1435
|
-
);
|
|
1436
|
-
};
|
|
1437
|
-
}
|
|
1438
|
-
})
|
|
1439
|
-
);
|
|
1440
|
-
function resolveQuery(...args) {
|
|
1441
|
-
return _resolveQuery(...args);
|
|
1442
|
-
}
|
|
1443
|
-
const _resolveQuery = bindActionByResource(
|
|
1444
|
-
queryStore,
|
|
1445
|
-
({ state, instance }, { signal, ...options }) => {
|
|
1446
|
-
const normalized = normalizeOptionsWithPerspective(instance, options), { getCurrent } = getQueryState(instance, normalized), key = getQueryKey(normalized), subscriptionId = insecureRandomId();
|
|
1447
|
-
state.set("addSubscriber", addSubscriber(key, subscriptionId));
|
|
1448
|
-
const aborted$ = signal ? new Observable((observer) => {
|
|
1449
|
-
const cleanup = () => {
|
|
1450
|
-
signal.removeEventListener("abort", listener);
|
|
1451
|
-
}, listener = () => {
|
|
1452
|
-
observer.error(new DOMException("The operation was aborted.", "AbortError")), observer.complete(), cleanup();
|
|
1453
|
-
};
|
|
1454
|
-
return signal.addEventListener("abort", listener), cleanup;
|
|
1455
|
-
}).pipe(
|
|
1456
|
-
catchError((error) => {
|
|
1457
|
-
throw error instanceof Error && error.name === "AbortError" && state.set("removeSubscriber", removeSubscriber(key, subscriptionId)), error;
|
|
1458
|
-
})
|
|
1459
|
-
) : NEVER, resolved$ = state.observable.pipe(
|
|
1460
|
-
map(getCurrent),
|
|
1461
|
-
first((i) => i !== void 0)
|
|
1462
|
-
), promise = firstValueFrom(race([resolved$, aborted$])), releaseSubscriber = () => {
|
|
1463
|
-
setCleanupTimeout(() => {
|
|
1464
|
-
state.set("removeSubscriber", removeSubscriber(key, subscriptionId));
|
|
1465
|
-
}, QUERY_STATE_CLEAR_DELAY);
|
|
1466
|
-
};
|
|
1467
|
-
return promise.then(releaseSubscriber, releaseSubscriber), promise;
|
|
1468
|
-
}
|
|
1469
|
-
), DEFAULT_STALE_TIME = 3e4, DEFAULT_GC_TIME = 3e5, definitions = /* @__PURE__ */ new Map(), inflight = /* @__PURE__ */ new Map(), gcTimers = /* @__PURE__ */ new Map(), intervalTimers = /* @__PURE__ */ new Map(), snapshotCache = /* @__PURE__ */ new WeakMap(), PENDING_SNAPSHOT = {
|
|
1470
|
-
status: "pending",
|
|
1471
|
-
data: void 0,
|
|
1472
|
-
error: void 0,
|
|
1473
|
-
isFetching: !1,
|
|
1474
|
-
dataUpdatedAt: void 0
|
|
1475
|
-
}, entryKey = (fetcherName, rawKey) => `${fetcherName}:${rawKey}`, computeTags = (def, data, params) => typeof def.tags == "function" ? def.tags(data, ...params) : def.tags ?? [], isUpdaterFn = (updater) => typeof updater == "function", applyUpdater = (updater, current) => isUpdaterFn(updater) ? updater(current) : updater, needsFetch = (entry, def) => entry.isFetching ? !1 : entry.status !== "success" ? !0 : entry.forcedStale || Date.now() - (entry.dataUpdatedAt ?? 0) >= (def.staleTime ?? DEFAULT_STALE_TIME), asTyped = (entry) => entry, toSnapshot = (entry) => {
|
|
1476
|
-
if (!entry) return PENDING_SNAPSHOT;
|
|
1477
|
-
const cached = snapshotCache.get(entry);
|
|
1478
|
-
if (cached) return cached;
|
|
1479
|
-
let snapshot;
|
|
1480
|
-
return entry.status === "success" ? snapshot = {
|
|
1481
|
-
status: "success",
|
|
1482
|
-
data: entry.data,
|
|
1483
|
-
error: entry.error,
|
|
1484
|
-
isFetching: entry.isFetching,
|
|
1485
|
-
dataUpdatedAt: entry.dataUpdatedAt
|
|
1486
|
-
} : entry.status === "error" ? snapshot = {
|
|
1487
|
-
status: "error",
|
|
1488
|
-
data: void 0,
|
|
1489
|
-
error: entry.error,
|
|
1490
|
-
isFetching: entry.isFetching,
|
|
1491
|
-
dataUpdatedAt: void 0
|
|
1492
|
-
} : snapshot = {
|
|
1493
|
-
status: "pending",
|
|
1494
|
-
data: void 0,
|
|
1495
|
-
error: void 0,
|
|
1496
|
-
isFetching: entry.isFetching,
|
|
1497
|
-
dataUpdatedAt: void 0
|
|
1498
|
-
}, snapshotCache.set(entry, snapshot), snapshot;
|
|
1499
|
-
}, cacheStore = {
|
|
1500
|
-
name: "FetcherCache",
|
|
1501
|
-
getInitialState: () => ({ entries: {} }),
|
|
1502
|
-
initialize: () => () => {
|
|
1503
|
-
for (const timer2 of gcTimers.values()) clearTimeout(timer2);
|
|
1504
|
-
for (const timer2 of intervalTimers.values()) clearInterval(timer2);
|
|
1505
|
-
for (const fetch of inflight.values()) fetch.sub.unsubscribe();
|
|
1506
|
-
gcTimers.clear(), intervalTimers.clear(), inflight.clear();
|
|
1507
|
-
}
|
|
1508
|
-
}, updateEntry = (state, key, actionName, updater) => {
|
|
1509
|
-
state.set(actionName, (prev) => {
|
|
1510
|
-
const next = updater(prev.entries[key]);
|
|
1511
|
-
if (next === prev.entries[key]) return prev;
|
|
1512
|
-
const entries = { ...prev.entries };
|
|
1513
|
-
return next === void 0 ? delete entries[key] : entries[key] = next, { entries };
|
|
1514
|
-
});
|
|
1515
|
-
}, baseEntry = (def, key, instance, params) => {
|
|
1516
|
-
const seeded = def.initialData?.(instance, ...params);
|
|
1517
|
-
return seeded ? {
|
|
1518
|
-
fetcherName: def.name,
|
|
1519
|
-
key,
|
|
1520
|
-
params,
|
|
1521
|
-
instance,
|
|
1522
|
-
status: "success",
|
|
1523
|
-
data: seeded.data,
|
|
1524
|
-
error: void 0,
|
|
1525
|
-
dataUpdatedAt: seeded.dataUpdatedAt,
|
|
1526
|
-
isFetching: !1,
|
|
1527
|
-
version: 0,
|
|
1528
|
-
forcedStale: !1,
|
|
1529
|
-
tags: computeTags(def, seeded.data, params),
|
|
1530
|
-
subscriptions: 0
|
|
1531
|
-
} : {
|
|
1532
|
-
fetcherName: def.name,
|
|
1533
|
-
key,
|
|
1534
|
-
params,
|
|
1535
|
-
instance,
|
|
1536
|
-
status: "pending",
|
|
1537
|
-
data: void 0,
|
|
1538
|
-
error: void 0,
|
|
1539
|
-
dataUpdatedAt: void 0,
|
|
1540
|
-
isFetching: !1,
|
|
1541
|
-
version: 0,
|
|
1542
|
-
forcedStale: !1,
|
|
1543
|
-
tags: [],
|
|
1544
|
-
subscriptions: 0
|
|
1545
|
-
};
|
|
1546
|
-
}, startFetch = (state, def, instance, params, force) => {
|
|
1547
|
-
const key = entryKey(def.name, def.getKey(instance, ...params)), existing = inflight.get(key);
|
|
1548
|
-
if (existing && !force) return existing.promise;
|
|
1549
|
-
existing && (existing.sub.unsubscribe(), inflight.delete(key)), updateEntry(state, key, "fetchStart", (prev) => ({
|
|
1550
|
-
...prev ?? baseEntry(def, key, instance, params),
|
|
1551
|
-
isFetching: !0
|
|
1552
|
-
}));
|
|
1553
|
-
const startVersion = state.get().entries[key]?.version ?? 0;
|
|
1554
|
-
let resolve, reject;
|
|
1555
|
-
const promise = new Promise((res, rej) => {
|
|
1556
|
-
resolve = res, reject = rej;
|
|
1557
|
-
});
|
|
1558
|
-
existing && promise.then(existing.resolve, existing.reject);
|
|
1559
|
-
const sub = new Subscription();
|
|
1560
|
-
return inflight.set(key, { sub, promise, resolve, reject, startVersion }), sub.add(
|
|
1561
|
-
def.fetch(instance)(...params).subscribe({
|
|
1562
|
-
next: (data) => {
|
|
1563
|
-
const current = state.get().entries[key];
|
|
1564
|
-
if (current && current.version !== startVersion) {
|
|
1565
|
-
inflight.delete(key), current.isFetching && updateEntry(
|
|
1566
|
-
state,
|
|
1567
|
-
key,
|
|
1568
|
-
"fetchDiscard",
|
|
1569
|
-
(prev) => prev && { ...prev, isFetching: !1 }
|
|
1570
|
-
), resolve(current.data), sub.unsubscribe();
|
|
1571
|
-
return;
|
|
1572
|
-
}
|
|
1573
|
-
updateEntry(state, key, "fetchSuccess", (prev) => ({
|
|
1574
|
-
...prev ?? baseEntry(def, key, instance, params),
|
|
1575
|
-
status: "success",
|
|
1576
|
-
data,
|
|
1577
|
-
error: void 0,
|
|
1578
|
-
dataUpdatedAt: Date.now(),
|
|
1579
|
-
isFetching: !1,
|
|
1580
|
-
forcedStale: !1,
|
|
1581
|
-
tags: computeTags(def, data, params)
|
|
1582
|
-
})), resolve(data);
|
|
1583
|
-
},
|
|
1584
|
-
error: (error) => {
|
|
1585
|
-
updateEntry(state, key, "fetchError", (prev) => prev && (prev.status === "success" ? { ...prev, error, isFetching: !1 } : { ...prev, status: "error", error, isFetching: !1 })), inflight.delete(key), reject(error);
|
|
1586
|
-
},
|
|
1587
|
-
complete: () => {
|
|
1588
|
-
inflight.delete(key), state.get().entries[key]?.isFetching && updateEntry(state, key, "fetchSettle", (prev) => prev && { ...prev, isFetching: !1 });
|
|
1589
|
-
}
|
|
1590
|
-
})
|
|
1591
|
-
), promise;
|
|
1592
|
-
}, detach = (promise) => {
|
|
1593
|
-
promise.catch(() => {
|
|
1594
|
-
});
|
|
1595
|
-
}, markStale = (state, key) => updateEntry(state, key, "markStale", (prev) => prev && { ...prev, forcedStale: !0 }), startInterval = (state, def, instance, params, key) => {
|
|
1596
|
-
if (!def.refetchInterval || intervalTimers.has(key)) return;
|
|
1597
|
-
const timer2 = setCleanupInterval(() => {
|
|
1598
|
-
if (typeof document < "u" && document.hidden) return;
|
|
1599
|
-
const entry = state.get().entries[key];
|
|
1600
|
-
entry && entry.subscriptions > 0 && detach(startFetch(state, def, instance, params, !0));
|
|
1601
|
-
}, def.refetchInterval);
|
|
1602
|
-
intervalTimers.set(key, timer2);
|
|
1603
|
-
}, scheduleGc = (state, def, key) => {
|
|
1604
|
-
if (gcTimers.has(key)) return;
|
|
1605
|
-
const entry = state.get().entries[key];
|
|
1606
|
-
if (!entry || entry.subscriptions > 0) return;
|
|
1607
|
-
const timer2 = setCleanupTimeout(() => {
|
|
1608
|
-
gcTimers.delete(key);
|
|
1609
|
-
const fetch = inflight.get(key);
|
|
1610
|
-
fetch && (fetch.sub.unsubscribe(), inflight.delete(key)), updateEntry(state, key, "gc", () => {
|
|
1611
|
-
});
|
|
1612
|
-
}, def.gcTime ?? DEFAULT_GC_TIME);
|
|
1613
|
-
gcTimers.set(key, timer2);
|
|
1614
|
-
}, invalidateByTags = bindActionGlobally(
|
|
1615
|
-
cacheStore,
|
|
1616
|
-
({ state }, targets) => {
|
|
1617
|
-
const refetches = [];
|
|
1618
|
-
for (const [key, entry] of Object.entries(state.get().entries)) {
|
|
1619
|
-
if (!entry.tags.some(
|
|
1620
|
-
(tag) => targets.some(
|
|
1621
|
-
(target) => tag.type === target.type && (target.id === void 0 || tag.id === target.id)
|
|
1622
|
-
)
|
|
1623
|
-
) || (markStale(state, key), entry.subscriptions <= 0)) continue;
|
|
1624
|
-
const def = definitions.get(entry.fetcherName);
|
|
1625
|
-
def && refetches.push(
|
|
1626
|
-
startFetch(state, def, entry.instance, entry.params, !0).catch(() => {
|
|
1627
|
-
})
|
|
1628
|
-
);
|
|
1629
|
-
}
|
|
1630
|
-
return Promise.all(refetches).then(() => {
|
|
1631
|
-
});
|
|
1632
|
-
}
|
|
1633
|
-
);
|
|
1634
|
-
function defineFetcher(definition) {
|
|
1635
|
-
const def = definition;
|
|
1636
|
-
definitions.set(definition.name, def);
|
|
1637
|
-
const getState = bindActionGlobally(
|
|
1638
|
-
cacheStore,
|
|
1639
|
-
createStateSourceAction({
|
|
1640
|
-
selector: ({ state, instance }, ...params) => {
|
|
1641
|
-
const key = entryKey(def.name, def.getKey(instance, ...params)), entry = state.entries[key];
|
|
1642
|
-
return toSnapshot(entry && asTyped(entry));
|
|
1643
|
-
},
|
|
1644
|
-
onSubscribe: ({ state, instance }, ...params) => {
|
|
1645
|
-
const key = entryKey(def.name, def.getKey(instance, ...params)), pendingGc = gcTimers.get(key);
|
|
1646
|
-
return pendingGc && (clearTimeout(pendingGc), gcTimers.delete(key)), updateEntry(state, key, "subscribe", (prev) => ({
|
|
1647
|
-
...prev ?? baseEntry(def, key, instance, params),
|
|
1648
|
-
instance,
|
|
1649
|
-
subscriptions: (prev?.subscriptions ?? 0) + 1
|
|
1650
|
-
})), startInterval(state, def, instance, params, key), queueMicrotask(() => {
|
|
1651
|
-
const entry = state.get().entries[key];
|
|
1652
|
-
entry && entry.subscriptions > 0 && needsFetch(entry, def) && detach(startFetch(state, def, instance, params, !1));
|
|
1653
|
-
}), () => {
|
|
1654
|
-
updateEntry(
|
|
1655
|
-
state,
|
|
1656
|
-
key,
|
|
1657
|
-
"unsubscribe",
|
|
1658
|
-
(prev) => prev && { ...prev, subscriptions: Math.max(0, prev.subscriptions - 1) }
|
|
1659
|
-
);
|
|
1660
|
-
const entry = state.get().entries[key];
|
|
1661
|
-
if (!entry || entry.subscriptions > 0) return;
|
|
1662
|
-
const interval = intervalTimers.get(key);
|
|
1663
|
-
interval && (clearInterval(interval), intervalTimers.delete(key)), scheduleGc(state, def, key);
|
|
1664
|
-
};
|
|
1665
|
-
}
|
|
1666
|
-
})
|
|
1667
|
-
), resolveState = (instance, ...params) => firstValueFrom(
|
|
1668
|
-
getState(instance, ...params).observable.pipe(
|
|
1669
|
-
filter(
|
|
1670
|
-
(snapshot) => snapshot.status !== "pending"
|
|
1671
|
-
),
|
|
1672
|
-
map((snapshot) => {
|
|
1673
|
-
if (snapshot.status === "error") throw snapshot.error;
|
|
1674
|
-
return snapshot.data;
|
|
1675
|
-
})
|
|
1676
|
-
)
|
|
1677
|
-
), invalidate = bindActionGlobally(
|
|
1678
|
-
cacheStore,
|
|
1679
|
-
({ state, instance }, ...params) => {
|
|
1680
|
-
const key = entryKey(def.name, def.getKey(instance, ...params));
|
|
1681
|
-
markStale(state, key);
|
|
1682
|
-
const entry = state.get().entries[key];
|
|
1683
|
-
entry && entry.subscriptions > 0 && detach(startFetch(state, def, instance, params, !0));
|
|
1684
|
-
}
|
|
1685
|
-
), invalidateAll = bindActionGlobally(cacheStore, ({ state }) => {
|
|
1686
|
-
const prefix = `${def.name}:`;
|
|
1687
|
-
for (const [key, entry] of Object.entries(state.get().entries))
|
|
1688
|
-
key.startsWith(prefix) && (markStale(state, key), entry.subscriptions > 0 && detach(startFetch(state, def, entry.instance, entry.params, !0)));
|
|
1689
|
-
}), refetch = bindActionGlobally(
|
|
1690
|
-
cacheStore,
|
|
1691
|
-
({ state, instance }, ...params) => {
|
|
1692
|
-
const key = entryKey(def.name, def.getKey(instance, ...params)), promise = startFetch(state, def, instance, params, !0);
|
|
1693
|
-
return scheduleGc(state, def, key), promise;
|
|
1694
|
-
}
|
|
1695
|
-
), setData = bindActionGlobally(
|
|
1696
|
-
cacheStore,
|
|
1697
|
-
({ state, instance }, params, updater) => {
|
|
1698
|
-
const key = entryKey(def.name, def.getKey(instance, ...params));
|
|
1699
|
-
let previous;
|
|
1700
|
-
return updateEntry(state, key, "setData", (prev) => {
|
|
1701
|
-
previous = prev;
|
|
1702
|
-
const from = asTyped(prev ?? baseEntry(def, key, instance, params)), nextData = applyUpdater(updater, from.data);
|
|
1703
|
-
return {
|
|
1704
|
-
...from,
|
|
1705
|
-
status: "success",
|
|
1706
|
-
data: nextData,
|
|
1707
|
-
dataUpdatedAt: from.dataUpdatedAt ?? Date.now(),
|
|
1708
|
-
version: from.version + 1,
|
|
1709
|
-
tags: computeTags(def, nextData, params)
|
|
1710
|
-
};
|
|
1711
|
-
}), scheduleGc(state, def, key), { undo: () => updateEntry(state, key, "undoSetData", () => previous) };
|
|
1712
|
-
}
|
|
1713
|
-
);
|
|
1714
|
-
return { getState, resolveState, invalidate, invalidateAll, refetch, setData };
|
|
1715
|
-
}
|
|
1716
|
-
function defineMutation(definition) {
|
|
1717
|
-
return (instance, input) => {
|
|
1718
|
-
const undos = [], write = (fetcher, params, updater) => {
|
|
1719
|
-
undos.push(fetcher.setData(instance, params, updater).undo);
|
|
1720
|
-
};
|
|
1721
|
-
return definition.onMutate?.(write, input), firstValueFrom(definition.mutationFn(instance)(input)).then(
|
|
1722
|
-
(result) => {
|
|
1723
|
-
definition.onSuccess?.(write, result, input);
|
|
1724
|
-
const targets = typeof definition.invalidates == "function" ? definition.invalidates(result, input) : definition.invalidates ?? [], invalidated = targets.length ? invalidateByTags(instance, targets) : Promise.resolve();
|
|
1725
|
-
return { data: result, invalidated };
|
|
1726
|
-
},
|
|
1727
|
-
(error) => {
|
|
1728
|
-
for (let i = undos.length - 1; i >= 0; i--) undos[i]();
|
|
1729
|
-
throw error;
|
|
1730
|
-
}
|
|
1731
|
-
);
|
|
1732
|
-
};
|
|
1733
|
-
}
|
|
1734
|
-
var version = "3.0.0-rc.1";
|
|
1735
|
-
const CORE_SDK_VERSION = getEnv("PKG_VERSION") || `${version}-development`, API_VERSION = "vX", PROJECT_API_VERSION = "2025-07-18", USERS_STATE_CLEAR_DELAY = 5e3, DEFAULT_USERS_BATCH_SIZE = 100, getUsersKey = (instance, {
|
|
1736
|
-
resourceType,
|
|
1737
|
-
organizationId,
|
|
1738
|
-
batchSize = DEFAULT_USERS_BATCH_SIZE,
|
|
1739
|
-
projectId = instance.config.projectId,
|
|
1740
|
-
userId
|
|
1741
|
-
} = {}) => JSON.stringify({
|
|
1742
|
-
resourceType,
|
|
1743
|
-
organizationId,
|
|
1744
|
-
batchSize,
|
|
1745
|
-
projectId,
|
|
1746
|
-
userId
|
|
1747
|
-
}), parseUsersKey = (key) => JSON.parse(key), addSubscription = (subscriptionId, key) => (prev) => {
|
|
1748
|
-
const group = prev.users[key], subscriptions = [...group?.subscriptions ?? [], subscriptionId];
|
|
1749
|
-
return { ...prev, users: { ...prev.users, [key]: { ...group, subscriptions } } };
|
|
1750
|
-
}, removeSubscription = (subscriptionId, key) => (prev) => {
|
|
1751
|
-
const group = prev.users[key];
|
|
1752
|
-
if (!group) return prev;
|
|
1753
|
-
const subscriptions = group.subscriptions.filter((id) => id !== subscriptionId);
|
|
1754
|
-
return subscriptions.length ? { ...prev, users: { ...prev.users, [key]: { ...group, subscriptions } } } : { ...prev, users: omitProperty(prev.users, key) };
|
|
1755
|
-
}, setUsersData = (key, { data, nextCursor, totalCount }) => (prev) => {
|
|
1756
|
-
const group = prev.users[key];
|
|
1757
|
-
if (!group) return prev;
|
|
1758
|
-
const users = [...group.users ?? [], ...data];
|
|
1759
|
-
return { ...prev, users: { ...prev.users, [key]: { ...group, users, totalCount, nextCursor } } };
|
|
1760
|
-
}, updateLastLoadMoreRequest = (timestamp, key) => (prev) => {
|
|
1761
|
-
const group = prev.users[key];
|
|
1762
|
-
return group ? { ...prev, users: { ...prev.users, [key]: { ...group, lastLoadMoreRequest: timestamp } } } : prev;
|
|
1763
|
-
}, setUsersError = (key, error) => (prev) => {
|
|
1764
|
-
const group = prev.users[key];
|
|
1765
|
-
return group ? { ...prev, users: { ...prev.users, [key]: { ...group, error } } } : prev;
|
|
1766
|
-
}, cancelRequest = (key) => (prev) => {
|
|
1767
|
-
const group = prev.users[key];
|
|
1768
|
-
return !group || group.subscriptions.length ? prev : { ...prev, users: omitProperty(prev.users, key) };
|
|
1769
|
-
}, initializeRequest = (key) => (prev) => prev.users[key] ? prev : { ...prev, users: { ...prev.users, [key]: { subscriptions: [] } } }, TOKEN_REGEX = /(?:[^\s"]+|"[^"]*")+/g;
|
|
1770
|
-
function isNegationToken(token) {
|
|
1771
|
-
return typeof token < "u" && token.trim().startsWith("-");
|
|
1772
|
-
}
|
|
1773
|
-
function isPrefixToken(token) {
|
|
1774
|
-
return typeof token < "u" && token.trim().endsWith("*");
|
|
1775
|
-
}
|
|
1776
|
-
function isExactMatchToken(token) {
|
|
1777
|
-
return !!token && token.length >= 2 && token.startsWith('"') && token.endsWith('"');
|
|
1778
|
-
}
|
|
1779
|
-
function createGroqSearchFilter(query) {
|
|
1780
|
-
const trimmedQuery = query.trim();
|
|
1781
|
-
if (!trimmedQuery)
|
|
1782
|
-
return "";
|
|
1783
|
-
const tokens = trimmedQuery.match(TOKEN_REGEX) ?? [], reversedIndex = [...tokens].reverse().findIndex(
|
|
1784
|
-
(token) => !isNegationToken(token) && !isExactMatchToken(token)
|
|
1785
|
-
), finalIncrementalTokenIndex = reversedIndex === -1 ? -1 : tokens.length - 1 - reversedIndex, finalIncrementalToken = tokens[finalIncrementalTokenIndex], processedTokens = [...tokens];
|
|
1786
|
-
return finalIncrementalToken !== void 0 && !isPrefixToken(finalIncrementalToken) && processedTokens.splice(
|
|
1787
|
-
finalIncrementalTokenIndex,
|
|
1788
|
-
1,
|
|
1789
|
-
`${finalIncrementalToken}*`
|
|
1790
|
-
), `[@] match text::query("${processedTokens.join(" ").replace(/"/g, '\\"')}")`;
|
|
1791
|
-
}
|
|
1792
|
-
export {
|
|
1793
|
-
API_VERSION,
|
|
1794
|
-
AuthStateType,
|
|
1795
|
-
CORE_SDK_VERSION,
|
|
1796
|
-
DEFAULT_API_VERSION$1 as DEFAULT_API_VERSION,
|
|
1797
|
-
PREVIEW_PROJECTION,
|
|
1798
|
-
PROJECT_API_VERSION,
|
|
1799
|
-
REQUEST_TAG_PREFIX,
|
|
1800
|
-
USERS_STATE_CLEAR_DELAY,
|
|
1801
|
-
addSubscription,
|
|
1802
|
-
authStore,
|
|
1803
|
-
authStore$1,
|
|
1804
|
-
bindActionByResource,
|
|
1805
|
-
bindActionByResourceAndPerspective,
|
|
1806
|
-
bindActionGlobally,
|
|
1807
|
-
cancelRequest,
|
|
1808
|
-
clientStore$1 as clientStore,
|
|
1809
|
-
configureLogging,
|
|
1810
|
-
createGroqSearchFilter,
|
|
1811
|
-
createLoggedInAuthState,
|
|
1812
|
-
createLogger,
|
|
1813
|
-
createStateSourceAction,
|
|
1814
|
-
defineFetcher,
|
|
1815
|
-
defineMutation,
|
|
1816
|
-
defineStore,
|
|
1817
|
-
getActiveReleasesState,
|
|
1818
|
-
getAllReleasesState,
|
|
1819
|
-
getAuthCode,
|
|
1820
|
-
getAuthLogger,
|
|
1821
|
-
getAuthState,
|
|
1822
|
-
getCleanedUrl,
|
|
1823
|
-
getClient,
|
|
1824
|
-
getClientErrorApiBody,
|
|
1825
|
-
getClientErrorApiDescription,
|
|
1826
|
-
getClientErrorApiType,
|
|
1827
|
-
getClientState,
|
|
1828
|
-
getCurrentUserState,
|
|
1829
|
-
getDashboardOrganizationId,
|
|
1830
|
-
getDefaultLocation,
|
|
1831
|
-
getIsInDashboardState,
|
|
1832
|
-
getLoginUrlState,
|
|
1833
|
-
getPerspectiveState,
|
|
1834
|
-
getQueryKey,
|
|
1835
|
-
getQueryState,
|
|
1836
|
-
getTokenFromLocation,
|
|
1837
|
-
getTokenState,
|
|
1838
|
-
getUsersKey,
|
|
1839
|
-
initializeRequest,
|
|
1840
|
-
insecureRandomId,
|
|
1841
|
-
isCanvasResource,
|
|
1842
|
-
isCanvasSource,
|
|
1843
|
-
isDatasetResource,
|
|
1844
|
-
isDatasetSource,
|
|
1845
|
-
isDeepEqual,
|
|
1846
|
-
isMediaLibraryResource,
|
|
1847
|
-
isMediaLibrarySource,
|
|
1848
|
-
isProjectUserNotFoundClientError,
|
|
1849
|
-
isReleasePerspective,
|
|
1850
|
-
isStudioConfig,
|
|
1851
|
-
omitProperty,
|
|
1852
|
-
parseQueryKey,
|
|
1853
|
-
parseUsersKey,
|
|
1854
|
-
pickProperties,
|
|
1855
|
-
removeSubscription,
|
|
1856
|
-
resolveQuery,
|
|
1857
|
-
setAuthToken,
|
|
1858
|
-
setCleanupTimeout,
|
|
1859
|
-
setUsersData,
|
|
1860
|
-
setUsersError,
|
|
1861
|
-
transformProjectionToPreview,
|
|
1862
|
-
updateLastLoadMoreRequest
|
|
1863
|
-
};
|
|
1864
|
-
//# sourceMappingURL=createGroqSearchFilter.js.map
|