@sanity/sdk 3.0.0-rc.0 → 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.
Files changed (241) hide show
  1. package/README.md +12 -0
  2. package/dist/_exports/_internal.d.ts +163 -0
  3. package/dist/_exports/_internal.d.ts.map +1 -0
  4. package/dist/_exports/_internal.js +332 -0
  5. package/dist/_exports/_internal.js.map +1 -0
  6. package/dist/_exports/agent.d.ts +65 -0
  7. package/dist/_exports/agent.d.ts.map +1 -0
  8. package/dist/_exports/agent.js +71 -0
  9. package/dist/_exports/agent.js.map +1 -0
  10. package/dist/_exports/comlink.d.ts +118 -0
  11. package/dist/_exports/comlink.d.ts.map +1 -0
  12. package/dist/_exports/comlink.js +69 -0
  13. package/dist/_exports/comlink.js.map +1 -0
  14. package/dist/authStore-CtE9bLHW.js +754 -0
  15. package/dist/authStore-CtE9bLHW.js.map +1 -0
  16. package/dist/authStore-DKFX8fn7.d.ts +3179 -0
  17. package/dist/authStore-DKFX8fn7.d.ts.map +1 -0
  18. package/dist/clientStore-BtE2-q2i.js +90 -0
  19. package/dist/clientStore-BtE2-q2i.js.map +1 -0
  20. package/dist/createSanityInstance-DUI1bGIg.d.ts +278 -0
  21. package/dist/createSanityInstance-DUI1bGIg.d.ts.map +1 -0
  22. package/dist/createStateSourceAction-BOKtqFNm.js +300 -0
  23. package/dist/createStateSourceAction-BOKtqFNm.js.map +1 -0
  24. package/dist/getEnv-D5RGkQLu.js +8 -0
  25. package/dist/getEnv-D5RGkQLu.js.map +1 -0
  26. package/dist/getNodeState-CR3__B2D.js +67 -0
  27. package/dist/getNodeState-CR3__B2D.js.map +1 -0
  28. package/dist/index.d.ts +3 -2332
  29. package/dist/index.js +4171 -4332
  30. package/dist/index.js.map +1 -1
  31. package/dist/logger-DAtJb5RQ.js +173 -0
  32. package/dist/logger-DAtJb5RQ.js.map +1 -0
  33. package/dist/object-CxXlSVg7.js +83 -0
  34. package/dist/object-CxXlSVg7.js.map +1 -0
  35. package/dist/queryStore-DPf9sN3V.js +1346 -0
  36. package/dist/queryStore-DPf9sN3V.js.map +1 -0
  37. package/dist/rolldown-runtime-vyAXikos.js +9 -0
  38. package/dist/setCleanupTimeout-BiM6q1KF.js +31 -0
  39. package/dist/setCleanupTimeout-BiM6q1KF.js.map +1 -0
  40. package/dist/telemetryManager-Dq_qCkeI.js +127 -0
  41. package/dist/telemetryManager-Dq_qCkeI.js.map +1 -0
  42. package/dist/version-BChjsi4u.js +9 -0
  43. package/dist/version-BChjsi4u.js.map +1 -0
  44. package/package.json +47 -52
  45. package/src/_exports/_internal.ts +27 -0
  46. package/src/_exports/agent.ts +19 -0
  47. package/src/_exports/comlink.ts +16 -0
  48. package/src/_exports/index.ts +125 -64
  49. package/src/access/checkPermissions.test.ts +55 -0
  50. package/src/access/checkPermissions.ts +54 -0
  51. package/src/agent/agentActions.test.ts +16 -60
  52. package/src/agent/agentActions.ts +25 -38
  53. package/src/applications/applications.test-d.ts +88 -0
  54. package/src/applications/applications.test.ts +130 -0
  55. package/src/applications/applications.ts +367 -0
  56. package/src/auth/authLogger.ts +30 -0
  57. package/src/auth/authStore.test.ts +194 -13
  58. package/src/auth/authStore.ts +58 -26
  59. package/src/auth/getOrganizationVerificationState.test.ts +18 -17
  60. package/src/auth/getOrganizationVerificationState.ts +4 -4
  61. package/src/auth/handleAuthCallback.test.ts +35 -1
  62. package/src/auth/handleAuthCallback.ts +25 -6
  63. package/src/auth/logout.test.ts +75 -2
  64. package/src/auth/logout.ts +23 -4
  65. package/src/auth/refreshStampedToken.test.ts +219 -469
  66. package/src/auth/refreshStampedToken.ts +79 -195
  67. package/src/auth/studioAuth.ts +1 -1
  68. package/src/auth/studioModeAuth.ts +2 -1
  69. package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +146 -13
  70. package/src/auth/subscribeToStateAndFetchCurrentUser.ts +37 -6
  71. package/src/auth/subscribeToStorageEventsAndSetToken.test.ts +2 -0
  72. package/src/client/clientStore.test.ts +62 -37
  73. package/src/client/clientStore.ts +45 -75
  74. package/src/client/liveEvents.test.ts +151 -0
  75. package/src/client/liveEvents.ts +107 -0
  76. package/src/comlink/controller/actions/destroyController.test.ts +4 -1
  77. package/src/comlink/controller/actions/getOrCreateChannel.test.ts +4 -1
  78. package/src/comlink/controller/actions/getOrCreateChannel.ts +2 -2
  79. package/src/comlink/controller/actions/getOrCreateController.test.ts +4 -1
  80. package/src/comlink/controller/actions/releaseChannel.test.ts +1 -1
  81. package/src/comlink/controller/comlinkControllerStore.test.ts +4 -1
  82. package/src/comlink/node/actions/getOrCreateNode.test.ts +9 -3
  83. package/src/comlink/node/actions/getOrCreateNode.ts +2 -2
  84. package/src/comlink/node/actions/releaseNode.test.ts +7 -4
  85. package/src/comlink/node/comlinkNodeStore.test.ts +2 -2
  86. package/src/comlink/node/getNodeState.test.ts +1 -1
  87. package/src/comlink/node/getNodeState.ts +2 -1
  88. package/src/comments/addonDatasetStore.test.ts +215 -0
  89. package/src/comments/addonDatasetStore.ts +249 -0
  90. package/src/comments/buildCommentThreads.test.ts +83 -0
  91. package/src/comments/buildCommentThreads.ts +54 -0
  92. package/src/comments/commentActions.test.ts +540 -0
  93. package/src/comments/commentActions.ts +555 -0
  94. package/src/comments/commentFieldPath.test.ts +40 -0
  95. package/src/comments/commentFieldPath.ts +44 -0
  96. package/src/comments/commentsConstants.ts +80 -0
  97. package/src/comments/commentsStore.test.ts +419 -0
  98. package/src/comments/commentsStore.ts +483 -0
  99. package/src/comments/normalizeComment.test.ts +116 -0
  100. package/src/comments/normalizeComment.ts +45 -0
  101. package/src/comments/observeComments.test.ts +193 -0
  102. package/src/comments/observeComments.ts +113 -0
  103. package/src/comments/reducers.test.ts +277 -0
  104. package/src/comments/reducers.ts +316 -0
  105. package/src/comments/types.ts +249 -0
  106. package/src/comments/weakenReferences.test.ts +47 -0
  107. package/src/comments/weakenReferences.ts +29 -0
  108. package/src/config/__tests__/handles.test.ts +18 -12
  109. package/src/config/handles.ts +25 -7
  110. package/src/config/sanityConfig.ts +40 -82
  111. package/src/datasets/datasets.test.ts +2 -2
  112. package/src/datasets/datasets.ts +10 -4
  113. package/src/document/actions.test.ts +115 -33
  114. package/src/document/actions.ts +212 -15
  115. package/src/document/applyDocumentActions.test.ts +35 -13
  116. package/src/document/applyDocumentActions.ts +30 -9
  117. package/src/document/documentConstants.ts +15 -0
  118. package/src/document/documentStore.concurrency.test.ts +1306 -0
  119. package/src/document/documentStore.test.ts +753 -273
  120. package/src/document/documentStore.ts +197 -75
  121. package/src/document/events.test.ts +57 -2
  122. package/src/document/events.ts +82 -26
  123. package/src/document/listen.test.ts +56 -0
  124. package/src/document/listen.ts +74 -21
  125. package/src/document/listenerEventOperators.test.ts +311 -0
  126. package/src/document/listenerEventOperators.ts +217 -0
  127. package/src/document/patchOperations.test.ts +76 -2
  128. package/src/document/patchOperations.ts +60 -1
  129. package/src/document/permissions.test.ts +107 -60
  130. package/src/document/permissions.ts +44 -19
  131. package/src/document/processActions/create.ts +138 -0
  132. package/src/document/processActions/delete.ts +100 -0
  133. package/src/document/processActions/discard.ts +63 -0
  134. package/src/document/processActions/edit.ts +154 -0
  135. package/src/document/processActions/processActions.ts +218 -0
  136. package/src/document/processActions/publish.ts +120 -0
  137. package/src/document/processActions/releaseArchive.ts +77 -0
  138. package/src/document/processActions/releaseCreate.ts +59 -0
  139. package/src/document/processActions/releaseDelete.ts +65 -0
  140. package/src/document/processActions/releaseEdit.ts +37 -0
  141. package/src/document/processActions/releasePublish.ts +45 -0
  142. package/src/document/processActions/releaseSchedule.ts +87 -0
  143. package/src/document/processActions/releaseUtil.ts +31 -0
  144. package/src/document/processActions/shared.ts +308 -0
  145. package/src/document/processActions/unpublish.ts +85 -0
  146. package/src/document/processActions.test.ts +1129 -121
  147. package/src/document/reducers.test.ts +772 -64
  148. package/src/document/reducers.ts +205 -51
  149. package/src/document/resourceRules.test.ts +178 -0
  150. package/src/document/resourceRules.ts +117 -0
  151. package/src/document/sharedListener.test.ts +16 -14
  152. package/src/document/sharedListener.ts +24 -8
  153. package/src/document/util.test.ts +46 -0
  154. package/src/document/util.ts +50 -0
  155. package/src/favorites/favorites.test.ts +5 -6
  156. package/src/installations/installations.test-d.ts +73 -0
  157. package/src/installations/installations.test.ts +62 -0
  158. package/src/installations/installations.ts +206 -0
  159. package/src/organization/organization.test-d.ts +36 -0
  160. package/src/organization/organization.test.ts +138 -0
  161. package/src/organization/organization.ts +138 -0
  162. package/src/organizations/organizations.test-d.ts +56 -0
  163. package/src/organizations/organizations.test.ts +150 -0
  164. package/src/organizations/organizations.ts +107 -0
  165. package/src/presence/bifurTransport.test.ts +201 -9
  166. package/src/presence/bifurTransport.ts +98 -14
  167. package/src/presence/paths.test.ts +70 -0
  168. package/src/presence/paths.ts +41 -0
  169. package/src/presence/presenceStore.test.ts +915 -24
  170. package/src/presence/presenceStore.ts +576 -104
  171. package/src/presence/types.ts +175 -3
  172. package/src/preview/previewProjectionUtils.test.ts +9 -22
  173. package/src/preview/previewProjectionUtils.ts +7 -3
  174. package/src/preview/types.ts +0 -15
  175. package/src/project/project.test-d.ts +37 -0
  176. package/src/project/project.test.ts +157 -12
  177. package/src/project/project.ts +138 -25
  178. package/src/projection/getProjectionState.test.ts +18 -20
  179. package/src/projection/getProjectionState.ts +23 -3
  180. package/src/projection/projectionQuery.ts +5 -5
  181. package/src/projection/projectionStore.test.ts +1 -9
  182. package/src/projection/resolveProjection.test.ts +1 -2
  183. package/src/projection/resolveProjection.ts +16 -0
  184. package/src/projection/subscribeToStateAndFetchBatches.test.ts +1 -1
  185. package/src/projection/subscribeToStateAndFetchBatches.ts +32 -23
  186. package/src/projects/projects.test-d.ts +32 -0
  187. package/src/projects/projects.test.ts +108 -42
  188. package/src/projects/projects.ts +63 -27
  189. package/src/query/queryStore.test.ts +259 -123
  190. package/src/query/queryStore.ts +85 -69
  191. package/src/query/reducers.test.ts +0 -42
  192. package/src/query/reducers.ts +2 -18
  193. package/src/releases/getPerspectiveState.test.ts +17 -23
  194. package/src/releases/getPerspectiveState.ts +8 -20
  195. package/src/releases/observeReleases.test.ts +127 -0
  196. package/src/releases/observeReleases.ts +102 -0
  197. package/src/releases/releasesStore.test.ts +100 -53
  198. package/src/releases/releasesStore.ts +69 -44
  199. package/src/releases/utils/sortReleases.test.ts +38 -2
  200. package/src/releases/utils/sortReleases.ts +15 -10
  201. package/src/store/createActionBinder.test.ts +109 -90
  202. package/src/store/createActionBinder.ts +36 -28
  203. package/src/store/createSanityInstance.test.ts +15 -13
  204. package/src/store/createSanityInstance.ts +14 -2
  205. package/src/store/createStateSourceAction.test.ts +64 -2
  206. package/src/store/createStateSourceAction.ts +38 -43
  207. package/src/store/createStoreInstance.test.ts +4 -2
  208. package/src/store/fetcherStore.test-d.ts +121 -0
  209. package/src/store/fetcherStore.test.ts +299 -0
  210. package/src/store/fetcherStore.ts +801 -0
  211. package/src/telemetry/environment.test.ts +119 -0
  212. package/src/telemetry/environment.ts +92 -0
  213. package/src/telemetry/events.ts +42 -0
  214. package/src/telemetry/initTelemetry.test.ts +432 -0
  215. package/src/telemetry/initTelemetry.ts +218 -0
  216. package/src/telemetry/telemetryManager.test.ts +327 -0
  217. package/src/telemetry/telemetryManager.ts +199 -0
  218. package/src/users/reducers.test.ts +3 -1
  219. package/src/users/reducers.ts +5 -6
  220. package/src/users/types.ts +4 -4
  221. package/src/users/usersStore.test.ts +16 -12
  222. package/src/users/usersStore.ts +5 -1
  223. package/src/utils/buildQuery.test.ts +14 -0
  224. package/src/utils/buildQuery.ts +17 -0
  225. package/src/utils/createFetcherStore.test.ts +7 -5
  226. package/src/utils/createFetcherStore.ts +8 -5
  227. package/src/utils/getStagingApiHost.test.ts +21 -0
  228. package/src/utils/getStagingApiHost.ts +14 -0
  229. package/src/utils/ids.test.ts +1 -29
  230. package/src/utils/ids.ts +0 -10
  231. package/src/utils/includeShape.ts +36 -0
  232. package/src/utils/isImportError.test.ts +72 -0
  233. package/src/utils/isImportError.ts +34 -0
  234. package/src/utils/logger.test.ts +12 -0
  235. package/src/utils/logger.ts +8 -3
  236. package/src/utils/object.test.ts +95 -0
  237. package/src/utils/object.ts +142 -0
  238. package/src/utils/setCleanupTimeout.ts +37 -0
  239. package/src/document/processActions.ts +0 -707
  240. package/src/utils/defineIntent.test.ts +0 -477
  241. package/src/utils/defineIntent.ts +0 -244
@@ -0,0 +1,173 @@
1
+ const LOG_LEVEL_PRIORITY = {
2
+ error: 0,
3
+ warn: 1,
4
+ info: 2,
5
+ debug: 3,
6
+ trace: 4
7
+ }, DEFAULT_CONFIG = {
8
+ level: "warn",
9
+ namespaces: [],
10
+ internal: !1,
11
+ timestamps: !0,
12
+ enableInProduction: !1,
13
+ handler: {
14
+ error: console.error.bind(console),
15
+ warn: console.warn.bind(console),
16
+ info: console.info.bind(console),
17
+ debug: console.debug.bind(console),
18
+ trace: console.debug.bind(console)
19
+ }
20
+ };
21
+ /**
22
+ * Parse DEBUG environment variable for automatic logging configuration
23
+ *
24
+ * Supports patterns similar to Sanity CLI/Studio:
25
+ * - DEBUG=sanity:* (all namespaces, debug level)
26
+ * - DEBUG=sanity:auth,sanity:document (specific namespaces)
27
+ * - DEBUG=sanity:trace:* (all namespaces, trace level)
28
+ * - DEBUG=sanity:*:internal (enable internal logs)
29
+ *
30
+ * @internal
31
+ */
32
+ function parseDebugEnvVar() {
33
+ if (typeof process > "u" || !process.env?.DEBUG) return null;
34
+ let debug = process.env.DEBUG;
35
+ if (!debug.includes("sanity")) return null;
36
+ let config = {}, levelMatch = debug.match(/sanity:(trace|debug|info|warn|error):/), hasLevelSpecifier = !!levelMatch;
37
+ if (config.level = levelMatch ? levelMatch[1] : "debug", debug === "sanity") config.namespaces = ["*"];
38
+ else if (hasLevelSpecifier && debug.match(/sanity:(trace|debug|info|warn|error):\*/)) config.namespaces = ["*"];
39
+ else if (!hasLevelSpecifier && debug.includes("sanity:*")) config.namespaces = ["*"];
40
+ else {
41
+ let namespaces = debug.split(",").filter((s) => s.includes("sanity:")).map((s) => {
42
+ let cleaned = s.replace(/^sanity:/, "");
43
+ return hasLevelSpecifier && cleaned.match(/^(trace|debug|info|warn|error):/) ? cleaned.split(":").slice(1).join(":") : cleaned.split(":")[0];
44
+ }).filter(Boolean).filter((ns) => ns !== "*");
45
+ namespaces.length > 0 && (config.namespaces = namespaces);
46
+ }
47
+ return debug.includes(":internal") && (config.internal = !0), config;
48
+ }
49
+ const envConfig = parseDebugEnvVar();
50
+ let globalConfig = {
51
+ ...DEFAULT_CONFIG,
52
+ ...envConfig ?? {}
53
+ };
54
+ /* c8 ignore next 14 */
55
+ envConfig && ([
56
+ "info",
57
+ "debug",
58
+ "trace"
59
+ ].includes(globalConfig.level) || globalConfig.level === "warn") && console.info(`[${(/* @__PURE__ */ new Date()).toISOString()}] [INFO] [sdk] Logging auto-configured from DEBUG environment variable`, {
60
+ level: globalConfig.level,
61
+ namespaces: globalConfig.namespaces,
62
+ internal: globalConfig.internal,
63
+ source: "env:DEBUG",
64
+ value: typeof process < "u" ? process.env?.DEBUG : void 0
65
+ });
66
+ /**
67
+ * Configure the global logging system
68
+ * @public
69
+ */
70
+ function configureLogging(config) {
71
+ globalConfig = {
72
+ ...globalConfig,
73
+ ...config,
74
+ handler: config.handler ?? globalConfig.handler
75
+ };
76
+ }
77
+ /**
78
+ * Check if logging is enabled in the current environment
79
+ * @internal
80
+ */
81
+ function isLoggingEnabled() {
82
+ return typeof process < "u" && process.env?.NODE_ENV === "production" ? globalConfig.enableInProduction : !0;
83
+ }
84
+ /**
85
+ * Check if a namespace is enabled
86
+ * @internal
87
+ */
88
+ function isNamespaceEnabled(namespace) {
89
+ return isLoggingEnabled() ? globalConfig.namespaces.includes("*") ? !0 : globalConfig.namespaces.includes(namespace) : !1;
90
+ }
91
+ /**
92
+ * Check if a log level is enabled
93
+ * @internal
94
+ */
95
+ function isLevelEnabled(level) {
96
+ return isLoggingEnabled() ? LOG_LEVEL_PRIORITY[level] <= LOG_LEVEL_PRIORITY[globalConfig.level] : !1;
97
+ }
98
+ /**
99
+ * Format a log message with timestamp, namespace, and instance context
100
+ * @internal
101
+ */
102
+ function formatMessage(namespace, level, message, context) {
103
+ let parts = [];
104
+ if (globalConfig.timestamps) {
105
+ let timestamp = (/* @__PURE__ */ new Date()).toISOString();
106
+ parts.push(`[${timestamp}]`);
107
+ }
108
+ parts.push(`[${level.toUpperCase()}]`), parts.push(`[${namespace}]`);
109
+ let instanceContext = context?.instanceContext;
110
+ 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];
111
+ }
112
+ /**
113
+ * Sanitize context for logging (remove sensitive data)
114
+ * @internal
115
+ * @remarks
116
+ * This performs shallow sanitization only - it redacts top-level keys that contain
117
+ * sensitive names (token, password, secret, apiKey, authorization).
118
+ * Nested sensitive data (e.g., `\{auth: \{token: 'secret'\}\}`) will NOT be redacted.
119
+ * If deep sanitization is needed in the future, this can be enhanced to recursively
120
+ * traverse nested objects.
121
+ */
122
+ function sanitizeContext(context) {
123
+ if (!context || Object.keys(context).length === 0) return;
124
+ let sanitized = { ...context }, sensitiveKeys = [
125
+ "token",
126
+ "password",
127
+ "secret",
128
+ "apiKey",
129
+ "authorization"
130
+ ];
131
+ for (let key of Object.keys(sanitized)) sensitiveKeys.some((sensitive) => key.toLowerCase().includes(sensitive)) && (sanitized[key] = "[REDACTED]");
132
+ return sanitized;
133
+ }
134
+ /**
135
+ * Create a logger for a specific namespace
136
+ * @param namespace - A string identifier for the logging domain (e.g., 'auth', 'document')
137
+ * @param baseContext - Optional base context to include in all log messages
138
+ * @remarks
139
+ * If baseContext includes an `instanceContext` property (with projectId, dataset, instanceId),
140
+ * it will be automatically formatted into the log output for easier debugging of
141
+ * multi-instance scenarios.
142
+ * @public
143
+ */
144
+ function createLogger(namespace, baseContext) {
145
+ let logAtLevel = (level, message, context) => {
146
+ if (!isNamespaceEnabled(namespace) || !isLevelEnabled(level) || context?.internal && !globalConfig.internal) return;
147
+ let [formatted, finalContext] = formatMessage(namespace, level, message, sanitizeContext({
148
+ ...baseContext,
149
+ ...context
150
+ }));
151
+ globalConfig.handler[level](formatted, finalContext);
152
+ };
153
+ return {
154
+ namespace,
155
+ error: (message, context) => logAtLevel("error", message, context),
156
+ warn: (message, context) => logAtLevel("warn", message, context),
157
+ info: (message, context) => logAtLevel("info", message, context),
158
+ debug: (message, context) => logAtLevel("debug", message, context),
159
+ trace: (message, context) => logAtLevel("trace", message, {
160
+ ...context,
161
+ internal: !0
162
+ }),
163
+ isLevelEnabled: (level) => isNamespaceEnabled(namespace) && isLevelEnabled(level),
164
+ child: (childContext) => createLogger(namespace, {
165
+ ...baseContext,
166
+ ...childContext
167
+ }),
168
+ getInstanceContext: () => baseContext?.instanceContext
169
+ };
170
+ }
171
+ export { createLogger as n, configureLogging as t };
172
+
173
+ //# sourceMappingURL=logger-DAtJb5RQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-DAtJb5RQ.js","names":[],"sources":["../src/utils/logger.ts"],"sourcesContent":["/**\n * Logging infrastructure for the Sanity SDK\n *\n * Provides multi-level, namespace-based logging for both SDK users and maintainers.\n * In production builds, all logging can be stripped via tree-shaking.\n *\n * @example SDK User\n * ```ts\n * import {configureLogging} from '@sanity/sdk'\n *\n * configureLogging({\n * level: 'info',\n * namespaces: ['auth', 'document']\n * })\n * ```\n *\n * @example SDK Maintainer\n * ```ts\n * configureLogging({\n * level: 'trace',\n * namespaces: ['*'],\n * internal: true\n * })\n * ```\n */\n\n/**\n * Log levels in order of verbosity (least to most)\n * - error: Critical failures that prevent operation\n * - warn: Issues that may cause problems but don't stop execution\n * - info: High-level informational messages (SDK user level)\n * - debug: Detailed debugging information (maintainer level)\n * - trace: Very detailed tracing (maintainer level, includes RxJS streams)\n * @public\n */\nexport type LogLevel = 'error' | 'warn' | 'info' | 'debug' | 'trace'\n\n/**\n * Log namespaces organize logs by functional domain\n *\n * @remarks\n * This is an extensible string type. As logging is added to more modules,\n * additional namespaces will be recognized. Currently implemented namespaces\n * will be documented as they are added.\n * @internal\n */\nexport type LogNamespace = string\n\n/**\n * Configuration for the logging system\n * @public\n */\nexport interface LoggerConfig {\n /**\n * Minimum log level to output\n * @defaultValue 'warn'\n */\n level?: LogLevel\n\n /**\n * Namespaces to enable. Use ['*'] for all namespaces\n * @defaultValue []\n * @remarks\n * Available namespaces depend on which modules have logging integrated.\n * Check the SDK documentation for the current list of instrumented modules.\n * @example ['auth', 'document']\n */\n namespaces?: string[]\n\n /**\n * Enable internal/maintainer-level logging\n * Shows RxJS streams, store internals, etc.\n * @defaultValue false\n */\n internal?: boolean\n\n /**\n * Custom log handler (for testing or custom output)\n * @defaultValue console methods\n */\n handler?: LogHandler\n\n /**\n * Enable timestamps in log output\n * @defaultValue true\n */\n timestamps?: boolean\n\n /**\n * Enable in production builds\n * @defaultValue false\n */\n enableInProduction?: boolean\n}\n\n/**\n * Custom log handler interface\n *\n * @internal\n */\nexport interface LogHandler {\n error: (message: string, context?: LogContext) => void\n warn: (message: string, context?: LogContext) => void\n info: (message: string, context?: LogContext) => void\n debug: (message: string, context?: LogContext) => void\n trace: (message: string, context?: LogContext) => void\n}\n\n/**\n * Context object attached to log messages\n *\n * This interface allows you to attach arbitrary contextual data to log messages.\n * The index signature `[key: string]: unknown` enables you to add any custom\n * properties relevant to your log entry (e.g., `userId`, `documentId`, `action`, etc.).\n *\n * **Sensitive data sanitization:**\n * Top-level keys containing sensitive names (`token`, `password`, `secret`, `apiKey`,\n * `authorization`) are automatically redacted to `[REDACTED]` in log output.\n *\n * @example\n * ```ts\n * logger.info('User logged in', {\n * userId: '123', // Custom context\n * action: 'login', // Custom context\n * token: 'secret' // Will be redacted to [REDACTED]\n * })\n * ```\n *\n * @internal\n */\nexport interface LogContext {\n /**\n * Custom context properties that provide additional information about the log entry.\n * Any key-value pairs can be added here (e.g., userId, documentId, requestId, etc.).\n * Keys with sensitive names (token, password, secret, apiKey, authorization) are\n * automatically sanitized.\n */\n [key: string]: unknown\n /** Error object if logging an error */\n error?: Error | unknown\n /** Duration in milliseconds for timed operations */\n duration?: number\n /** Stack trace for debugging */\n stack?: string\n /** Instance context (automatically added when available) */\n instanceContext?: InstanceContext\n}\n\n/**\n * Instance context information automatically added to logs\n * @internal\n */\nexport interface InstanceContext {\n /** Unique instance ID */\n instanceId?: string\n /** Project ID */\n projectId?: string\n /** Dataset name */\n dataset?: string\n}\n\n/**\n * Logger instance for a specific namespace\n * @internal\n */\nexport interface Logger {\n readonly namespace: string\n error: (message: string, context?: LogContext) => void\n warn: (message: string, context?: LogContext) => void\n info: (message: string, context?: LogContext) => void\n debug: (message: string, context?: LogContext) => void\n trace: (message: string, context?: LogContext) => void\n /** Check if a log level is enabled (for performance-sensitive code) */\n isLevelEnabled: (level: LogLevel) => boolean\n /** Create a child logger with extended context */\n child: (context: LogContext) => Logger\n /** Get the instance context if available */\n getInstanceContext: () => InstanceContext | undefined\n}\n\n// Log level priority (lower number = higher priority)\nconst LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4,\n}\n\n// Default logging configuration\nconst DEFAULT_CONFIG: Required<LoggerConfig> = {\n level: 'warn',\n namespaces: [],\n internal: false,\n timestamps: true,\n enableInProduction: false,\n handler: {\n // eslint-disable-next-line no-console\n error: console.error.bind(console),\n // eslint-disable-next-line no-console\n warn: console.warn.bind(console),\n // eslint-disable-next-line no-console\n info: console.info.bind(console),\n // eslint-disable-next-line no-console\n debug: console.debug.bind(console),\n // eslint-disable-next-line no-console\n trace: console.debug.bind(console), // trace uses console.debug\n },\n}\n\n/**\n * Parse DEBUG environment variable for automatic logging configuration\n *\n * Supports patterns similar to Sanity CLI/Studio:\n * - DEBUG=sanity:* (all namespaces, debug level)\n * - DEBUG=sanity:auth,sanity:document (specific namespaces)\n * - DEBUG=sanity:trace:* (all namespaces, trace level)\n * - DEBUG=sanity:*:internal (enable internal logs)\n *\n * @internal\n */\nexport function parseDebugEnvVar(): Partial<LoggerConfig> | null {\n if (typeof process === 'undefined' || !process.env?.['DEBUG']) {\n return null\n }\n\n const debug = process.env['DEBUG']\n\n // Only process if it includes 'sanity'\n if (!debug.includes('sanity')) {\n return null\n }\n\n const config: Partial<LoggerConfig> = {}\n\n // Parse level from pattern like \"sanity:trace:*\" or \"sanity:debug:*\"\n const levelMatch = debug.match(/sanity:(trace|debug|info|warn|error):/)\n const hasLevelSpecifier = !!levelMatch\n if (levelMatch) {\n config.level = levelMatch[1] as LogLevel\n } else {\n // Default to debug level if just \"sanity:*\" or \"sanity:namespace\"\n config.level = 'debug'\n }\n\n // Parse namespaces\n if (debug === 'sanity') {\n config.namespaces = ['*']\n } else if (hasLevelSpecifier && debug.match(/sanity:(trace|debug|info|warn|error):\\*/)) {\n // Pattern like \"sanity:trace:*\" - wildcard after level\n config.namespaces = ['*']\n } else if (!hasLevelSpecifier && debug.includes('sanity:*')) {\n // Pattern like \"sanity:*\" - wildcard without level\n config.namespaces = ['*']\n } else {\n // Extract specific namespaces like \"sanity:auth,sanity:document\"\n const namespaces = debug\n .split(',')\n .filter((s) => s.includes('sanity:'))\n .map((s) => {\n // Remove 'sanity:' prefix\n const cleaned = s.replace(/^sanity:/, '')\n // If there's a level specifier, skip it\n if (hasLevelSpecifier && cleaned.match(/^(trace|debug|info|warn|error):/)) {\n // Get the part after the level: \"trace:auth\" -> \"auth\"\n return cleaned.split(':').slice(1).join(':')\n }\n // Otherwise get the first part: \"auth:something\" -> \"auth\"\n return cleaned.split(':')[0]\n })\n .filter(Boolean)\n .filter((ns) => ns !== '*') // Filter out wildcards\n\n if (namespaces.length > 0) {\n config.namespaces = namespaces\n }\n }\n\n // Check for internal flag: DEBUG=sanity:*:internal\n if (debug.includes(':internal')) {\n config.internal = true\n }\n\n return config\n}\n\n// Global configuration - initialized with env var settings if present\nconst envConfig = parseDebugEnvVar()\nlet globalConfig: Required<LoggerConfig> = {\n ...DEFAULT_CONFIG,\n ...(envConfig ?? {}),\n}\n\n// Log that env var configuration was detected (only if DEBUG is set)\n// Note: This runs at module initialization, difficult to test without complex module mocking\n/* c8 ignore next 14 */\nif (envConfig) {\n const shouldLog =\n ['info', 'debug', 'trace'].includes(globalConfig.level) || globalConfig.level === 'warn'\n if (shouldLog) {\n // eslint-disable-next-line no-console\n console.info(\n `[${new Date().toISOString()}] [INFO] [sdk] Logging auto-configured from DEBUG environment variable`,\n {\n level: globalConfig.level,\n namespaces: globalConfig.namespaces,\n internal: globalConfig.internal,\n source: 'env:DEBUG',\n value: typeof process !== 'undefined' ? process.env?.['DEBUG'] : undefined,\n },\n )\n }\n}\n\n/**\n * Configure the global logging system\n * @public\n */\nexport function configureLogging(config: LoggerConfig): void {\n globalConfig = {\n ...globalConfig,\n ...config,\n handler: config.handler ?? globalConfig.handler,\n }\n}\n\n/**\n * Get the current logging configuration\n * @internal\n */\nexport function getLoggingConfig(): Readonly<Required<LoggerConfig>> {\n return globalConfig\n}\n\n/**\n * Reset logging to default configuration\n * @internal\n */\nexport function resetLogging(): void {\n globalConfig = {...DEFAULT_CONFIG}\n}\n\n/**\n * Check if logging is enabled in the current environment\n * @internal\n */\nfunction isLoggingEnabled(): boolean {\n // In production, only log if explicitly enabled\n if (typeof process !== 'undefined' && process.env?.['NODE_ENV'] === 'production') {\n return globalConfig.enableInProduction\n }\n return true\n}\n\n/**\n * Check if a namespace is enabled\n * @internal\n */\nfunction isNamespaceEnabled(namespace: string): boolean {\n if (!isLoggingEnabled()) return false\n if (globalConfig.namespaces.includes('*')) return true\n return globalConfig.namespaces.includes(namespace)\n}\n\n/**\n * Check if a log level is enabled\n * @internal\n */\nfunction isLevelEnabled(level: LogLevel): boolean {\n if (!isLoggingEnabled()) return false\n return LOG_LEVEL_PRIORITY[level] <= LOG_LEVEL_PRIORITY[globalConfig.level]\n}\n\n/**\n * Format a log message with timestamp, namespace, and instance context\n * @internal\n */\nfunction formatMessage(\n namespace: LogNamespace,\n level: LogLevel,\n message: string,\n context?: LogContext,\n): [string, LogContext | undefined] {\n const parts: string[] = []\n\n if (globalConfig.timestamps) {\n const timestamp = new Date().toISOString()\n parts.push(`[${timestamp}]`)\n }\n\n parts.push(`[${level.toUpperCase()}]`)\n parts.push(`[${namespace}]`)\n\n // Add instance context if available\n const instanceContext = context?.instanceContext\n if (instanceContext) {\n if (instanceContext.projectId) {\n parts.push(`[project:${instanceContext.projectId}]`)\n }\n if (instanceContext.dataset) {\n parts.push(`[dataset:${instanceContext.dataset}]`)\n }\n if (instanceContext.instanceId) {\n parts.push(`[instance:${instanceContext.instanceId.slice(0, 8)}]`)\n }\n }\n\n parts.push(message)\n\n return [parts.join(' '), context]\n}\n\n/**\n * Sanitize context for logging (remove sensitive data)\n * @internal\n * @remarks\n * This performs shallow sanitization only - it redacts top-level keys that contain\n * sensitive names (token, password, secret, apiKey, authorization).\n * Nested sensitive data (e.g., `\\{auth: \\{token: 'secret'\\}\\}`) will NOT be redacted.\n * If deep sanitization is needed in the future, this can be enhanced to recursively\n * traverse nested objects.\n */\nfunction sanitizeContext(context?: LogContext): LogContext | undefined {\n if (!context || Object.keys(context).length === 0) return undefined\n\n const sanitized = {...context}\n\n // Remove or redact sensitive fields at the top level\n const sensitiveKeys = ['token', 'password', 'secret', 'apiKey', 'authorization']\n for (const key of Object.keys(sanitized)) {\n if (sensitiveKeys.some((sensitive) => key.toLowerCase().includes(sensitive))) {\n sanitized[key] = '[REDACTED]'\n }\n }\n\n return sanitized\n}\n\n/**\n * Create a logger for a specific namespace\n * @param namespace - A string identifier for the logging domain (e.g., 'auth', 'document')\n * @param baseContext - Optional base context to include in all log messages\n * @remarks\n * If baseContext includes an `instanceContext` property (with projectId, dataset, instanceId),\n * it will be automatically formatted into the log output for easier debugging of\n * multi-instance scenarios.\n * @public\n */\nexport function createLogger(namespace: string, baseContext?: LogContext): Logger {\n const logAtLevel = (level: LogLevel, message: string, context?: LogContext) => {\n // Early return if namespace or level not enabled\n if (!isNamespaceEnabled(namespace)) return\n if (!isLevelEnabled(level)) return\n\n // Skip internal logs if not enabled\n if (context?.['internal'] && !globalConfig.internal) return\n\n const mergedContext = {...baseContext, ...context}\n const sanitized = sanitizeContext(mergedContext)\n const [formatted, finalContext] = formatMessage(namespace, level, message, sanitized)\n\n globalConfig.handler[level](formatted, finalContext)\n }\n\n const logger: Logger = {\n namespace,\n error: (message, context) => logAtLevel('error', message, context),\n warn: (message, context) => logAtLevel('warn', message, context),\n info: (message, context) => logAtLevel('info', message, context),\n debug: (message, context) => logAtLevel('debug', message, context),\n trace: (message, context) => logAtLevel('trace', message, {...context, internal: true}),\n isLevelEnabled: (level) => isNamespaceEnabled(namespace) && isLevelEnabled(level),\n child: (childContext) => createLogger(namespace, {...baseContext, ...childContext}),\n getInstanceContext: () => baseContext?.instanceContext,\n }\n\n return logger\n}\n\n/**\n * Create a performance timer for measuring operation duration\n * @internal\n */\nexport function createTimer(\n namespace: string,\n operation: string,\n): {end: (message?: string, context?: LogContext) => number} {\n const logger = createLogger(namespace)\n const start = performance.now()\n\n return {\n end: (message?: string, context?: LogContext): number => {\n const duration = performance.now() - start\n logger.debug(message ?? `${operation} completed`, {\n ...context,\n operation,\n duration,\n })\n return duration\n },\n }\n}\n\n/**\n * Utility to log RxJS operator execution (for maintainers)\n * Will be exported in future PR when logging is added to stores\n * @internal\n */\n/* c8 ignore next 4 */\nfunction logRxJSOperator(namespace: string, operator: string, context?: LogContext): void {\n const logger = createLogger(namespace)\n logger.trace(`RxJS: ${operator}`, {...context, internal: true, operator})\n}\n\n/**\n * Extract instance context from a SanityInstance for logging\n * Will be exported in future PR when logging is added to stores\n * @param instance - The SanityInstance to extract context from\n * @returns Instance context suitable for logging\n * @internal\n */\n/* c8 ignore next 7 */\nfunction getInstanceContext(instance: {\n instanceId?: string\n config?: {projectId?: string; dataset?: string}\n}): InstanceContext {\n return {\n instanceId: instance.instanceId,\n projectId: instance.config?.projectId,\n dataset: instance.config?.dataset,\n }\n}\n\n// Prevent unused function warnings - these will be exported and used in future PRs\n/* c8 ignore next 2 */\nvoid logRxJSOperator\nvoid getInstanceContext\n"],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Returns true when the input is a non-null object.
3
+ *
4
+ * @internal
5
+ */
6
+ function isObject(value) {
7
+ return typeof value == "object" && !!value;
8
+ }
9
+ const hasOwn = (value, key) => Object.prototype.hasOwnProperty.call(value, key), isPlainObject = (value) => {
10
+ if (!isObject(value)) return !1;
11
+ let prototype = Object.getPrototypeOf(value);
12
+ return prototype === Object.prototype || prototype === null;
13
+ };
14
+ /**
15
+ * Creates a shallow copy without the provided property.
16
+ *
17
+ * @internal
18
+ */
19
+ function omitProperty(value, key) {
20
+ if (!value) return {};
21
+ let { [key]: _omitted, ...rest } = value;
22
+ return rest;
23
+ }
24
+ /**
25
+ * Creates a shallow copy containing only the provided properties.
26
+ *
27
+ * @internal
28
+ */
29
+ function pickProperties(value, keys) {
30
+ let result = {};
31
+ for (let key of keys) hasOwn(value, key) && (result[key] = value[key]);
32
+ return result;
33
+ }
34
+ const areSetsEqual = (left, right) => {
35
+ if (left.size !== right.size) return !1;
36
+ let unmatched = [...right];
37
+ outer: for (let leftValue of left) {
38
+ for (let index = 0; index < unmatched.length; index++) if (isDeepEqual(leftValue, unmatched[index])) {
39
+ unmatched.splice(index, 1);
40
+ continue outer;
41
+ }
42
+ return !1;
43
+ }
44
+ return unmatched.length === 0;
45
+ }, areMapsEqual = (left, right) => {
46
+ if (left.size !== right.size) return !1;
47
+ let unmatched = [...right.entries()];
48
+ outer: for (let [leftKey, leftValue] of left) {
49
+ for (let index = 0; index < unmatched.length; index++) {
50
+ let [rightKey, rightValue] = unmatched[index];
51
+ if (isDeepEqual(leftKey, rightKey) && isDeepEqual(leftValue, rightValue)) {
52
+ unmatched.splice(index, 1);
53
+ continue outer;
54
+ }
55
+ }
56
+ return !1;
57
+ }
58
+ return unmatched.length === 0;
59
+ };
60
+ /**
61
+ * Compares values deeply across the plain object, array, map, and set shapes used by the SDK.
62
+ * This helper is intended for acyclic SDK data structures and does not guard against circular
63
+ * references.
64
+ *
65
+ * @internal
66
+ */
67
+ function isDeepEqual(left, right) {
68
+ if (Object.is(left, right)) return !0;
69
+ if (!isObject(left) || !isObject(right)) return !1;
70
+ if (left instanceof Date && right instanceof Date) return left.getTime() === right.getTime();
71
+ if (left instanceof RegExp && right instanceof RegExp) return left.source === right.source && left.flags === right.flags;
72
+ if (left instanceof Set && right instanceof Set) return areSetsEqual(left, right);
73
+ if (left instanceof Map && right instanceof Map) return areMapsEqual(left, right);
74
+ if (Array.isArray(left) || Array.isArray(right)) return !Array.isArray(left) || !Array.isArray(right) || left.length !== right.length ? !1 : left.every((value, index) => isDeepEqual(value, right[index]));
75
+ if (!isPlainObject(left) || !isPlainObject(right)) return !1;
76
+ let leftKeys = Object.keys(left), rightKeys = Object.keys(right);
77
+ if (leftKeys.length !== rightKeys.length) return !1;
78
+ for (let key of leftKeys) if (!hasOwn(right, key) || !isDeepEqual(left[key], right[key])) return !1;
79
+ return !0;
80
+ }
81
+ export { pickProperties as i, isObject as n, omitProperty as r, isDeepEqual as t };
82
+
83
+ //# sourceMappingURL=object-CxXlSVg7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object-CxXlSVg7.js","names":[],"sources":["../src/utils/object.ts"],"sourcesContent":["/**\n * Returns true when the input is a non-null object.\n *\n * @internal\n */\nexport function isObject(value: unknown): value is object {\n return typeof value === 'object' && value !== null\n}\n\nconst hasOwn = (value: object, key: PropertyKey) => Object.prototype.hasOwnProperty.call(value, key)\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (!isObject(value)) return false\n\n const prototype = Object.getPrototypeOf(value)\n return prototype === Object.prototype || prototype === null\n}\n\n/**\n * Creates a shallow copy without the provided property.\n *\n * @internal\n */\nexport function omitProperty<T extends object, K extends keyof T>(\n value: T | null | undefined,\n key: K,\n): Omit<T, K> {\n if (!value) return {} as Omit<T, K>\n\n const {[key]: _omitted, ...rest} = value\n return rest\n}\n\n/**\n * Creates a shallow copy containing only the provided properties.\n *\n * @internal\n */\nexport function pickProperties<T extends object, K extends keyof T>(\n value: T,\n keys: readonly K[],\n): Pick<T, K> {\n const result = {} as Pick<T, K>\n\n for (const key of keys) {\n if (hasOwn(value, key)) {\n result[key] = value[key]\n }\n }\n\n return result\n}\n\nconst areSetsEqual = (left: Set<unknown>, right: Set<unknown>): boolean => {\n if (left.size !== right.size) return false\n\n const unmatched = [...right]\n\n outer: for (const leftValue of left) {\n for (let index = 0; index < unmatched.length; index++) {\n if (isDeepEqual(leftValue, unmatched[index])) {\n unmatched.splice(index, 1)\n continue outer\n }\n }\n\n return false\n }\n\n return unmatched.length === 0\n}\n\nconst areMapsEqual = (left: Map<unknown, unknown>, right: Map<unknown, unknown>): boolean => {\n if (left.size !== right.size) return false\n\n const unmatched = [...right.entries()]\n\n outer: for (const [leftKey, leftValue] of left) {\n for (let index = 0; index < unmatched.length; index++) {\n const [rightKey, rightValue] = unmatched[index]\n\n if (isDeepEqual(leftKey, rightKey) && isDeepEqual(leftValue, rightValue)) {\n unmatched.splice(index, 1)\n continue outer\n }\n }\n\n return false\n }\n\n return unmatched.length === 0\n}\n\n/**\n * Compares values deeply across the plain object, array, map, and set shapes used by the SDK.\n * This helper is intended for acyclic SDK data structures and does not guard against circular\n * references.\n *\n * @internal\n */\nexport function isDeepEqual<T>(left: T, right: T): boolean {\n if (Object.is(left, right)) return true\n\n if (!isObject(left) || !isObject(right)) return false\n\n if (left instanceof Date && right instanceof Date) {\n return left.getTime() === right.getTime()\n }\n\n if (left instanceof RegExp && right instanceof RegExp) {\n return left.source === right.source && left.flags === right.flags\n }\n\n if (left instanceof Set && right instanceof Set) {\n return areSetsEqual(left, right)\n }\n\n if (left instanceof Map && right instanceof Map) {\n return areMapsEqual(left, right)\n }\n\n if (Array.isArray(left) || Array.isArray(right)) {\n if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) return false\n\n return left.every((value, index) => isDeepEqual(value, right[index]))\n }\n\n if (!isPlainObject(left) || !isPlainObject(right)) return false\n\n const leftKeys = Object.keys(left)\n const rightKeys = Object.keys(right)\n\n if (leftKeys.length !== rightKeys.length) return false\n\n for (const key of leftKeys) {\n if (!hasOwn(right, key) || !isDeepEqual(left[key], right[key])) {\n return false\n }\n }\n\n return true\n}\n"],"mappings":";;;;;AAKA,SAAgB,SAAS,OAAiC;CACxD,OAAO,OAAO,SAAU,cAAY;AACtC;AAEA,MAAM,UAAU,OAAe,QAAqB,OAAO,UAAU,eAAe,KAAK,OAAO,GAAG,GAE7F,iBAAiB,UAAqD;CAC1E,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;CAE7B,IAAM,YAAY,OAAO,eAAe,KAAK;CAC7C,OAAO,cAAc,OAAO,aAAa,cAAc;AACzD;;;;;;AAOA,SAAgB,aACd,OACA,KACY;CACZ,IAAI,CAAC,OAAO,OAAO,CAAC;CAEpB,IAAM,GAAE,MAAM,UAAU,GAAG,SAAQ;CACnC,OAAO;AACT;;;;;;AAOA,SAAgB,eACd,OACA,MACY;CACZ,IAAM,SAAS,CAAC;CAEhB,KAAK,IAAM,OAAO,MAChB,AAAI,OAAO,OAAO,GAAG,MACnB,OAAO,OAAO,MAAM;CAIxB,OAAO;AACT;AAEA,MAAM,gBAAgB,MAAoB,UAAiC;CACzE,IAAI,KAAK,SAAS,MAAM,MAAM,OAAO;CAErC,IAAM,YAAY,CAAC,GAAG,KAAK;CAE3B,OAAO,KAAK,IAAM,aAAa,MAAM;EACnC,KAAK,IAAI,QAAQ,GAAG,QAAQ,UAAU,QAAQ,SAC5C,IAAI,YAAY,WAAW,UAAU,MAAM,GAAG;GAC5C,UAAU,OAAO,OAAO,CAAC;GACzB,SAAS;EACX;EAGF,OAAO;CACT;CAEA,OAAO,UAAU,WAAW;AAC9B,GAEM,gBAAgB,MAA6B,UAA0C;CAC3F,IAAI,KAAK,SAAS,MAAM,MAAM,OAAO;CAErC,IAAM,YAAY,CAAC,GAAG,MAAM,QAAQ,CAAC;CAErC,OAAO,KAAK,IAAM,CAAC,SAAS,cAAc,MAAM;EAC9C,KAAK,IAAI,QAAQ,GAAG,QAAQ,UAAU,QAAQ,SAAS;GACrD,IAAM,CAAC,UAAU,cAAc,UAAU;GAEzC,IAAI,YAAY,SAAS,QAAQ,KAAK,YAAY,WAAW,UAAU,GAAG;IACxE,UAAU,OAAO,OAAO,CAAC;IACzB,SAAS;GACX;EACF;EAEA,OAAO;CACT;CAEA,OAAO,UAAU,WAAW;AAC9B;;;;;;;;AASA,SAAgB,YAAe,MAAS,OAAmB;CACzD,IAAI,OAAO,GAAG,MAAM,KAAK,GAAG,OAAO;CAEnC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,KAAK,GAAG,OAAO;CAEhD,IAAI,gBAAgB,QAAQ,iBAAiB,MAC3C,OAAO,KAAK,QAAQ,MAAM,MAAM,QAAQ;CAG1C,IAAI,gBAAgB,UAAU,iBAAiB,QAC7C,OAAO,KAAK,WAAW,MAAM,UAAU,KAAK,UAAU,MAAM;CAG9D,IAAI,gBAAgB,OAAO,iBAAiB,KAC1C,OAAO,aAAa,MAAM,KAAK;CAGjC,IAAI,gBAAgB,OAAO,iBAAiB,KAC1C,OAAO,aAAa,MAAM,KAAK;CAGjC,IAAI,MAAM,QAAQ,IAAI,KAAK,MAAM,QAAQ,KAAK,GAG5C,OAFI,CAAC,MAAM,QAAQ,IAAI,KAAK,CAAC,MAAM,QAAQ,KAAK,KAAK,KAAK,WAAW,MAAM,SAAe,KAEnF,KAAK,OAAO,OAAO,UAAU,YAAY,OAAO,MAAM,MAAM,CAAC;CAGtE,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,KAAK,GAAG,OAAO;CAE1D,IAAM,WAAW,OAAO,KAAK,IAAI,GAC3B,YAAY,OAAO,KAAK,KAAK;CAEnC,IAAI,SAAS,WAAW,UAAU,QAAQ,OAAO;CAEjD,KAAK,IAAM,OAAO,UAChB,IAAI,CAAC,OAAO,OAAO,GAAG,KAAK,CAAC,YAAY,KAAK,MAAM,MAAM,IAAI,GAC3D,OAAO;CAIX,OAAO;AACT"}