@hexclave/react 1.0.29 → 1.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clickmap/clickmap-core.js +1 -1
- package/dist/clickmap/index.js +2 -2
- package/dist/components/api-key-dialogs.js +2 -2
- package/dist/components/credential-sign-in.js +1 -1
- package/dist/components/credential-sign-up.js +1 -1
- package/dist/components/magic-link-sign-in.js +1 -1
- package/dist/components/team-switcher.js +1 -1
- package/dist/components-page/account-settings/active-sessions/active-sessions-page.js +1 -1
- package/dist/components-page/account-settings/email-and-auth/emails-section.js +1 -1
- package/dist/components-page/account-settings/email-and-auth/mfa-section.js +1 -1
- package/dist/components-page/account-settings/email-and-auth/password-section.js +1 -1
- package/dist/components-page/account-settings/teams/team-api-keys-section.js +1 -1
- package/dist/components-page/account-settings/teams/team-creation-page.js +1 -1
- package/dist/components-page/account-settings/teams/team-member-invitation-section.js +1 -1
- package/dist/components-page/auth-page.js +1 -1
- package/dist/components-page/cli-auth-confirm.js +1 -1
- package/dist/components-page/cli-auth-confirm.test.js +1 -1
- package/dist/components-page/forgot-password.js +1 -1
- package/dist/components-page/oauth-callback.d.ts.map +1 -1
- package/dist/components-page/oauth-callback.js +3 -1
- package/dist/components-page/oauth-callback.js.map +1 -1
- package/dist/components-page/oauth-callback.test.js +3 -1
- package/dist/components-page/oauth-callback.test.js.map +1 -1
- package/dist/components-page/onboarding.js +1 -1
- package/dist/components-page/password-reset.js +1 -1
- package/dist/components-page/team-creation.js +1 -1
- package/dist/dev-tool/dev-tool-core.js +1 -1
- package/dist/dev-tool/index.js +1 -1
- package/dist/esm/clickmap/clickmap-core.js +1 -1
- package/dist/esm/clickmap/index.js +2 -2
- package/dist/esm/components/api-key-dialogs.js +2 -2
- package/dist/esm/components/credential-sign-in.js +1 -1
- package/dist/esm/components/credential-sign-up.js +1 -1
- package/dist/esm/components/magic-link-sign-in.js +1 -1
- package/dist/esm/components/team-switcher.js +1 -1
- package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js +1 -1
- package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js +1 -1
- package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js +1 -1
- package/dist/esm/components-page/account-settings/email-and-auth/password-section.js +1 -1
- package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js +1 -1
- package/dist/esm/components-page/account-settings/teams/team-creation-page.js +1 -1
- package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js +1 -1
- package/dist/esm/components-page/auth-page.js +1 -1
- package/dist/esm/components-page/cli-auth-confirm.js +1 -1
- package/dist/esm/components-page/cli-auth-confirm.test.js +1 -1
- package/dist/esm/components-page/forgot-password.js +1 -1
- package/dist/esm/components-page/oauth-callback.d.ts.map +1 -1
- package/dist/esm/components-page/oauth-callback.js +3 -1
- package/dist/esm/components-page/oauth-callback.js.map +1 -1
- package/dist/esm/components-page/oauth-callback.test.js +3 -1
- package/dist/esm/components-page/oauth-callback.test.js.map +1 -1
- package/dist/esm/components-page/onboarding.js +1 -1
- package/dist/esm/components-page/password-reset.js +1 -1
- package/dist/esm/components-page/team-creation.js +1 -1
- package/dist/esm/dev-tool/dev-tool-core.js +1 -1
- package/dist/esm/dev-tool/index.js +1 -1
- package/dist/esm/generated/quetzal-translations.d.ts +2 -2
- package/dist/esm/lib/auth.js +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +2 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +6 -10
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.js +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +14 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js +31 -16
- package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.js +9 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -0
- package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/interfaces/server-app.d.ts +13 -0
- package/dist/esm/lib/hexclave-app/apps/interfaces/server-app.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/interfaces/server-app.js.map +1 -1
- package/dist/esm/lib/hexclave-app/teams/index.d.ts +4 -0
- package/dist/esm/lib/hexclave-app/teams/index.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/teams/index.js.map +1 -1
- package/dist/esm/providers/theme-provider.js +1 -1
- package/dist/esm/pushed-config-error-overlay/index.js +1 -1
- package/dist/generated/quetzal-translations.d.ts +2 -2
- package/dist/lib/auth.js +1 -1
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -0
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +6 -10
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
- package/dist/lib/hexclave-app/apps/implementations/event-tracker.js +1 -1
- package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +14 -0
- package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js +31 -16
- package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/session-replay.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/session-replay.js +9 -2
- package/dist/lib/hexclave-app/apps/implementations/session-replay.js.map +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -0
- package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +13 -0
- package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/server-app.js.map +1 -1
- package/dist/lib/hexclave-app/teams/index.d.ts +4 -0
- package/dist/lib/hexclave-app/teams/index.d.ts.map +1 -1
- package/dist/lib/hexclave-app/teams/index.js.map +1 -1
- package/dist/providers/theme-provider.js +1 -1
- package/dist/pushed-config-error-overlay/index.js +1 -1
- package/package.json +3 -3
- package/src/components-page/oauth-callback.test.tsx +4 -0
- package/src/components-page/oauth-callback.tsx +6 -0
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +3 -5
- package/src/lib/hexclave-app/apps/implementations/server-app-impl.ts +35 -19
- package/src/lib/hexclave-app/apps/implementations/session-replay.ts +16 -1
- package/src/lib/hexclave-app/apps/interfaces/client-app.ts +1 -0
- package/src/lib/hexclave-app/apps/interfaces/server-app.ts +5 -0
- package/src/lib/hexclave-app/teams/index.ts +4 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_chunk = require('../../../../chunk-BE-pF4vm.js');
|
|
3
|
-
let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
|
|
4
3
|
let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
|
|
4
|
+
let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
|
|
5
5
|
let _hexclave_shared_dist_utils_results = require("@hexclave/shared/dist/utils/results");
|
|
6
6
|
let _hexclave_shared_dist_utils_env = require("@hexclave/shared/dist/utils/env");
|
|
7
7
|
let _hexclave_shared_dist_known_errors = require("@hexclave/shared/dist/known-errors");
|
|
@@ -60,6 +60,7 @@ const FLUSH_INTERVAL_MS = 5e3;
|
|
|
60
60
|
const MAX_EVENTS_PER_BATCH = 200;
|
|
61
61
|
const MAX_APPROX_BYTES_PER_BATCH = 512e3;
|
|
62
62
|
const MAX_FLUSH_PAYLOAD_BYTES = 9e5;
|
|
63
|
+
const textEncoder = new TextEncoder();
|
|
63
64
|
function safeParseStoredSession(raw) {
|
|
64
65
|
if (!raw) return null;
|
|
65
66
|
try {
|
|
@@ -186,6 +187,12 @@ var SessionRecorder = class {
|
|
|
186
187
|
try {
|
|
187
188
|
let offset = 0;
|
|
188
189
|
while (offset < allEvents.length) {
|
|
190
|
+
const firstSize = allSizes[offset] ?? (0, _hexclave_shared_dist_utils_errors.throwErr)("_eventSizes out of sync with _events — this should never happen");
|
|
191
|
+
if (firstSize > MAX_FLUSH_PAYLOAD_BYTES) {
|
|
192
|
+
(0, _hexclave_shared_dist_utils_errors.captureWarning)("SessionRecorder.flush", /* @__PURE__ */ new Error(`Dropping oversized session replay event (${firstSize} bytes > ${MAX_FLUSH_PAYLOAD_BYTES} byte limit); it cannot be sent without a 413.`));
|
|
193
|
+
offset += 1;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
189
196
|
let batchBytes = 0;
|
|
190
197
|
let batchEnd = offset;
|
|
191
198
|
for (let i = offset; i < allEvents.length; i++) {
|
|
@@ -258,7 +265,7 @@ var SessionRecorder = class {
|
|
|
258
265
|
this._takingSnapshot = false;
|
|
259
266
|
}
|
|
260
267
|
}
|
|
261
|
-
const eventSize = JSON.stringify(event).
|
|
268
|
+
const eventSize = textEncoder.encode(JSON.stringify(event)).byteLength;
|
|
262
269
|
this._events.push(event);
|
|
263
270
|
this._eventSizes.push(eventSize);
|
|
264
271
|
this._approxBytes += eventSize;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-replay.js","names":["KnownErrors","Result"],"sources":["../../../../../src/lib/hexclave-app/apps/implementations/session-replay.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownErrors } from \"@hexclave/shared/dist/known-errors\";\nimport { isBrowserLike } from \"@hexclave/shared/dist/utils/env\";\nimport { captureWarning, throwErr } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\n\nexport type AnalyticsReplayOptions = {\n /**\n * Whether session replays are enabled.\n *\n * @default true\n */\n enabled?: boolean,\n /**\n * Whether to mask the content of all `<input>` elements.\n *\n * @default true\n */\n maskAllInputs?: boolean,\n /**\n * A CSS class name or RegExp. Elements with a matching class will be blocked\n * (replaced with a placeholder in the recording).\n *\n * @default undefined\n */\n blockClass?: string | RegExp,\n /**\n * A CSS selector string. Elements matching this selector will be blocked\n * (replaced with a placeholder in the recording).\n *\n * @default undefined\n */\n blockSelector?: string,\n};\n\nexport type AnalyticsOptions = {\n /**\n * Whether SDK-managed analytics capture is enabled.\n *\n * @default true\n */\n enabled?: boolean,\n /**\n * Options for session replay recording. Replays are enabled by default;\n * set `enabled: false` to opt out.\n */\n replays?: AnalyticsReplayOptions,\n};\n\nexport function getSessionReplayOptions(analyticsOptions: AnalyticsOptions | undefined): AnalyticsReplayOptions {\n return {\n ...analyticsOptions?.replays,\n enabled: analyticsOptions?.replays?.enabled ?? true,\n };\n}\n\n/**\n * Converts AnalyticsOptions to a JSON-safe representation.\n * RegExp blockClass values are serialized as `{ __regexp, __flags }` objects.\n * The return type is AnalyticsOptions to keep StackClientAppJson simple;\n * the actual runtime value is JSON-safe.\n */\nexport function analyticsOptionsToJson(options: AnalyticsOptions | undefined): AnalyticsOptions | undefined {\n if (!options?.replays?.blockClass) return options;\n const { blockClass, ...rest } = options.replays;\n if (!(blockClass instanceof RegExp)) return options;\n return {\n ...options,\n replays: {\n ...rest,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n blockClass: { __regexp: blockClass.source, __flags: blockClass.flags } as any,\n },\n };\n}\n\n/**\n * Reconstructs AnalyticsOptions from a JSON-deserialized value.\n * Converts `{ __regexp, __flags }` objects back to RegExp instances.\n */\nexport function analyticsOptionsFromJson(json: AnalyticsOptions | undefined): AnalyticsOptions | undefined {\n if (!json?.replays?.blockClass) return json;\n const { blockClass, ...rest } = json.replays;\n if (typeof blockClass === 'object' && '__regexp' in blockClass) {\n const bc = blockClass as unknown as { __regexp: string, __flags: string };\n return {\n ...json,\n replays: {\n ...rest,\n blockClass: new RegExp(bc.__regexp, bc.__flags),\n },\n };\n }\n return json;\n}\n\n// ---------- Recording internals ----------\n\n// Hexclave rebrand: canonical localStorage prefix (colon delimiters preserved).\nconst LOCAL_STORAGE_PREFIX = \"hexclave:session-replay:v1\";\n// Hexclave rebrand: legacy prefix — dual-read only, so a recording session active\n// across an SDK upgrade is not orphaned. Never written.\nconst LEGACY_LOCAL_STORAGE_PREFIX = \"stack:session-replay:v1\";\nconst IDLE_TTL_MS = 3 * 60 * 1000;\n\nconst FLUSH_INTERVAL_MS = 5_000;\nconst MAX_EVENTS_PER_BATCH = 200;\nconst MAX_APPROX_BYTES_PER_BATCH = 512_000;\n// The server rejects payloads > 1MB. Stay well under to account for JSON\n// envelope overhead (browser_session_id, timestamps, wrapper keys, etc.).\nconst MAX_FLUSH_PAYLOAD_BYTES = 900_000;\n\nexport type StoredSession = {\n session_id: string,\n created_at_ms: number,\n last_activity_ms: number,\n};\n\nexport function safeParseStoredSession(raw: string | null): StoredSession | null {\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw);\n if (typeof parsed !== \"object\" || parsed === null) return null;\n if (typeof parsed.session_id !== \"string\") return null;\n if (typeof parsed.created_at_ms !== \"number\") return null;\n if (typeof parsed.last_activity_ms !== \"number\") return null;\n return parsed as StoredSession;\n } catch {\n return null;\n }\n}\n\nexport function makeStorageKey(projectId: string) {\n return `${LOCAL_STORAGE_PREFIX}:${projectId}`;\n}\n\n// Hexclave rebrand: legacy key, dual-read only (never written).\nexport function makeLegacyStorageKey(projectId: string) {\n return `${LEGACY_LOCAL_STORAGE_PREFIX}:${projectId}`;\n}\n\nexport function generateUuid() {\n return crypto.randomUUID();\n}\n\nexport function getOrRotateSession(options: { key: string, legacyKey?: string, nowMs: number }): StoredSession {\n // Hexclave rebrand: prefer the new key; fall back to the legacy key so a\n // recording session active across an SDK upgrade is not orphaned.\n const existing = safeParseStoredSession(localStorage.getItem(options.key))\n ?? (options.legacyKey ? safeParseStoredSession(localStorage.getItem(options.legacyKey)) : null);\n if (existing && options.nowMs - existing.last_activity_ms <= IDLE_TTL_MS) {\n return existing;\n }\n const next: StoredSession = {\n session_id: generateUuid(),\n created_at_ms: options.nowMs,\n last_activity_ms: options.nowMs,\n };\n localStorage.setItem(options.key, JSON.stringify(next));\n return next;\n}\n\nexport type SessionRecorderDeps = {\n projectId: string,\n sendBatch: (body: string, options: { keepalive: boolean }) => Promise<Result<Response, Error>>,\n};\n\nexport function isAnalyticsNotEnabledError(error: unknown): boolean {\n return KnownErrors.AnalyticsNotEnabled.isInstance(error);\n}\n\n/**\n * Whether the error looks like a network failure caused by an ad blocker or\n * similar extension blocking analytics requests. These are expected in\n * production and should be silently ignored rather than logged as warnings.\n */\nexport function isAdBlockerNetworkError(error: unknown): boolean {\n if (error instanceof Error) {\n return error.message.includes(\"Failed to fetch\")\n || error.message.includes(\"NetworkError\")\n || error.message.includes(\"Load failed\")\n || error.message.includes(\"network connection\");\n }\n return false;\n}\n\nexport class SessionRecorder {\n private _started = false;\n private _cancelled = false;\n private _disabled = false;\n private _stopRecording: (() => void) | null = null;\n private _detachListeners: (() => void) | null = null;\n private _flushTimer: ReturnType<typeof setInterval> | null = null;\n private _events: unknown[] = [];\n private _eventSizes: number[] = [];\n private _approxBytes = 0;\n private _lastPersistActivity = 0;\n private _recording = false;\n private _rrwebModule: typeof import(\"rrweb\") | null = null;\n private _lastBrowserSessionId: string | null = null;\n private _takingSnapshot = false;\n private _flushInProgress = false;\n private readonly _sessionReplaySegmentId: string;\n private readonly _storageKey: string;\n // Hexclave rebrand: legacy key used for dual-read fallback only.\n private readonly _legacyStorageKey: string;\n private readonly _deps: SessionRecorderDeps;\n private readonly _replayOptions: AnalyticsReplayOptions;\n\n constructor(deps: SessionRecorderDeps, replayOptions: AnalyticsReplayOptions) {\n this._deps = deps;\n this._replayOptions = replayOptions;\n this._sessionReplaySegmentId = generateUuid();\n this._storageKey = makeStorageKey(deps.projectId);\n this._legacyStorageKey = makeLegacyStorageKey(deps.projectId);\n }\n\n /**\n * Starts recording. Idempotent — calling multiple times is safe.\n */\n start() {\n if (this._started) return;\n if (!isBrowserLike()) return;\n this._started = true;\n\n // Kick off rrweb recording\n runAsynchronously(() => this._startRecording(), { noErrorLogging: true });\n\n // Periodic flush\n this._flushTimer = setInterval(() => this._tick(), FLUSH_INTERVAL_MS);\n }\n\n stop() {\n this._cancelled = true;\n if (this._flushTimer !== null) {\n clearInterval(this._flushTimer);\n this._flushTimer = null;\n }\n // Flush remaining events before cleanup\n runAsynchronously(() => this._flush({ keepalive: true }));\n this._stopCurrentRecording();\n }\n\n clearBuffer() {\n this._events = [];\n this._eventSizes = [];\n this._approxBytes = 0;\n }\n\n private _persistActivity(nowMs: number): StoredSession {\n const stored = getOrRotateSession({ key: this._storageKey, legacyKey: this._legacyStorageKey, nowMs });\n if (nowMs - this._lastPersistActivity < 5_000) return stored;\n this._lastPersistActivity = nowMs;\n const updated: StoredSession = { ...stored, last_activity_ms: nowMs };\n localStorage.setItem(this._storageKey, JSON.stringify(updated));\n return stored;\n }\n\n private async _flush(options: { keepalive: boolean }) {\n if (this._disabled) return;\n if (this._events.length === 0) return;\n // Prevent concurrent in-flight HTTP requests. When a flush is already\n // in-flight, a second batch could race on the server (both call\n // findRecentSessionReplay before either upsert commits) and create\n // duplicate SessionReplay records. Events stay in _events and will be\n // picked up by the next tick or batch-size check.\n if (this._flushInProgress) return;\n\n const nowMs = Date.now();\n const stored = getOrRotateSession({ key: this._storageKey, legacyKey: this._legacyStorageKey, nowMs });\n\n // Capture all buffered events upfront (before any await) so that\n // stop() / _stopCurrentRecording() clearing this._events cannot race\n // with the async send loop below and silently discard overflow batches.\n const allEvents = this._events;\n const allSizes = this._eventSizes;\n this._events = [];\n this._eventSizes = [];\n this._approxBytes = 0;\n\n this._flushInProgress = true;\n try {\n let offset = 0;\n while (offset < allEvents.length) {\n // Build a batch that fits under the server's payload limit.\n // When _flushInProgress blocked earlier flushes, events can accumulate\n // well past MAX_APPROX_BYTES_PER_BATCH; sending them all at once would\n // exceed the server's 1MB body limit (413).\n let batchBytes = 0;\n let batchEnd = offset;\n for (let i = offset; i < allEvents.length; i++) {\n const nextSize = allSizes[i] ?? throwErr(\"_eventSizes out of sync with _events — this should never happen\");\n if (batchBytes + nextSize > MAX_FLUSH_PAYLOAD_BYTES && batchEnd > offset) break;\n batchBytes += nextSize;\n batchEnd = i + 1;\n }\n\n const batchEvents = allEvents.slice(offset, batchEnd);\n offset = batchEnd;\n\n const batchId = generateUuid();\n const payload = {\n browser_session_id: stored.session_id,\n session_replay_segment_id: this._sessionReplaySegmentId,\n batch_id: batchId,\n started_at_ms: stored.created_at_ms,\n sent_at_ms: nowMs,\n events: batchEvents,\n };\n\n const res = await this._deps.sendBatch(\n JSON.stringify(payload),\n { keepalive: options.keepalive },\n );\n\n if (res.status === \"error\") {\n if (isAnalyticsNotEnabledError(res.error)) {\n this._disable();\n return;\n }\n // Ad blockers commonly block analytics endpoints, causing network\n // errors. These are expected and should not pollute the console.\n if (isAdBlockerNetworkError(res.error)) {\n return;\n }\n captureWarning(\"SessionRecorder.flush\", res.error);\n return;\n }\n\n if (!res.data.ok) {\n captureWarning(\"SessionRecorder.flush\", new Error(`SessionRecorder flush failed: ${res.data.status} ${await res.data.text()}`));\n return;\n }\n }\n } finally {\n this._flushInProgress = false;\n }\n }\n\n private _disable() {\n this._disabled = true;\n this.clearBuffer();\n if (this._flushTimer !== null) {\n clearInterval(this._flushTimer);\n this._flushTimer = null;\n }\n this._stopCurrentRecording();\n }\n\n private async _startRecording() {\n if (this._recording || this._cancelled) return;\n\n if (!this._rrwebModule) {\n const rrwebImport = await Result.fromPromise(import(\"rrweb\"));\n if (rrwebImport.status === \"error\") {\n console.warn(\"SessionRecorder: rrweb import failed. Is rrweb installed?\", rrwebImport.error);\n return;\n }\n this._rrwebModule = rrwebImport.data;\n }\n\n // cancelled may change during the await above\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this._cancelled) return;\n\n this._stopRecording = this._rrwebModule.record({\n emit: (event) => {\n const nowMs = Date.now();\n const stored = this._persistActivity(nowMs);\n\n // Detect session rotation: after 3+ minutes idle, getOrRotateSession\n // creates a new session ID. We need to inject a FullSnapshot so the\n // new server-side SessionReplay record is playable.\n if (this._lastBrowserSessionId === null) {\n this._lastBrowserSessionId = stored.session_id;\n } else if (stored.session_id !== this._lastBrowserSessionId && !this._takingSnapshot) {\n this._lastBrowserSessionId = stored.session_id;\n // Inject a FullSnapshot for the new session (calls emit synchronously)\n this._takingSnapshot = true;\n try {\n this._rrwebModule!.record.takeFullSnapshot();\n } finally {\n this._takingSnapshot = false;\n }\n }\n\n const eventSize = JSON.stringify(event).length;\n this._events.push(event);\n this._eventSizes.push(eventSize);\n this._approxBytes += eventSize;\n if (this._events.length >= MAX_EVENTS_PER_BATCH || this._approxBytes >= MAX_APPROX_BYTES_PER_BATCH) {\n runAsynchronously(() => this._flush({ keepalive: false }));\n }\n },\n maskAllInputs: this._replayOptions.maskAllInputs ?? true,\n ...(this._replayOptions.blockClass !== undefined ? { blockClass: this._replayOptions.blockClass } : {}),\n ...(this._replayOptions.blockSelector !== undefined ? { blockSelector: this._replayOptions.blockSelector } : {}),\n }) ?? null;\n\n this._recording = true;\n\n const onPageHide = () => {\n runAsynchronously(() => this._flush({ keepalive: true }));\n };\n window.addEventListener(\"pagehide\", onPageHide);\n document.addEventListener(\"visibilitychange\", onPageHide);\n this._detachListeners = () => {\n window.removeEventListener(\"pagehide\", onPageHide);\n document.removeEventListener(\"visibilitychange\", onPageHide);\n };\n }\n\n private _stopCurrentRecording() {\n if (this._detachListeners) {\n this._detachListeners();\n this._detachListeners = null;\n }\n if (this._stopRecording) {\n this._stopRecording();\n this._stopRecording = null;\n }\n this._events = [];\n this._eventSizes = [];\n this._approxBytes = 0;\n this._recording = false;\n }\n\n private _tick() {\n if (this._cancelled) return;\n if (this._events.length > 0) {\n runAsynchronously(() => this._flush({ keepalive: false }));\n }\n }\n}\n"],"mappings":";;;;;;;;;AAqDA,SAAgB,wBAAwB,kBAAwE;AAC9G,QAAO;EACL,GAAG,kBAAkB;EACrB,SAAS,kBAAkB,SAAS,WAAW;EAChD;;;;;;;;AASH,SAAgB,uBAAuB,SAAqE;AAC1G,KAAI,CAAC,SAAS,SAAS,WAAY,QAAO;CAC1C,MAAM,EAAE,YAAY,GAAG,SAAS,QAAQ;AACxC,KAAI,EAAE,sBAAsB,QAAS,QAAO;AAC5C,QAAO;EACL,GAAG;EACH,SAAS;GACP,GAAG;GAEH,YAAY;IAAE,UAAU,WAAW;IAAQ,SAAS,WAAW;IAAO;GACvE;EACF;;;;;;AAOH,SAAgB,yBAAyB,MAAkE;AACzG,KAAI,CAAC,MAAM,SAAS,WAAY,QAAO;CACvC,MAAM,EAAE,YAAY,GAAG,SAAS,KAAK;AACrC,KAAI,OAAO,eAAe,YAAY,cAAc,YAAY;EAC9D,MAAM,KAAK;AACX,SAAO;GACL,GAAG;GACH,SAAS;IACP,GAAG;IACH,YAAY,IAAI,OAAO,GAAG,UAAU,GAAG,QAAQ;IAChD;GACF;;AAEH,QAAO;;AAMT,MAAM,uBAAuB;AAG7B,MAAM,8BAA8B;AACpC,MAAM,cAAc,MAAS;AAE7B,MAAM,oBAAoB;AAC1B,MAAM,uBAAuB;AAC7B,MAAM,6BAA6B;AAGnC,MAAM,0BAA0B;AAQhC,SAAgB,uBAAuB,KAA0C;AAC/E,KAAI,CAAC,IAAK,QAAO;AACjB,KAAI;EACF,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,MAAI,OAAO,WAAW,YAAY,WAAW,KAAM,QAAO;AAC1D,MAAI,OAAO,OAAO,eAAe,SAAU,QAAO;AAClD,MAAI,OAAO,OAAO,kBAAkB,SAAU,QAAO;AACrD,MAAI,OAAO,OAAO,qBAAqB,SAAU,QAAO;AACxD,SAAO;SACD;AACN,SAAO;;;AAIX,SAAgB,eAAe,WAAmB;AAChD,QAAO,GAAG,qBAAqB,GAAG;;AAIpC,SAAgB,qBAAqB,WAAmB;AACtD,QAAO,GAAG,4BAA4B,GAAG;;AAG3C,SAAgB,eAAe;AAC7B,QAAO,OAAO,YAAY;;AAG5B,SAAgB,mBAAmB,SAA4E;CAG7G,MAAM,WAAW,uBAAuB,aAAa,QAAQ,QAAQ,IAAI,CAAC,KACpE,QAAQ,YAAY,uBAAuB,aAAa,QAAQ,QAAQ,UAAU,CAAC,GAAG;AAC5F,KAAI,YAAY,QAAQ,QAAQ,SAAS,oBAAoB,YAC3D,QAAO;CAET,MAAM,OAAsB;EAC1B,YAAY,cAAc;EAC1B,eAAe,QAAQ;EACvB,kBAAkB,QAAQ;EAC3B;AACD,cAAa,QAAQ,QAAQ,KAAK,KAAK,UAAU,KAAK,CAAC;AACvD,QAAO;;AAQT,SAAgB,2BAA2B,OAAyB;AAClE,QAAOA,+CAAY,oBAAoB,WAAW,MAAM;;;;;;;AAQ1D,SAAgB,wBAAwB,OAAyB;AAC/D,KAAI,iBAAiB,MACnB,QAAO,MAAM,QAAQ,SAAS,kBAAkB,IAC3C,MAAM,QAAQ,SAAS,eAAe,IACtC,MAAM,QAAQ,SAAS,cAAc,IACrC,MAAM,QAAQ,SAAS,qBAAqB;AAEnD,QAAO;;AAGT,IAAa,kBAAb,MAA6B;CAuB3B,YAAY,MAA2B,eAAuC;kBAtB3D;oBACE;mBACD;wBAC0B;0BACE;qBACa;iBAChC,EAAE;qBACC,EAAE;sBACX;8BACQ;oBACV;sBACiC;+BACP;yBACrB;0BACC;AASzB,OAAK,QAAQ;AACb,OAAK,iBAAiB;AACtB,OAAK,0BAA0B,cAAc;AAC7C,OAAK,cAAc,eAAe,KAAK,UAAU;AACjD,OAAK,oBAAoB,qBAAqB,KAAK,UAAU;;;;;CAM/D,QAAQ;AACN,MAAI,KAAK,SAAU;AACnB,MAAI,qDAAgB,CAAE;AACtB,OAAK,WAAW;AAGhB,oEAAwB,KAAK,iBAAiB,EAAE,EAAE,gBAAgB,MAAM,CAAC;AAGzE,OAAK,cAAc,kBAAkB,KAAK,OAAO,EAAE,kBAAkB;;CAGvE,OAAO;AACL,OAAK,aAAa;AAClB,MAAI,KAAK,gBAAgB,MAAM;AAC7B,iBAAc,KAAK,YAAY;AAC/B,QAAK,cAAc;;AAGrB,oEAAwB,KAAK,OAAO,EAAE,WAAW,MAAM,CAAC,CAAC;AACzD,OAAK,uBAAuB;;CAG9B,cAAc;AACZ,OAAK,UAAU,EAAE;AACjB,OAAK,cAAc,EAAE;AACrB,OAAK,eAAe;;CAGtB,AAAQ,iBAAiB,OAA8B;EACrD,MAAM,SAAS,mBAAmB;GAAE,KAAK,KAAK;GAAa,WAAW,KAAK;GAAmB;GAAO,CAAC;AACtG,MAAI,QAAQ,KAAK,uBAAuB,IAAO,QAAO;AACtD,OAAK,uBAAuB;EAC5B,MAAM,UAAyB;GAAE,GAAG;GAAQ,kBAAkB;GAAO;AACrE,eAAa,QAAQ,KAAK,aAAa,KAAK,UAAU,QAAQ,CAAC;AAC/D,SAAO;;CAGT,MAAc,OAAO,SAAiC;AACpD,MAAI,KAAK,UAAW;AACpB,MAAI,KAAK,QAAQ,WAAW,EAAG;AAM/B,MAAI,KAAK,iBAAkB;EAE3B,MAAM,QAAQ,KAAK,KAAK;EACxB,MAAM,SAAS,mBAAmB;GAAE,KAAK,KAAK;GAAa,WAAW,KAAK;GAAmB;GAAO,CAAC;EAKtG,MAAM,YAAY,KAAK;EACvB,MAAM,WAAW,KAAK;AACtB,OAAK,UAAU,EAAE;AACjB,OAAK,cAAc,EAAE;AACrB,OAAK,eAAe;AAEpB,OAAK,mBAAmB;AACxB,MAAI;GACF,IAAI,SAAS;AACb,UAAO,SAAS,UAAU,QAAQ;IAKhC,IAAI,aAAa;IACjB,IAAI,WAAW;AACf,SAAK,IAAI,IAAI,QAAQ,IAAI,UAAU,QAAQ,KAAK;KAC9C,MAAM,WAAW,SAAS,uDAAe,kEAAkE;AAC3G,SAAI,aAAa,WAAW,2BAA2B,WAAW,OAAQ;AAC1E,mBAAc;AACd,gBAAW,IAAI;;IAGjB,MAAM,cAAc,UAAU,MAAM,QAAQ,SAAS;AACrD,aAAS;IAET,MAAM,UAAU,cAAc;IAC9B,MAAM,UAAU;KACd,oBAAoB,OAAO;KAC3B,2BAA2B,KAAK;KAChC,UAAU;KACV,eAAe,OAAO;KACtB,YAAY;KACZ,QAAQ;KACT;IAED,MAAM,MAAM,MAAM,KAAK,MAAM,UAC3B,KAAK,UAAU,QAAQ,EACvB,EAAE,WAAW,QAAQ,WAAW,CACjC;AAED,QAAI,IAAI,WAAW,SAAS;AAC1B,SAAI,2BAA2B,IAAI,MAAM,EAAE;AACzC,WAAK,UAAU;AACf;;AAIF,SAAI,wBAAwB,IAAI,MAAM,CACpC;AAEF,4DAAe,yBAAyB,IAAI,MAAM;AAClD;;AAGF,QAAI,CAAC,IAAI,KAAK,IAAI;AAChB,4DAAe,yCAAyB,IAAI,MAAM,iCAAiC,IAAI,KAAK,OAAO,GAAG,MAAM,IAAI,KAAK,MAAM,GAAG,CAAC;AAC/H;;;YAGI;AACR,QAAK,mBAAmB;;;CAI5B,AAAQ,WAAW;AACjB,OAAK,YAAY;AACjB,OAAK,aAAa;AAClB,MAAI,KAAK,gBAAgB,MAAM;AAC7B,iBAAc,KAAK,YAAY;AAC/B,QAAK,cAAc;;AAErB,OAAK,uBAAuB;;CAG9B,MAAc,kBAAkB;AAC9B,MAAI,KAAK,cAAc,KAAK,WAAY;AAExC,MAAI,CAAC,KAAK,cAAc;GACtB,MAAM,cAAc,MAAMC,2CAAO,YAAY,OAAO,SAAS;AAC7D,OAAI,YAAY,WAAW,SAAS;AAClC,YAAQ,KAAK,6DAA6D,YAAY,MAAM;AAC5F;;AAEF,QAAK,eAAe,YAAY;;AAKlC,MAAI,KAAK,WAAY;AAErB,OAAK,iBAAiB,KAAK,aAAa,OAAO;GAC7C,OAAO,UAAU;IACf,MAAM,QAAQ,KAAK,KAAK;IACxB,MAAM,SAAS,KAAK,iBAAiB,MAAM;AAK3C,QAAI,KAAK,0BAA0B,KACjC,MAAK,wBAAwB,OAAO;aAC3B,OAAO,eAAe,KAAK,yBAAyB,CAAC,KAAK,iBAAiB;AACpF,UAAK,wBAAwB,OAAO;AAEpC,UAAK,kBAAkB;AACvB,SAAI;AACF,WAAK,aAAc,OAAO,kBAAkB;eACpC;AACR,WAAK,kBAAkB;;;IAI3B,MAAM,YAAY,KAAK,UAAU,MAAM,CAAC;AACxC,SAAK,QAAQ,KAAK,MAAM;AACxB,SAAK,YAAY,KAAK,UAAU;AAChC,SAAK,gBAAgB;AACrB,QAAI,KAAK,QAAQ,UAAU,wBAAwB,KAAK,gBAAgB,2BACtE,mEAAwB,KAAK,OAAO,EAAE,WAAW,OAAO,CAAC,CAAC;;GAG9D,eAAe,KAAK,eAAe,iBAAiB;GACpD,GAAI,KAAK,eAAe,eAAe,SAAY,EAAE,YAAY,KAAK,eAAe,YAAY,GAAG,EAAE;GACtG,GAAI,KAAK,eAAe,kBAAkB,SAAY,EAAE,eAAe,KAAK,eAAe,eAAe,GAAG,EAAE;GAChH,CAAC,IAAI;AAEN,OAAK,aAAa;EAElB,MAAM,mBAAmB;AACvB,qEAAwB,KAAK,OAAO,EAAE,WAAW,MAAM,CAAC,CAAC;;AAE3D,SAAO,iBAAiB,YAAY,WAAW;AAC/C,WAAS,iBAAiB,oBAAoB,WAAW;AACzD,OAAK,yBAAyB;AAC5B,UAAO,oBAAoB,YAAY,WAAW;AAClD,YAAS,oBAAoB,oBAAoB,WAAW;;;CAIhE,AAAQ,wBAAwB;AAC9B,MAAI,KAAK,kBAAkB;AACzB,QAAK,kBAAkB;AACvB,QAAK,mBAAmB;;AAE1B,MAAI,KAAK,gBAAgB;AACvB,QAAK,gBAAgB;AACrB,QAAK,iBAAiB;;AAExB,OAAK,UAAU,EAAE;AACjB,OAAK,cAAc,EAAE;AACrB,OAAK,eAAe;AACpB,OAAK,aAAa;;CAGpB,AAAQ,QAAQ;AACd,MAAI,KAAK,WAAY;AACrB,MAAI,KAAK,QAAQ,SAAS,EACxB,mEAAwB,KAAK,OAAO,EAAE,WAAW,OAAO,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"session-replay.js","names":["KnownErrors","Result"],"sources":["../../../../../src/lib/hexclave-app/apps/implementations/session-replay.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownErrors } from \"@hexclave/shared/dist/known-errors\";\nimport { isBrowserLike } from \"@hexclave/shared/dist/utils/env\";\nimport { captureWarning, throwErr } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\n\nexport type AnalyticsReplayOptions = {\n /**\n * Whether session replays are enabled.\n *\n * @default true\n */\n enabled?: boolean,\n /**\n * Whether to mask the content of all `<input>` elements.\n *\n * @default true\n */\n maskAllInputs?: boolean,\n /**\n * A CSS class name or RegExp. Elements with a matching class will be blocked\n * (replaced with a placeholder in the recording).\n *\n * @default undefined\n */\n blockClass?: string | RegExp,\n /**\n * A CSS selector string. Elements matching this selector will be blocked\n * (replaced with a placeholder in the recording).\n *\n * @default undefined\n */\n blockSelector?: string,\n};\n\nexport type AnalyticsOptions = {\n /**\n * Whether SDK-managed analytics capture is enabled.\n *\n * @default true\n */\n enabled?: boolean,\n /**\n * Options for session replay recording. Replays are enabled by default;\n * set `enabled: false` to opt out.\n */\n replays?: AnalyticsReplayOptions,\n};\n\nexport function getSessionReplayOptions(analyticsOptions: AnalyticsOptions | undefined): AnalyticsReplayOptions {\n return {\n ...analyticsOptions?.replays,\n enabled: analyticsOptions?.replays?.enabled ?? true,\n };\n}\n\n/**\n * Converts AnalyticsOptions to a JSON-safe representation.\n * RegExp blockClass values are serialized as `{ __regexp, __flags }` objects.\n * The return type is AnalyticsOptions to keep StackClientAppJson simple;\n * the actual runtime value is JSON-safe.\n */\nexport function analyticsOptionsToJson(options: AnalyticsOptions | undefined): AnalyticsOptions | undefined {\n if (!options?.replays?.blockClass) return options;\n const { blockClass, ...rest } = options.replays;\n if (!(blockClass instanceof RegExp)) return options;\n return {\n ...options,\n replays: {\n ...rest,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n blockClass: { __regexp: blockClass.source, __flags: blockClass.flags } as any,\n },\n };\n}\n\n/**\n * Reconstructs AnalyticsOptions from a JSON-deserialized value.\n * Converts `{ __regexp, __flags }` objects back to RegExp instances.\n */\nexport function analyticsOptionsFromJson(json: AnalyticsOptions | undefined): AnalyticsOptions | undefined {\n if (!json?.replays?.blockClass) return json;\n const { blockClass, ...rest } = json.replays;\n if (typeof blockClass === 'object' && '__regexp' in blockClass) {\n const bc = blockClass as unknown as { __regexp: string, __flags: string };\n return {\n ...json,\n replays: {\n ...rest,\n blockClass: new RegExp(bc.__regexp, bc.__flags),\n },\n };\n }\n return json;\n}\n\n// ---------- Recording internals ----------\n\n// Hexclave rebrand: canonical localStorage prefix (colon delimiters preserved).\nconst LOCAL_STORAGE_PREFIX = \"hexclave:session-replay:v1\";\n// Hexclave rebrand: legacy prefix — dual-read only, so a recording session active\n// across an SDK upgrade is not orphaned. Never written.\nconst LEGACY_LOCAL_STORAGE_PREFIX = \"stack:session-replay:v1\";\nconst IDLE_TTL_MS = 3 * 60 * 1000;\n\nconst FLUSH_INTERVAL_MS = 5_000;\nconst MAX_EVENTS_PER_BATCH = 200;\nconst MAX_APPROX_BYTES_PER_BATCH = 512_000;\n// The server rejects payloads > 1MB. Stay well under to account for JSON\n// envelope overhead (browser_session_id, timestamps, wrapper keys, etc.).\nconst MAX_FLUSH_PAYLOAD_BYTES = 900_000;\n\n// Reused across the emit hot path to avoid per-event allocation.\nconst textEncoder = new TextEncoder();\n\nexport type StoredSession = {\n session_id: string,\n created_at_ms: number,\n last_activity_ms: number,\n};\n\nexport function safeParseStoredSession(raw: string | null): StoredSession | null {\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw);\n if (typeof parsed !== \"object\" || parsed === null) return null;\n if (typeof parsed.session_id !== \"string\") return null;\n if (typeof parsed.created_at_ms !== \"number\") return null;\n if (typeof parsed.last_activity_ms !== \"number\") return null;\n return parsed as StoredSession;\n } catch {\n return null;\n }\n}\n\nexport function makeStorageKey(projectId: string) {\n return `${LOCAL_STORAGE_PREFIX}:${projectId}`;\n}\n\n// Hexclave rebrand: legacy key, dual-read only (never written).\nexport function makeLegacyStorageKey(projectId: string) {\n return `${LEGACY_LOCAL_STORAGE_PREFIX}:${projectId}`;\n}\n\nexport function generateUuid() {\n return crypto.randomUUID();\n}\n\nexport function getOrRotateSession(options: { key: string, legacyKey?: string, nowMs: number }): StoredSession {\n // Hexclave rebrand: prefer the new key; fall back to the legacy key so a\n // recording session active across an SDK upgrade is not orphaned.\n const existing = safeParseStoredSession(localStorage.getItem(options.key))\n ?? (options.legacyKey ? safeParseStoredSession(localStorage.getItem(options.legacyKey)) : null);\n if (existing && options.nowMs - existing.last_activity_ms <= IDLE_TTL_MS) {\n return existing;\n }\n const next: StoredSession = {\n session_id: generateUuid(),\n created_at_ms: options.nowMs,\n last_activity_ms: options.nowMs,\n };\n localStorage.setItem(options.key, JSON.stringify(next));\n return next;\n}\n\nexport type SessionRecorderDeps = {\n projectId: string,\n sendBatch: (body: string, options: { keepalive: boolean }) => Promise<Result<Response, Error>>,\n};\n\nexport function isAnalyticsNotEnabledError(error: unknown): boolean {\n return KnownErrors.AnalyticsNotEnabled.isInstance(error);\n}\n\n/**\n * Whether the error looks like a network failure caused by an ad blocker or\n * similar extension blocking analytics requests. These are expected in\n * production and should be silently ignored rather than logged as warnings.\n */\nexport function isAdBlockerNetworkError(error: unknown): boolean {\n if (error instanceof Error) {\n return error.message.includes(\"Failed to fetch\")\n || error.message.includes(\"NetworkError\")\n || error.message.includes(\"Load failed\")\n || error.message.includes(\"network connection\");\n }\n return false;\n}\n\nexport class SessionRecorder {\n private _started = false;\n private _cancelled = false;\n private _disabled = false;\n private _stopRecording: (() => void) | null = null;\n private _detachListeners: (() => void) | null = null;\n private _flushTimer: ReturnType<typeof setInterval> | null = null;\n private _events: unknown[] = [];\n private _eventSizes: number[] = [];\n private _approxBytes = 0;\n private _lastPersistActivity = 0;\n private _recording = false;\n private _rrwebModule: typeof import(\"rrweb\") | null = null;\n private _lastBrowserSessionId: string | null = null;\n private _takingSnapshot = false;\n private _flushInProgress = false;\n private readonly _sessionReplaySegmentId: string;\n private readonly _storageKey: string;\n // Hexclave rebrand: legacy key used for dual-read fallback only.\n private readonly _legacyStorageKey: string;\n private readonly _deps: SessionRecorderDeps;\n private readonly _replayOptions: AnalyticsReplayOptions;\n\n constructor(deps: SessionRecorderDeps, replayOptions: AnalyticsReplayOptions) {\n this._deps = deps;\n this._replayOptions = replayOptions;\n this._sessionReplaySegmentId = generateUuid();\n this._storageKey = makeStorageKey(deps.projectId);\n this._legacyStorageKey = makeLegacyStorageKey(deps.projectId);\n }\n\n /**\n * Starts recording. Idempotent — calling multiple times is safe.\n */\n start() {\n if (this._started) return;\n if (!isBrowserLike()) return;\n this._started = true;\n\n // Kick off rrweb recording\n runAsynchronously(() => this._startRecording(), { noErrorLogging: true });\n\n // Periodic flush\n this._flushTimer = setInterval(() => this._tick(), FLUSH_INTERVAL_MS);\n }\n\n stop() {\n this._cancelled = true;\n if (this._flushTimer !== null) {\n clearInterval(this._flushTimer);\n this._flushTimer = null;\n }\n // Flush remaining events before cleanup\n runAsynchronously(() => this._flush({ keepalive: true }));\n this._stopCurrentRecording();\n }\n\n clearBuffer() {\n this._events = [];\n this._eventSizes = [];\n this._approxBytes = 0;\n }\n\n private _persistActivity(nowMs: number): StoredSession {\n const stored = getOrRotateSession({ key: this._storageKey, legacyKey: this._legacyStorageKey, nowMs });\n if (nowMs - this._lastPersistActivity < 5_000) return stored;\n this._lastPersistActivity = nowMs;\n const updated: StoredSession = { ...stored, last_activity_ms: nowMs };\n localStorage.setItem(this._storageKey, JSON.stringify(updated));\n return stored;\n }\n\n private async _flush(options: { keepalive: boolean }) {\n if (this._disabled) return;\n if (this._events.length === 0) return;\n // Prevent concurrent in-flight HTTP requests. When a flush is already\n // in-flight, a second batch could race on the server (both call\n // findRecentSessionReplay before either upsert commits) and create\n // duplicate SessionReplay records. Events stay in _events and will be\n // picked up by the next tick or batch-size check.\n if (this._flushInProgress) return;\n\n const nowMs = Date.now();\n const stored = getOrRotateSession({ key: this._storageKey, legacyKey: this._legacyStorageKey, nowMs });\n\n // Capture all buffered events upfront (before any await) so that\n // stop() / _stopCurrentRecording() clearing this._events cannot race\n // with the async send loop below and silently discard overflow batches.\n const allEvents = this._events;\n const allSizes = this._eventSizes;\n this._events = [];\n this._eventSizes = [];\n this._approxBytes = 0;\n\n this._flushInProgress = true;\n try {\n let offset = 0;\n while (offset < allEvents.length) {\n // Build a batch that fits under the server's payload limit.\n // When _flushInProgress blocked earlier flushes, events can accumulate\n // well past MAX_APPROX_BYTES_PER_BATCH; sending them all at once would\n // exceed the server's 1MB body limit (413).\n // A single event over the limit can't be sent (rrweb events aren't splittable); drop it and move on.\n const firstSize = allSizes[offset] ?? throwErr(\"_eventSizes out of sync with _events — this should never happen\");\n if (firstSize > MAX_FLUSH_PAYLOAD_BYTES) {\n captureWarning(\n \"SessionRecorder.flush\",\n new Error(`Dropping oversized session replay event (${firstSize} bytes > ${MAX_FLUSH_PAYLOAD_BYTES} byte limit); it cannot be sent without a 413.`),\n );\n offset += 1;\n continue;\n }\n\n let batchBytes = 0;\n let batchEnd = offset;\n for (let i = offset; i < allEvents.length; i++) {\n const nextSize = allSizes[i] ?? throwErr(\"_eventSizes out of sync with _events — this should never happen\");\n if (batchBytes + nextSize > MAX_FLUSH_PAYLOAD_BYTES && batchEnd > offset) break;\n batchBytes += nextSize;\n batchEnd = i + 1;\n }\n\n const batchEvents = allEvents.slice(offset, batchEnd);\n offset = batchEnd;\n\n const batchId = generateUuid();\n const payload = {\n browser_session_id: stored.session_id,\n session_replay_segment_id: this._sessionReplaySegmentId,\n batch_id: batchId,\n started_at_ms: stored.created_at_ms,\n sent_at_ms: nowMs,\n events: batchEvents,\n };\n\n const res = await this._deps.sendBatch(\n JSON.stringify(payload),\n { keepalive: options.keepalive },\n );\n\n if (res.status === \"error\") {\n if (isAnalyticsNotEnabledError(res.error)) {\n this._disable();\n return;\n }\n // Ad blockers commonly block analytics endpoints, causing network\n // errors. These are expected and should not pollute the console.\n if (isAdBlockerNetworkError(res.error)) {\n return;\n }\n captureWarning(\"SessionRecorder.flush\", res.error);\n return;\n }\n\n if (!res.data.ok) {\n captureWarning(\"SessionRecorder.flush\", new Error(`SessionRecorder flush failed: ${res.data.status} ${await res.data.text()}`));\n return;\n }\n }\n } finally {\n this._flushInProgress = false;\n }\n }\n\n private _disable() {\n this._disabled = true;\n this.clearBuffer();\n if (this._flushTimer !== null) {\n clearInterval(this._flushTimer);\n this._flushTimer = null;\n }\n this._stopCurrentRecording();\n }\n\n private async _startRecording() {\n if (this._recording || this._cancelled) return;\n\n if (!this._rrwebModule) {\n const rrwebImport = await Result.fromPromise(import(\"rrweb\"));\n if (rrwebImport.status === \"error\") {\n console.warn(\"SessionRecorder: rrweb import failed. Is rrweb installed?\", rrwebImport.error);\n return;\n }\n this._rrwebModule = rrwebImport.data;\n }\n\n // cancelled may change during the await above\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this._cancelled) return;\n\n this._stopRecording = this._rrwebModule.record({\n emit: (event) => {\n const nowMs = Date.now();\n const stored = this._persistActivity(nowMs);\n\n // Detect session rotation: after 3+ minutes idle, getOrRotateSession\n // creates a new session ID. We need to inject a FullSnapshot so the\n // new server-side SessionReplay record is playable.\n if (this._lastBrowserSessionId === null) {\n this._lastBrowserSessionId = stored.session_id;\n } else if (stored.session_id !== this._lastBrowserSessionId && !this._takingSnapshot) {\n this._lastBrowserSessionId = stored.session_id;\n // Inject a FullSnapshot for the new session (calls emit synchronously)\n this._takingSnapshot = true;\n try {\n this._rrwebModule!.record.takeFullSnapshot();\n } finally {\n this._takingSnapshot = false;\n }\n }\n\n // Measure UTF-8 byte length to match the server's byte limit (.length counts UTF-16 units, undercounting multibyte content).\n const eventSize = textEncoder.encode(JSON.stringify(event)).byteLength;\n this._events.push(event);\n this._eventSizes.push(eventSize);\n this._approxBytes += eventSize;\n if (this._events.length >= MAX_EVENTS_PER_BATCH || this._approxBytes >= MAX_APPROX_BYTES_PER_BATCH) {\n runAsynchronously(() => this._flush({ keepalive: false }));\n }\n },\n maskAllInputs: this._replayOptions.maskAllInputs ?? true,\n ...(this._replayOptions.blockClass !== undefined ? { blockClass: this._replayOptions.blockClass } : {}),\n ...(this._replayOptions.blockSelector !== undefined ? { blockSelector: this._replayOptions.blockSelector } : {}),\n }) ?? null;\n\n this._recording = true;\n\n const onPageHide = () => {\n runAsynchronously(() => this._flush({ keepalive: true }));\n };\n window.addEventListener(\"pagehide\", onPageHide);\n document.addEventListener(\"visibilitychange\", onPageHide);\n this._detachListeners = () => {\n window.removeEventListener(\"pagehide\", onPageHide);\n document.removeEventListener(\"visibilitychange\", onPageHide);\n };\n }\n\n private _stopCurrentRecording() {\n if (this._detachListeners) {\n this._detachListeners();\n this._detachListeners = null;\n }\n if (this._stopRecording) {\n this._stopRecording();\n this._stopRecording = null;\n }\n this._events = [];\n this._eventSizes = [];\n this._approxBytes = 0;\n this._recording = false;\n }\n\n private _tick() {\n if (this._cancelled) return;\n if (this._events.length > 0) {\n runAsynchronously(() => this._flush({ keepalive: false }));\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -200,6 +200,7 @@ type StackClientApp<HasTokenStore extends boolean = boolean, ProjectId extends s
|
|
|
200
200
|
accessToken: string;
|
|
201
201
|
refreshToken: string;
|
|
202
202
|
}): Promise<void>;
|
|
203
|
+
awaitPendingAuthResolutions(): Promise<void>;
|
|
203
204
|
};
|
|
204
205
|
} & AsyncStoreProperty<"project", [], Project, false> & AsyncStoreProperty<"item", [{
|
|
205
206
|
itemId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-app.d.ts","names":[],"sources":["../../../../../src/lib/hexclave-app/apps/interfaces/client-app.ts"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"client-app.d.ts","names":[],"sources":["../../../../../src/lib/hexclave-app/apps/interfaces/client-app.ts"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-app.js","names":["_HexclaveClientAppImpl"],"sources":["../../../../../src/lib/hexclave-app/apps/interfaces/client-app.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownErrors } from \"@hexclave/shared\";\nimport { CurrentUserCrud } from \"@hexclave/shared/dist/interface/crud/current-user\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { AsyncStoreProperty, AuthLike, GetCurrentPartialUserOptions, GetCurrentUserOptions, HandlerUrlOptions, HandlerUrls, OAuthScopesOnSignIn, RedirectMethod, RedirectToOptions, ResolvedHandlerUrls, hexclaveAppInternalsSymbol, TokenStoreInit } from \"../../common\";\nimport type { RequestListener } from \"@hexclave/shared/dist/interface/client-interface\";\nimport { CustomerInvoicesList, CustomerInvoicesRequestOptions, CustomerProductsList, CustomerProductsRequestOptions, Item } from \"../../customers\";\nimport { Project } from \"../../projects\";\nimport { ProjectCurrentUser, SyncedPartialUser, TokenPartialUser } from \"../../users\";\nimport { _HexclaveClientAppImpl } from \"../implementations\";\nimport { AnalyticsOptions } from \"../implementations/session-replay\";\n\n/** @deprecated Use `HexclaveClientAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = {\n baseUrl?: string | { browser: string, server: string },\n extraRequestHeaders?: Record<string, string>,\n projectId?: ProjectId,\n publishableClientKey?: string,\n urls?: HandlerUrlOptions,\n oauthScopesOnSignIn?: Partial<OAuthScopesOnSignIn>,\n tokenStore?: TokenStoreInit<HasTokenStore>,\n redirectMethod?: RedirectMethod,\n inheritsFrom?: StackClientApp<any, any>,\n\n /**\n * Whether to show the Hexclave dev tool indicator in browser-like environments.\n *\n * - `true`: always show\n * - `false`: never show\n * - `\"auto\"` (default): show based on NODE_ENV or origin heuristics\n */\n devTool?: boolean | \"auto\",\n\n /**\n * By default, the Stack app will automatically prefetch some data from Stack's server when this app is first\n * constructed. This improves the performance of your app, but will create network requests that are unnecessary if\n * the app is never used or disposed of immediately. To disable this behavior, set this option to true.\n */\n noAutomaticPrefetch?: boolean,\n\n /**\n * Options for analytics and session recording. Replays are enabled by default;\n * set `{ replays: { enabled: false } }` to opt out.\n */\n analytics?: AnalyticsOptions,\n} & (\n { tokenStore: TokenStoreInit<HasTokenStore> } | { tokenStore?: undefined, inheritsFrom: StackClientApp<HasTokenStore, any> }\n) & (\n string extends ProjectId ? unknown : ({ projectId: ProjectId } | { inheritsFrom: StackClientApp<any, ProjectId> })\n);\n\n\n/** @deprecated Use `HexclaveClientAppJson` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId> & { inheritsFrom?: undefined } & {\n uniqueIdentifier: string,\n // note: if you add more fields here, make sure to ensure the checkString in the constructor has/doesn't have them\n};\n\n/** @deprecated Use `HexclaveClientApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = (\n & {\n readonly projectId: ProjectId,\n\n /**\n * The version of the Hexclave SDK.\n */\n readonly version: string,\n\n /**\n * @deprecated Do not use `app.urls` for navigation. It is static and does not include runtime redirect-back,\n * cross-domain auth, or sign-out state. Use the matching `redirectToXyz()` method instead, for example\n * `redirectToSignIn()`, `redirectToSignUp()`, `redirectToSignOut()`, or `redirectToAccountSettings()`.\n */\n readonly urls: Readonly<ResolvedHandlerUrls>,\n\n signInWithOAuth(provider: string, options?: { returnTo?: string }): Promise<void>,\n signInWithCredential(options: { email: string, password: string, noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"EmailPasswordMismatch\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n signUpWithCredential(options: {\n email: string,\n password: string,\n noRedirect?: boolean,\n } & ({ noVerificationCallback: true } | { noVerificationCallback?: false, verificationCallbackUrl?: string })): Promise<Result<undefined, KnownErrors[\"UserWithEmailAlreadyExists\"] | KnownErrors[\"PasswordRequirementsNotMet\"] | KnownErrors[\"BotChallengeFailed\"]>>,\n signInWithPasskey(): Promise<Result<undefined, KnownErrors[\"PasskeyAuthenticationFailed\"] | KnownErrors[\"InvalidTotpCode\"] | KnownErrors[\"PasskeyWebAuthnError\"]>>,\n callOAuthCallback(): Promise<boolean>,\n promptCliLogin(options: { appUrl: string, expiresInMillis?: number, anonRefreshToken?: string, promptLink?: (url: string, loginCode: string) => void }): Promise<Result<string, KnownErrors[\"CliAuthError\"] | KnownErrors[\"CliAuthExpiredError\"] | KnownErrors[\"CliAuthUsedError\"]>>,\n sendForgotPasswordEmail(email: string, options?: { callbackUrl?: string }): Promise<Result<undefined, KnownErrors[\"UserNotFound\"]>>,\n sendMagicLinkEmail(email: string, options?: { callbackUrl?: string }): Promise<Result<{ nonce: string }, KnownErrors[\"RedirectUrlNotWhitelisted\"] | KnownErrors[\"BotChallengeFailed\"]>>,\n resetPassword(options: { code: string, password: string }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n verifyPasswordResetCode(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n verifyTeamInvitationCode(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n acceptTeamInvitation(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n getTeamInvitationDetails(code: string): Promise<Result<{ teamDisplayName: string }, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n verifyEmail(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n signInWithMagicLink(code: string, options?: { noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n signInWithMfa(otp: string, code: string, options?: { noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n\n redirectToOAuthCallback(): Promise<void>,\n\n getConvexClientAuth(options: HasTokenStore extends false ? { tokenStore: TokenStoreInit } : { tokenStore?: TokenStoreInit }): (args: { forceRefreshToken: boolean }) => Promise<string | null>,\n getConvexHttpClientAuth(options: { tokenStore: TokenStoreInit }): Promise<string>,\n\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): ProjectCurrentUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): ProjectCurrentUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): ProjectCurrentUser<ProjectId>,\n useUser(options?: GetCurrentUserOptions<HasTokenStore>): ProjectCurrentUser<ProjectId> | null,\n\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options?: GetCurrentUserOptions<HasTokenStore>): Promise<ProjectCurrentUser<ProjectId> | null>,\n\n cancelSubscription(options: { productId: string, subscriptionId?: string } | { productId: string, subscriptionId?: string, teamId: string }): Promise<void>,\n\n // note: we don't special-case 'anonymous' here to return non-null, see GetPartialUserOptions for more details\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): Promise<SyncedPartialUser | TokenPartialUser | null>,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): SyncedPartialUser | TokenPartialUser | null,\n useNavigate(): (to: string) => void, // THIS_LINE_PLATFORM react-like\n\n [hexclaveAppInternalsSymbol]: {\n toClientJson(): StackClientAppJson<HasTokenStore, ProjectId>,\n setCurrentUser(userJsonPromise: Promise<CurrentUserCrud['Client']['Read'] | null>): void,\n getConstructorOptions(): StackClientAppConstructorOptions<HasTokenStore, ProjectId> & { inheritsFrom?: undefined },\n sendSessionReplayBatch(body: string, options: { keepalive: boolean }): Promise<Result<Response, Error>>,\n sendAnalyticsEventBatch(body: string, options: { keepalive: boolean }): Promise<Result<Response, Error>>,\n addRequestListener(listener: RequestListener): () => void,\n sendRequest(path: string, requestOptions: RequestInit, requestType?: \"client\" | \"server\" | \"admin\"): Promise<Response>,\n getUrls(): Readonly<ResolvedHandlerUrls>,\n getRedirectMethod(): RedirectMethod,\n redirectToUrl(url: string | URL, options?: { replace?: boolean }): Promise<void>,\n redirectToHandler(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<void>,\n signInWithTokens(tokens: { accessToken: string, refreshToken: string }): Promise<void>,\n },\n }\n & AsyncStoreProperty<\"project\", [], Project, false>\n & AsyncStoreProperty<\n \"item\",\n [{ itemId: string, userId: string } | { itemId: string, teamId: string } | { itemId: string, customCustomerId: string }],\n Item,\n false\n >\n & AsyncStoreProperty<\n \"products\",\n [options: CustomerProductsRequestOptions],\n CustomerProductsList,\n true\n >\n & AsyncStoreProperty<\n \"invoices\",\n [options: CustomerInvoicesRequestOptions],\n CustomerInvoicesList,\n true\n >\n & { [K in `redirectTo${Capitalize<keyof Omit<HandlerUrls, 'handler' | 'oauthCallback'>>}`]: (options?: RedirectToOptions) => Promise<void> }\n & AuthLike<HasTokenStore extends false ? { tokenStore: TokenStoreInit } : { tokenStore?: TokenStoreInit }>\n);\n/** @deprecated Use `HexclaveClientAppConstructor` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppConstructor = {\n new <\n TokenStoreType extends string,\n HasTokenStore extends (TokenStoreType extends {} ? true : boolean),\n ProjectId extends string\n >(options: StackClientAppConstructorOptions<HasTokenStore, ProjectId>): StackClientApp<HasTokenStore, ProjectId>,\n new(options: StackClientAppConstructorOptions<boolean, string>): StackClientApp<boolean, string>,\n\n [hexclaveAppInternalsSymbol]: {\n fromClientJson<HasTokenStore extends boolean, ProjectId extends string>(\n json: StackClientAppJson<HasTokenStore, ProjectId>\n ): StackClientApp<HasTokenStore, ProjectId>,\n },\n};\nexport type HexclaveClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId>;\nexport type HexclaveClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppJson<HasTokenStore, ProjectId>;\nexport type HexclaveClientApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = StackClientApp<HasTokenStore, ProjectId>;\nexport type HexclaveClientAppConstructor = StackClientAppConstructor;\nexport const HexclaveClientApp: HexclaveClientAppConstructor = _HexclaveClientAppImpl;\n/** @deprecated Use `HexclaveClientApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport const StackClientApp: StackClientAppConstructor = HexclaveClientApp;\n"],"mappings":";;;;;AAqLA,MAAa,oBAAkDA;;AAE/D,MAAa,iBAA4C"}
|
|
1
|
+
{"version":3,"file":"client-app.js","names":["_HexclaveClientAppImpl"],"sources":["../../../../../src/lib/hexclave-app/apps/interfaces/client-app.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownErrors } from \"@hexclave/shared\";\nimport { CurrentUserCrud } from \"@hexclave/shared/dist/interface/crud/current-user\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { AsyncStoreProperty, AuthLike, GetCurrentPartialUserOptions, GetCurrentUserOptions, HandlerUrlOptions, HandlerUrls, OAuthScopesOnSignIn, RedirectMethod, RedirectToOptions, ResolvedHandlerUrls, hexclaveAppInternalsSymbol, TokenStoreInit } from \"../../common\";\nimport type { RequestListener } from \"@hexclave/shared/dist/interface/client-interface\";\nimport { CustomerInvoicesList, CustomerInvoicesRequestOptions, CustomerProductsList, CustomerProductsRequestOptions, Item } from \"../../customers\";\nimport { Project } from \"../../projects\";\nimport { ProjectCurrentUser, SyncedPartialUser, TokenPartialUser } from \"../../users\";\nimport { _HexclaveClientAppImpl } from \"../implementations\";\nimport { AnalyticsOptions } from \"../implementations/session-replay\";\n\n/** @deprecated Use `HexclaveClientAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = {\n baseUrl?: string | { browser: string, server: string },\n extraRequestHeaders?: Record<string, string>,\n projectId?: ProjectId,\n publishableClientKey?: string,\n urls?: HandlerUrlOptions,\n oauthScopesOnSignIn?: Partial<OAuthScopesOnSignIn>,\n tokenStore?: TokenStoreInit<HasTokenStore>,\n redirectMethod?: RedirectMethod,\n inheritsFrom?: StackClientApp<any, any>,\n\n /**\n * Whether to show the Hexclave dev tool indicator in browser-like environments.\n *\n * - `true`: always show\n * - `false`: never show\n * - `\"auto\"` (default): show based on NODE_ENV or origin heuristics\n */\n devTool?: boolean | \"auto\",\n\n /**\n * By default, the Stack app will automatically prefetch some data from Stack's server when this app is first\n * constructed. This improves the performance of your app, but will create network requests that are unnecessary if\n * the app is never used or disposed of immediately. To disable this behavior, set this option to true.\n */\n noAutomaticPrefetch?: boolean,\n\n /**\n * Options for analytics and session recording. Replays are enabled by default;\n * set `{ replays: { enabled: false } }` to opt out.\n */\n analytics?: AnalyticsOptions,\n} & (\n { tokenStore: TokenStoreInit<HasTokenStore> } | { tokenStore?: undefined, inheritsFrom: StackClientApp<HasTokenStore, any> }\n) & (\n string extends ProjectId ? unknown : ({ projectId: ProjectId } | { inheritsFrom: StackClientApp<any, ProjectId> })\n);\n\n\n/** @deprecated Use `HexclaveClientAppJson` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId> & { inheritsFrom?: undefined } & {\n uniqueIdentifier: string,\n // note: if you add more fields here, make sure to ensure the checkString in the constructor has/doesn't have them\n};\n\n/** @deprecated Use `HexclaveClientApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = (\n & {\n readonly projectId: ProjectId,\n\n /**\n * The version of the Hexclave SDK.\n */\n readonly version: string,\n\n /**\n * @deprecated Do not use `app.urls` for navigation. It is static and does not include runtime redirect-back,\n * cross-domain auth, or sign-out state. Use the matching `redirectToXyz()` method instead, for example\n * `redirectToSignIn()`, `redirectToSignUp()`, `redirectToSignOut()`, or `redirectToAccountSettings()`.\n */\n readonly urls: Readonly<ResolvedHandlerUrls>,\n\n signInWithOAuth(provider: string, options?: { returnTo?: string }): Promise<void>,\n signInWithCredential(options: { email: string, password: string, noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"EmailPasswordMismatch\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n signUpWithCredential(options: {\n email: string,\n password: string,\n noRedirect?: boolean,\n } & ({ noVerificationCallback: true } | { noVerificationCallback?: false, verificationCallbackUrl?: string })): Promise<Result<undefined, KnownErrors[\"UserWithEmailAlreadyExists\"] | KnownErrors[\"PasswordRequirementsNotMet\"] | KnownErrors[\"BotChallengeFailed\"]>>,\n signInWithPasskey(): Promise<Result<undefined, KnownErrors[\"PasskeyAuthenticationFailed\"] | KnownErrors[\"InvalidTotpCode\"] | KnownErrors[\"PasskeyWebAuthnError\"]>>,\n callOAuthCallback(): Promise<boolean>,\n promptCliLogin(options: { appUrl: string, expiresInMillis?: number, anonRefreshToken?: string, promptLink?: (url: string, loginCode: string) => void }): Promise<Result<string, KnownErrors[\"CliAuthError\"] | KnownErrors[\"CliAuthExpiredError\"] | KnownErrors[\"CliAuthUsedError\"]>>,\n sendForgotPasswordEmail(email: string, options?: { callbackUrl?: string }): Promise<Result<undefined, KnownErrors[\"UserNotFound\"]>>,\n sendMagicLinkEmail(email: string, options?: { callbackUrl?: string }): Promise<Result<{ nonce: string }, KnownErrors[\"RedirectUrlNotWhitelisted\"] | KnownErrors[\"BotChallengeFailed\"]>>,\n resetPassword(options: { code: string, password: string }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n verifyPasswordResetCode(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n verifyTeamInvitationCode(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n acceptTeamInvitation(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n getTeamInvitationDetails(code: string): Promise<Result<{ teamDisplayName: string }, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"TeamInvitationEmailMismatch\"]>>,\n verifyEmail(code: string): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"]>>,\n signInWithMagicLink(code: string, options?: { noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n signInWithMfa(otp: string, code: string, options?: { noRedirect?: boolean }): Promise<Result<undefined, KnownErrors[\"VerificationCodeError\"] | KnownErrors[\"InvalidTotpCode\"]>>,\n\n redirectToOAuthCallback(): Promise<void>,\n\n getConvexClientAuth(options: HasTokenStore extends false ? { tokenStore: TokenStoreInit } : { tokenStore?: TokenStoreInit }): (args: { forceRefreshToken: boolean }) => Promise<string | null>,\n getConvexHttpClientAuth(options: { tokenStore: TokenStoreInit }): Promise<string>,\n\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): ProjectCurrentUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): ProjectCurrentUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): ProjectCurrentUser<ProjectId>,\n useUser(options?: GetCurrentUserOptions<HasTokenStore>): ProjectCurrentUser<ProjectId> | null,\n\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): Promise<ProjectCurrentUser<ProjectId>>,\n getUser(options?: GetCurrentUserOptions<HasTokenStore>): Promise<ProjectCurrentUser<ProjectId> | null>,\n\n cancelSubscription(options: { productId: string, subscriptionId?: string } | { productId: string, subscriptionId?: string, teamId: string }): Promise<void>,\n\n // note: we don't special-case 'anonymous' here to return non-null, see GetPartialUserOptions for more details\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): Promise<SyncedPartialUser | TokenPartialUser | null>,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): SyncedPartialUser | TokenPartialUser | null,\n useNavigate(): (to: string) => void, // THIS_LINE_PLATFORM react-like\n\n [hexclaveAppInternalsSymbol]: {\n toClientJson(): StackClientAppJson<HasTokenStore, ProjectId>,\n setCurrentUser(userJsonPromise: Promise<CurrentUserCrud['Client']['Read'] | null>): void,\n getConstructorOptions(): StackClientAppConstructorOptions<HasTokenStore, ProjectId> & { inheritsFrom?: undefined },\n sendSessionReplayBatch(body: string, options: { keepalive: boolean }): Promise<Result<Response, Error>>,\n sendAnalyticsEventBatch(body: string, options: { keepalive: boolean }): Promise<Result<Response, Error>>,\n addRequestListener(listener: RequestListener): () => void,\n sendRequest(path: string, requestOptions: RequestInit, requestType?: \"client\" | \"server\" | \"admin\"): Promise<Response>,\n getUrls(): Readonly<ResolvedHandlerUrls>,\n getRedirectMethod(): RedirectMethod,\n redirectToUrl(url: string | URL, options?: { replace?: boolean }): Promise<void>,\n redirectToHandler(handlerName: keyof HandlerUrls, options?: RedirectToOptions): Promise<void>,\n signInWithTokens(tokens: { accessToken: string, refreshToken: string }): Promise<void>,\n awaitPendingAuthResolutions(): Promise<void>,\n },\n }\n & AsyncStoreProperty<\"project\", [], Project, false>\n & AsyncStoreProperty<\n \"item\",\n [{ itemId: string, userId: string } | { itemId: string, teamId: string } | { itemId: string, customCustomerId: string }],\n Item,\n false\n >\n & AsyncStoreProperty<\n \"products\",\n [options: CustomerProductsRequestOptions],\n CustomerProductsList,\n true\n >\n & AsyncStoreProperty<\n \"invoices\",\n [options: CustomerInvoicesRequestOptions],\n CustomerInvoicesList,\n true\n >\n & { [K in `redirectTo${Capitalize<keyof Omit<HandlerUrls, 'handler' | 'oauthCallback'>>}`]: (options?: RedirectToOptions) => Promise<void> }\n & AuthLike<HasTokenStore extends false ? { tokenStore: TokenStoreInit } : { tokenStore?: TokenStoreInit }>\n);\n/** @deprecated Use `HexclaveClientAppConstructor` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackClientAppConstructor = {\n new <\n TokenStoreType extends string,\n HasTokenStore extends (TokenStoreType extends {} ? true : boolean),\n ProjectId extends string\n >(options: StackClientAppConstructorOptions<HasTokenStore, ProjectId>): StackClientApp<HasTokenStore, ProjectId>,\n new(options: StackClientAppConstructorOptions<boolean, string>): StackClientApp<boolean, string>,\n\n [hexclaveAppInternalsSymbol]: {\n fromClientJson<HasTokenStore extends boolean, ProjectId extends string>(\n json: StackClientAppJson<HasTokenStore, ProjectId>\n ): StackClientApp<HasTokenStore, ProjectId>,\n },\n};\nexport type HexclaveClientAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId>;\nexport type HexclaveClientAppJson<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppJson<HasTokenStore, ProjectId>;\nexport type HexclaveClientApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = StackClientApp<HasTokenStore, ProjectId>;\nexport type HexclaveClientAppConstructor = StackClientAppConstructor;\nexport const HexclaveClientApp: HexclaveClientAppConstructor = _HexclaveClientAppImpl;\n/** @deprecated Use `HexclaveClientApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport const StackClientApp: StackClientAppConstructor = HexclaveClientApp;\n"],"mappings":";;;;;AAsLA,MAAa,oBAAkDA;;AAE/D,MAAa,iBAA4C"}
|
|
@@ -35,6 +35,19 @@ type StackServerApp<HasTokenStore extends boolean = boolean, ProjectId extends s
|
|
|
35
35
|
}) & {
|
|
36
36
|
quantity?: number;
|
|
37
37
|
})): Promise<void>;
|
|
38
|
+
createCheckoutUrl(options: (({
|
|
39
|
+
userId: string;
|
|
40
|
+
} | {
|
|
41
|
+
teamId: string;
|
|
42
|
+
} | {
|
|
43
|
+
customCustomerId: string;
|
|
44
|
+
}) & ({
|
|
45
|
+
productId: string;
|
|
46
|
+
} | {
|
|
47
|
+
product: InlineProduct;
|
|
48
|
+
}) & {
|
|
49
|
+
returnUrl?: string;
|
|
50
|
+
})): Promise<string>;
|
|
38
51
|
useUser(options: GetCurrentUserOptions<HasTokenStore> & {
|
|
39
52
|
or: 'redirect';
|
|
40
53
|
}): ProjectCurrentServerUser<ProjectId>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-app.d.ts","names":[],"sources":["../../../../../src/lib/hexclave-app/apps/interfaces/server-app.ts"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"server-app.d.ts","names":[],"sources":["../../../../../src/lib/hexclave-app/apps/interfaces/server-app.ts"],"mappings":";;;;;;;;;;;;;KAkBY,gCAAA,4DAA4F,gCAAA,CAAiC,aAAA,EAAe,SAAA;EACtJ,eAAA;AAAA;;KAIU,cAAA;EAER,UAAA,CAAW,IAAA,EAAM,uBAAA,GAA0B,OAAA,CAAQ,UAAA;EAPiD;;;EAWpG,aAAA,IAAiB,OAAA,CAAQ,wBAAA,CAAyB,SAAA;EAElD,UAAA,CAAW,OAAA,EAAS,uBAAA,GAA0B,OAAA,CAAQ,UAAA;EACtD,YAAA,CAAa,OAAA;IACR,MAAA;EAAA;IAAqB,MAAA;EAAA;IAAqB,gBAAA;EAAA;IAC1C,SAAA;EAAA;IAAwB,OAAA,EAAS,aAAA;EAAA;IAClC,QAAA;EAAA,KACA,OAAA;EACJ,iBAAA,CAAkB,OAAA;IACb,MAAA;EAAA;IAAqB,MAAA;EAAA;IAAqB,gBAAA;EAAA;IAC1C,SAAA;EAAA;IAAwB,OAAA,EAAS,aAAA;EAAA;IAClC,SAAA;EAAA,KACA,OAAA;EAEJ,OAAA,CAAQ,OAAA,EAAS,qBAAA,CAAsB,aAAA;IAAmB,EAAA;EAAA,IAAmB,wBAAA,CAAyB,SAAA;EACtG,OAAA,CAAQ,OAAA,EAAS,qBAAA,CAAsB,aAAA;IAAmB,EAAA;EAAA,IAAgB,wBAAA,CAAyB,SAAA;EACnG,OAAA,CAAQ,OAAA,EAAS,qBAAA,CAAsB,aAAA;IAAmB,EAAA;EAAA,IAAoB,wBAAA,CAAyB,SAAA;EACvG,OAAA,CAAQ,OAAA,GAAU,qBAAA,CAAsB,aAAA,IAAiB,wBAAA,CAAyB,SAAA;EAClF,OAAA,CAAQ,EAAA,WAAa,UAAA;EACrB,OAAA,CAAQ,OAAA;IAAW,MAAA;IAAgB,EAAA;EAAA,IAAqC,UAAA;EACxE,OAAA,CAAQ,OAAA;IAAW,IAAA;IAAgB,GAAA,EAAK,eAAA;IAAsB,EAAA;EAAA,IAAqC,UAAA;EAEnG,OAAA,CAAQ,OAAA,EAAS,qBAAA,CAAsB,aAAA;IAAmB,EAAA;EAAA,IAAmB,OAAA,CAAQ,wBAAA,CAAyB,SAAA;EAC9G,OAAA,CAAQ,OAAA,EAAS,qBAAA,CAAsB,aAAA;IAAmB,EAAA;EAAA,IAAgB,OAAA,CAAQ,wBAAA,CAAyB,SAAA;EAC3G,OAAA,CAAQ,OAAA,EAAS,qBAAA,CAAsB,aAAA;IAAmB,EAAA;EAAA,IAAoB,OAAA,CAAQ,wBAAA,CAAyB,SAAA;EAC/G,OAAA,CAAQ,OAAA,GAAU,qBAAA,CAAsB,aAAA,IAAiB,OAAA,CAAQ,wBAAA,CAAyB,SAAA;EAC1F,OAAA,CAAQ,EAAA,WAAa,OAAA,CAAQ,UAAA;EAC7B,OAAA,CAAQ,OAAA;IAAW,MAAA;IAAgB,EAAA;EAAA,IAAqC,OAAA,CAAQ,UAAA;EAChF,OAAA,CAAQ,OAAA;IAAW,IAAA;IAAgB,GAAA,EAAK,eAAA;IAAsB,EAAA;EAAA,IAAqC,OAAA,CAAQ,UAAA;EAG3G,cAAA,CAAe,OAAA,EAAS,4BAAA,CAA6B,aAAA;IAAmB,IAAA;EAAA,IAAkB,OAAA,CAAQ,gBAAA;EAClG,cAAA,CAAe,OAAA,EAAS,4BAAA,CAA6B,aAAA;IAAmB,IAAA;EAAA,IAAmB,OAAA,CAAQ,gBAAA;EACnG,cAAA,CAAe,OAAA,EAAS,4BAAA,CAA6B,aAAA,IAAiB,OAAA,CAAQ,uBAAA,GAA0B,gBAAA;EACxG,cAAA,CAAe,OAAA,EAAS,4BAAA,CAA6B,aAAA;IAAmB,IAAA;EAAA,IAAkB,gBAAA;EAC1F,cAAA,CAAe,OAAA,EAAS,4BAAA,CAA6B,aAAA;IAAmB,IAAA;EAAA,IAAmB,gBAAA;EAC3F,cAAA,CAAe,OAAA,EAAS,4BAAA,CAA6B,aAAA,IAAiB,uBAAA,GAA0B,gBAAA;EAChG,OAAA,CAAQ,EAAA,WAAa,UAAA;EACrB,OAAA,CAAQ,OAAA;IAAW,MAAA;EAAA,IAAmB,UAAA;EACtC,OAAA,CAAQ,EAAA,WAAa,OAAA,CAAQ,UAAA;EAC7B,OAAA,CAAQ,OAAA;IAAW,MAAA;EAAA,IAAmB,OAAA,CAAQ,UAAA;EAG9C,QAAA,CAAS,OAAA,GAAU,sBAAA,GAAyB,UAAA;IAAiB,UAAA;EAAA;EAC7D,SAAA,CAAU,OAAA,GAAU,sBAAA,GAAyB,OAAA,CAAQ,UAAA;IAAiB,UAAA;EAAA;EALzC;;;;;;EAa7B,yBAAA,CAA0B,MAAA,UAAgB,OAAA;IAAY,SAAA;EAAA,IAAwB,OAAA;IAAU,MAAA;IAAgB,YAAA;EAAA;EACxG,wBAAA,CAAyB,MAAA,UAAgB,OAAA;IAAY,SAAA;EAAA;IAA0B,MAAA;IAAgB,YAAA;EAAA;EAG/F,mBAAA,CAAoB,OAAA;IAClB,MAAA;IACA,SAAA;IACA,gBAAA;IACA,KAAA;IACA,WAAA;IACA,sBAAA;EAAA,IACE,OAAA,CAAQ,MAAA,CAAO,mBAAA,EAAqB,YAAA,QAAoB,WAAA,CAAY,0CAAA;EAExE,SAAA,CAAU,OAAA,EAAS,gBAAA,GAAmB,OAAA;EAEtC,qBAAA,IAAyB,OAAA,CAAQ,iBAAA;EACjC,qBAAA,IAAyB,iBAAA;EAEzB,0BAAA,IAA8B,OAAA;AAAA,IAE9B,kBAAA,UAA4B,EAAA,WAAa,UAAA,kBACzC,IAAA,CAAK,kBAAA,cAAgC,UAAA,uCACrC,kBAAA,WAA6B,OAAA,GAAU,sBAAA,GAAyB,UAAA;EAAiB,UAAA;AAAA,WACjF,kBAAA,oBAAsC,EAAA,WAAa,cAAA,WACnD,kBAAA;EAEG,MAAA;EAAgB,MAAA;AAAA;EAAqB,MAAA;EAAgB,MAAA;AAAA;EAAqB,MAAA;EAAgB,gBAAA;AAAA,IAC7F,UAAA,WAGA,kBAAA,cAEC,OAAA,EAAS,8BAAA,GACV,oBAAA,UAGA,cAAA,CAAe,aAAA,EAAe,SAAA;;KAGtB,yBAAA;EAAA,2DAGe,cAAA,yDAEvB,OAAA,EAAS,gCAAA,CAAiC,aAAA,EAAe,SAAA,IAAa,cAAA,CAAe,aAAA,EAAe,SAAA;EAAA,KACjG,OAAA,EAAS,gCAAA,oBAAoD,cAAA;AAAA;AAAA,KAExD,mCAAA,4DAA+F,gCAAA,CAAiC,aAAA,EAAe,SAAA;AAAA,KAC/I,iBAAA,+EAAgG,cAAA,CAAe,aAAA,EAAe,SAAA;AAAA,KAC9H,4BAAA,GAA+B,yBAAA;AAAA,cAC9B,iBAAA,EAAmB,4BAAA;;cAEnB,cAAA,EAAgB,yBAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-app.js","names":["_HexclaveServerAppImpl"],"sources":["../../../../../src/lib/hexclave-app/apps/interfaces/server-app.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownErrors } from \"@hexclave/shared\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport type { GenericQueryCtx } from \"convex/server\";\nimport { AsyncStoreProperty, GetCurrentPartialUserOptions, GetCurrentUserOptions } from \"../../common\";\nimport { CustomerProductsList, CustomerProductsRequestOptions, InlineProduct, ServerItem } from \"../../customers\";\nimport { DataVaultStore } from \"../../data-vault\";\nimport { EmailDeliveryInfo, SendEmailOptions } from \"../../email\";\nimport { ServerListTeamsOptions, ServerListUsersOptions, ServerTeam, ServerTeamCreateOptions } from \"../../teams\";\nimport { ProjectCurrentServerUser, ServerOAuthProvider, ServerUser, ServerUserCreateOptions, SyncedPartialServerUser, TokenPartialUser } from \"../../users\";\nimport { _HexclaveServerAppImpl } from \"../implementations\";\nimport { StackClientApp, StackClientAppConstructorOptions } from \"./client-app\";\n\n\n/** @deprecated Use `HexclaveServerAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackServerAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId> & {\n secretServerKey?: string,\n};\n\n/** @deprecated Use `HexclaveServerApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackServerApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = (\n & {\n createTeam(data: ServerTeamCreateOptions): Promise<ServerTeam>,\n /**\n * @deprecated use `getUser()` instead\n */\n getServerUser(): Promise<ProjectCurrentServerUser<ProjectId> | null>,\n\n createUser(options: ServerUserCreateOptions): Promise<ServerUser>,\n grantProduct(options: (\n ({ userId: string } | { teamId: string } | { customCustomerId: string }) &\n ({ productId: string } | { product: InlineProduct }) &\n { quantity?: number }\n )): Promise<void>,\n\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): ProjectCurrentServerUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): ProjectCurrentServerUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): ProjectCurrentServerUser<ProjectId>,\n useUser(options?: GetCurrentUserOptions<HasTokenStore>): ProjectCurrentServerUser<ProjectId> | null,\n useUser(id: string): ServerUser | null,\n useUser(options: { apiKey: string, or?: \"return-null\" | \"anonymous\" }): ServerUser | null,\n useUser(options: { from: \"convex\", ctx: GenericQueryCtx<any>, or?: \"return-null\" | \"anonymous\" }): ServerUser | null,\n\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): Promise<ProjectCurrentServerUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): Promise<ProjectCurrentServerUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): Promise<ProjectCurrentServerUser<ProjectId>>,\n getUser(options?: GetCurrentUserOptions<HasTokenStore>): Promise<ProjectCurrentServerUser<ProjectId> | null>,\n getUser(id: string): Promise<ServerUser | null>,\n getUser(options: { apiKey: string, or?: \"return-null\" | \"anonymous\" }): Promise<ServerUser | null>,\n getUser(options: { from: \"convex\", ctx: GenericQueryCtx<any>, or?: \"return-null\" | \"anonymous\" }): Promise<ServerUser | null>,\n\n // note: we don't special-case 'anonymous' here to return non-null, see GetPartialUserOptions for more details\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): Promise<SyncedPartialServerUser | TokenPartialUser | null>,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): SyncedPartialServerUser | TokenPartialUser | null,\n useTeam(id: string): ServerTeam | null,\n useTeam(options: { apiKey: string }): ServerTeam | null,\n getTeam(id: string): Promise<ServerTeam | null>,\n getTeam(options: { apiKey: string }): Promise<ServerTeam | null>,\n\n\n useUsers(options?: ServerListUsersOptions): ServerUser[] & { nextCursor: string | null }, // THIS_LINE_PLATFORM react-like\n listUsers(options?: ServerListUsersOptions): Promise<ServerUser[] & { nextCursor: string | null }>,\n\n /**\n * Returns every direct (or recursive) team permission grant for every\n * member of the given team in one request. Use this instead of calling\n * `user.listPermissions(team)` per row when rendering a roster — that\n * pattern produces an N+1 over the team-member endpoint.\n */\n listTeamMemberPermissions(teamId: string, options?: { recursive?: boolean }): Promise<{ userId: string, permissionId: string }[]>,\n useTeamMemberPermissions(teamId: string, options?: { recursive?: boolean }): { userId: string, permissionId: string }[],\n\n // TODO this should actually be on ServerUser\n createOAuthProvider(options: {\n userId: string,\n accountId: string,\n providerConfigId: string,\n email: string,\n allowSignIn: boolean,\n allowConnectedAccounts: boolean,\n }): Promise<Result<ServerOAuthProvider, InstanceType<typeof KnownErrors.OAuthProviderAccountIdAlreadyUsedForSignIn>>>,\n\n sendEmail(options: SendEmailOptions): Promise<void>,\n\n getEmailDeliveryStats(): Promise<EmailDeliveryInfo>,\n useEmailDeliveryStats(): EmailDeliveryInfo,\n\n activateEmailCapacityBoost(): Promise<void>,\n }\n & AsyncStoreProperty<\"user\", [id: string], ServerUser | null, false>\n & Omit<AsyncStoreProperty<\"users\", [], ServerUser[], true>, \"listUsers\" | \"useUsers\">\n & AsyncStoreProperty<\"teams\", [options?: ServerListTeamsOptions], ServerTeam[] & { nextCursor: string | null }, true>\n & AsyncStoreProperty<\"dataVaultStore\", [id: string], DataVaultStore, false>\n & AsyncStoreProperty<\n \"item\",\n [{ itemId: string, userId: string } | { itemId: string, teamId: string } | { itemId: string, customCustomerId: string }],\n ServerItem,\n false\n >\n & AsyncStoreProperty<\n \"products\",\n [options: CustomerProductsRequestOptions],\n CustomerProductsList,\n true\n >\n & StackClientApp<HasTokenStore, ProjectId>\n);\n/** @deprecated Use `HexclaveServerAppConstructor` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackServerAppConstructor = {\n new <\n TokenStoreType extends string,\n HasTokenStore extends (TokenStoreType extends {} ? true : boolean),\n ProjectId extends string\n >(options: StackServerAppConstructorOptions<HasTokenStore, ProjectId>): StackServerApp<HasTokenStore, ProjectId>,\n new (options: StackServerAppConstructorOptions<boolean, string>): StackServerApp<boolean, string>,\n};\nexport type HexclaveServerAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackServerAppConstructorOptions<HasTokenStore, ProjectId>;\nexport type HexclaveServerApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = StackServerApp<HasTokenStore, ProjectId>;\nexport type HexclaveServerAppConstructor = StackServerAppConstructor;\nexport const HexclaveServerApp: HexclaveServerAppConstructor = _HexclaveServerAppImpl;\n/** @deprecated Use `HexclaveServerApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport const StackServerApp: StackServerAppConstructor = HexclaveServerApp;\n"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"server-app.js","names":["_HexclaveServerAppImpl"],"sources":["../../../../../src/lib/hexclave-app/apps/interfaces/server-app.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownErrors } from \"@hexclave/shared\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport type { GenericQueryCtx } from \"convex/server\";\nimport { AsyncStoreProperty, GetCurrentPartialUserOptions, GetCurrentUserOptions } from \"../../common\";\nimport { CustomerProductsList, CustomerProductsRequestOptions, InlineProduct, ServerItem } from \"../../customers\";\nimport { DataVaultStore } from \"../../data-vault\";\nimport { EmailDeliveryInfo, SendEmailOptions } from \"../../email\";\nimport { ServerListTeamsOptions, ServerListUsersOptions, ServerTeam, ServerTeamCreateOptions } from \"../../teams\";\nimport { ProjectCurrentServerUser, ServerOAuthProvider, ServerUser, ServerUserCreateOptions, SyncedPartialServerUser, TokenPartialUser } from \"../../users\";\nimport { _HexclaveServerAppImpl } from \"../implementations\";\nimport { StackClientApp, StackClientAppConstructorOptions } from \"./client-app\";\n\n\n/** @deprecated Use `HexclaveServerAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackServerAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackClientAppConstructorOptions<HasTokenStore, ProjectId> & {\n secretServerKey?: string,\n};\n\n/** @deprecated Use `HexclaveServerApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackServerApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = (\n & {\n createTeam(data: ServerTeamCreateOptions): Promise<ServerTeam>,\n /**\n * @deprecated use `getUser()` instead\n */\n getServerUser(): Promise<ProjectCurrentServerUser<ProjectId> | null>,\n\n createUser(options: ServerUserCreateOptions): Promise<ServerUser>,\n grantProduct(options: (\n ({ userId: string } | { teamId: string } | { customCustomerId: string }) &\n ({ productId: string } | { product: InlineProduct }) &\n { quantity?: number }\n )): Promise<void>,\n createCheckoutUrl(options: (\n ({ userId: string } | { teamId: string } | { customCustomerId: string }) &\n ({ productId: string } | { product: InlineProduct }) &\n { returnUrl?: string }\n )): Promise<string>,\n\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): ProjectCurrentServerUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): ProjectCurrentServerUser<ProjectId>,\n useUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): ProjectCurrentServerUser<ProjectId>,\n useUser(options?: GetCurrentUserOptions<HasTokenStore>): ProjectCurrentServerUser<ProjectId> | null,\n useUser(id: string): ServerUser | null,\n useUser(options: { apiKey: string, or?: \"return-null\" | \"anonymous\" }): ServerUser | null,\n useUser(options: { from: \"convex\", ctx: GenericQueryCtx<any>, or?: \"return-null\" | \"anonymous\" }): ServerUser | null,\n\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'redirect' }): Promise<ProjectCurrentServerUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'throw' }): Promise<ProjectCurrentServerUser<ProjectId>>,\n getUser(options: GetCurrentUserOptions<HasTokenStore> & { or: 'anonymous' }): Promise<ProjectCurrentServerUser<ProjectId>>,\n getUser(options?: GetCurrentUserOptions<HasTokenStore>): Promise<ProjectCurrentServerUser<ProjectId> | null>,\n getUser(id: string): Promise<ServerUser | null>,\n getUser(options: { apiKey: string, or?: \"return-null\" | \"anonymous\" }): Promise<ServerUser | null>,\n getUser(options: { from: \"convex\", ctx: GenericQueryCtx<any>, or?: \"return-null\" | \"anonymous\" }): Promise<ServerUser | null>,\n\n // note: we don't special-case 'anonymous' here to return non-null, see GetPartialUserOptions for more details\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): Promise<TokenPartialUser | null>,\n getPartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): Promise<SyncedPartialServerUser | TokenPartialUser | null>,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'token' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore> & { from: 'convex' }): TokenPartialUser | null,\n usePartialUser(options: GetCurrentPartialUserOptions<HasTokenStore>): SyncedPartialServerUser | TokenPartialUser | null,\n useTeam(id: string): ServerTeam | null,\n useTeam(options: { apiKey: string }): ServerTeam | null,\n getTeam(id: string): Promise<ServerTeam | null>,\n getTeam(options: { apiKey: string }): Promise<ServerTeam | null>,\n\n\n useUsers(options?: ServerListUsersOptions): ServerUser[] & { nextCursor: string | null }, // THIS_LINE_PLATFORM react-like\n listUsers(options?: ServerListUsersOptions): Promise<ServerUser[] & { nextCursor: string | null }>,\n\n /**\n * Returns every direct (or recursive) team permission grant for every\n * member of the given team in one request. Use this instead of calling\n * `user.listPermissions(team)` per row when rendering a roster — that\n * pattern produces an N+1 over the team-member endpoint.\n */\n listTeamMemberPermissions(teamId: string, options?: { recursive?: boolean }): Promise<{ userId: string, permissionId: string }[]>,\n useTeamMemberPermissions(teamId: string, options?: { recursive?: boolean }): { userId: string, permissionId: string }[],\n\n // TODO this should actually be on ServerUser\n createOAuthProvider(options: {\n userId: string,\n accountId: string,\n providerConfigId: string,\n email: string,\n allowSignIn: boolean,\n allowConnectedAccounts: boolean,\n }): Promise<Result<ServerOAuthProvider, InstanceType<typeof KnownErrors.OAuthProviderAccountIdAlreadyUsedForSignIn>>>,\n\n sendEmail(options: SendEmailOptions): Promise<void>,\n\n getEmailDeliveryStats(): Promise<EmailDeliveryInfo>,\n useEmailDeliveryStats(): EmailDeliveryInfo,\n\n activateEmailCapacityBoost(): Promise<void>,\n }\n & AsyncStoreProperty<\"user\", [id: string], ServerUser | null, false>\n & Omit<AsyncStoreProperty<\"users\", [], ServerUser[], true>, \"listUsers\" | \"useUsers\">\n & AsyncStoreProperty<\"teams\", [options?: ServerListTeamsOptions], ServerTeam[] & { nextCursor: string | null }, true>\n & AsyncStoreProperty<\"dataVaultStore\", [id: string], DataVaultStore, false>\n & AsyncStoreProperty<\n \"item\",\n [{ itemId: string, userId: string } | { itemId: string, teamId: string } | { itemId: string, customCustomerId: string }],\n ServerItem,\n false\n >\n & AsyncStoreProperty<\n \"products\",\n [options: CustomerProductsRequestOptions],\n CustomerProductsList,\n true\n >\n & StackClientApp<HasTokenStore, ProjectId>\n);\n/** @deprecated Use `HexclaveServerAppConstructor` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackServerAppConstructor = {\n new <\n TokenStoreType extends string,\n HasTokenStore extends (TokenStoreType extends {} ? true : boolean),\n ProjectId extends string\n >(options: StackServerAppConstructorOptions<HasTokenStore, ProjectId>): StackServerApp<HasTokenStore, ProjectId>,\n new (options: StackServerAppConstructorOptions<boolean, string>): StackServerApp<boolean, string>,\n};\nexport type HexclaveServerAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackServerAppConstructorOptions<HasTokenStore, ProjectId>;\nexport type HexclaveServerApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = StackServerApp<HasTokenStore, ProjectId>;\nexport type HexclaveServerAppConstructor = StackServerAppConstructor;\nexport const HexclaveServerApp: HexclaveServerAppConstructor = _HexclaveServerAppImpl;\n/** @deprecated Use `HexclaveServerApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport const StackServerApp: StackServerAppConstructor = HexclaveServerApp;\n"],"mappings":";;;;;AAmIA,MAAa,oBAAkDA;;AAE/D,MAAa,iBAA4C"}
|
|
@@ -113,6 +113,10 @@ type ServerListUsersOptionsBase = {
|
|
|
113
113
|
* Free-text search. Matches user ID (exact UUID), display name, and contact channels (e.g. primary email).
|
|
114
114
|
*/
|
|
115
115
|
query?: string;
|
|
116
|
+
/**
|
|
117
|
+
* Exclude users whose primary email domain matches one of these exact domains.
|
|
118
|
+
*/
|
|
119
|
+
excludedEmailDomains?: string[];
|
|
116
120
|
/**
|
|
117
121
|
* Only return users who are members of the given team.
|
|
118
122
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/lib/hexclave-app/teams/index.ts"],"mappings":";;;;;;;;KAaY,iBAAA;EACV,WAAA;EACA,eAAA;AAAA;AAAA,KAGU,8BAAA;EACV,WAAA;EACA,eAAA;AAAA;AAAA,KAGU,yBAAA,GAA4B,iBAAA;EACtC,MAAA,CAAO,MAAA,EAAQ,8BAAA,GAAiC,OAAA;AAAA;AAAA,KAGtC,QAAA;EACV,EAAA;EACA,WAAA,EAAa,iBAAA;AAAA;;;;;;;KASH,kBAAA;EACV,EAAA;EACA,cAAA;EACA,SAAA,EAAW,IAAA;EACX,MAAA,IAAU,OAAA;AAAA;AAfZ;;;AAAA,KAqBY,cAAA,GAAiB,kBAAA;;;;;;AAV7B;;KAmBY,sBAAA;EACV,EAAA;EACA,MAAA;EACA,eAAA;EACA,cAAA;EACA,SAAA,EAAW,IAAA;EApBX;;;;AAMF;EAqBE,MAAA,IAAU,OAAA;AAAA;AAAA,KAGA,IAAA;EACV,EAAA;EACA,WAAA;EACA,eAAA;EACA,cAAA;EACA,sBAAA;EACA,UAAA,CAAW,OAAA;IAAW,KAAA;IAAe,WAAA;EAAA,IAAyB,OAAA;EAC9D,SAAA,IAAa,OAAA,CAAQ,QAAA;EACrB,QAAA,IAAY,QAAA;EACZ,eAAA,IAAmB,OAAA,CAAQ,kBAAA;EAC3B,cAAA,IAAkB,kBAAA;EAClB,MAAA,CAAO,MAAA,EAAQ,iBAAA,GAAoB,OAAA;EACnC,MAAA,IAAU,OAAA;EACV,YAAA,CAAa,OAAA,EAAS,qBAAA,WAAgC,OAAA,CAAQ,mBAAA;AAAA,IAC5D,kBAAA,gBAAkC,UAAA,YAAsB,QAAA;AAAA,KAEhD,iBAAA;EACV,WAAA;EACA,eAAA;EACA,cAAA,GAAiB,YAAA;AAAA;AAAA,iBAEH,uBAAA,CAAwB,OAAA,EAAS,iBAAA,GAAoB,SAAA;AAAA,KAQzD,iBAAA;EACV,WAAA;EACA,eAAA;AAAA;AAAA,iBAEc,uBAAA,CAAwB,OAAA,EAAS,iBAAA,EAAmB,aAAA,WAAwB,SAAA;AAAA,KAShF,uBAAA,GAA0B,iBAAA;AAAA,KAE1B,cAAA,GAAiB,UAAA;EAC3B,WAAA,EAAa,uBAAA;AAAA;AAAA,KAGH,UAAA;EACV,SAAA,EAAW,IAAA;EACX,cAAA;EACA,SAAA,IAAa,OAAA,CAAQ,cAAA;EACrB,QAAA,IAAY,UAAA;EACZ,MAAA,CAAO,MAAA,EAAQ,uBAAA,GAA0B,OAAA;EACzC,MAAA,IAAU,OAAA;EACV,OAAA,CAAQ,MAAA,WAAiB,OAAA;EACzB,UAAA,CAAW,OAAA;IAAW,KAAA;IAAe,WAAA;EAAA,IAAyB,OAAA;EAC9D,UAAA,CAAW,MAAA,WAAiB,OAAA;AAAA,IAC1B,IAAA;AAAA,KAEC,0BAAA;EACH,MAAA;EACA,KAAA;EACA,OAAA;EACA,IAAA;EAvDA;;;EA2DA,KAAA;EA1DkB;;;EA8DlB,MAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/lib/hexclave-app/teams/index.ts"],"mappings":";;;;;;;;KAaY,iBAAA;EACV,WAAA;EACA,eAAA;AAAA;AAAA,KAGU,8BAAA;EACV,WAAA;EACA,eAAA;AAAA;AAAA,KAGU,yBAAA,GAA4B,iBAAA;EACtC,MAAA,CAAO,MAAA,EAAQ,8BAAA,GAAiC,OAAA;AAAA;AAAA,KAGtC,QAAA;EACV,EAAA;EACA,WAAA,EAAa,iBAAA;AAAA;;;;;;;KASH,kBAAA;EACV,EAAA;EACA,cAAA;EACA,SAAA,EAAW,IAAA;EACX,MAAA,IAAU,OAAA;AAAA;AAfZ;;;AAAA,KAqBY,cAAA,GAAiB,kBAAA;;;;;;AAV7B;;KAmBY,sBAAA;EACV,EAAA;EACA,MAAA;EACA,eAAA;EACA,cAAA;EACA,SAAA,EAAW,IAAA;EApBX;;;;AAMF;EAqBE,MAAA,IAAU,OAAA;AAAA;AAAA,KAGA,IAAA;EACV,EAAA;EACA,WAAA;EACA,eAAA;EACA,cAAA;EACA,sBAAA;EACA,UAAA,CAAW,OAAA;IAAW,KAAA;IAAe,WAAA;EAAA,IAAyB,OAAA;EAC9D,SAAA,IAAa,OAAA,CAAQ,QAAA;EACrB,QAAA,IAAY,QAAA;EACZ,eAAA,IAAmB,OAAA,CAAQ,kBAAA;EAC3B,cAAA,IAAkB,kBAAA;EAClB,MAAA,CAAO,MAAA,EAAQ,iBAAA,GAAoB,OAAA;EACnC,MAAA,IAAU,OAAA;EACV,YAAA,CAAa,OAAA,EAAS,qBAAA,WAAgC,OAAA,CAAQ,mBAAA;AAAA,IAC5D,kBAAA,gBAAkC,UAAA,YAAsB,QAAA;AAAA,KAEhD,iBAAA;EACV,WAAA;EACA,eAAA;EACA,cAAA,GAAiB,YAAA;AAAA;AAAA,iBAEH,uBAAA,CAAwB,OAAA,EAAS,iBAAA,GAAoB,SAAA;AAAA,KAQzD,iBAAA;EACV,WAAA;EACA,eAAA;AAAA;AAAA,iBAEc,uBAAA,CAAwB,OAAA,EAAS,iBAAA,EAAmB,aAAA,WAAwB,SAAA;AAAA,KAShF,uBAAA,GAA0B,iBAAA;AAAA,KAE1B,cAAA,GAAiB,UAAA;EAC3B,WAAA,EAAa,uBAAA;AAAA;AAAA,KAGH,UAAA;EACV,SAAA,EAAW,IAAA;EACX,cAAA;EACA,SAAA,IAAa,OAAA,CAAQ,cAAA;EACrB,QAAA,IAAY,UAAA;EACZ,MAAA,CAAO,MAAA,EAAQ,uBAAA,GAA0B,OAAA;EACzC,MAAA,IAAU,OAAA;EACV,OAAA,CAAQ,MAAA,WAAiB,OAAA;EACzB,UAAA,CAAW,OAAA;IAAW,KAAA;IAAe,WAAA;EAAA,IAAyB,OAAA;EAC9D,UAAA,CAAW,MAAA,WAAiB,OAAA;AAAA,IAC1B,IAAA;AAAA,KAEC,0BAAA;EACH,MAAA;EACA,KAAA;EACA,OAAA;EACA,IAAA;EAvDA;;;EA2DA,KAAA;EA1DkB;;;EA8DlB,oBAAA;EA7DmC;;;EAiEnC,MAAA;EA/DsB;;;;EAoEtB,iBAAA;EAnEoC;;;;EAwEpC,gBAAA;AAAA;AAAA,KAGU,sBAAA,GAAyB,0BAAA;EAEjC,aAAA;AAAA;EAzEF;;;;;EAgFE,aAAA;EACA,gBAAA;AAAA;AAAA,KAIQ,sBAAA;EACV,OAAA;EACA,IAAA;EACA,MAAA;EACA,KAAA;EAtF4E;AAQ9E;;EAkFE,KAAA;AAAA;AAAA,KAGU,uBAAA,GAA0B,iBAAA;EACpC,aAAA;AAAA;AAAA,iBAEc,6BAAA,CAA8B,OAAA,EAAS,uBAAA,GAA0B,SAAA;AAAA,KAQrE,uBAAA,GAA0B,iBAAA;EACpC,sBAAA,GAAyB,YAAA;EACzB,cAAA,GAAiB,YAAA;AAAA;AAAA,iBAEH,6BAAA,CAA8B,OAAA,EAAS,uBAAA,GAA0B,SAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/lib/hexclave-app/teams/index.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { TeamsCrud } from \"@hexclave/shared/dist/interface/crud/teams\";\nimport { ReadonlyJson } from \"@hexclave/shared/dist/utils/json\";\n\nimport { ApiKeyCreationOptions, TeamApiKey, TeamApiKeyFirstView } from \"../api-keys\";\nimport { AsyncStoreProperty } from \"../common\";\nimport { Customer } from \"../customers\";\nimport { ServerUser } from \"../users\";\n\n\nexport type TeamMemberProfile = {\n displayName: string | null,\n profileImageUrl: string | null,\n}\n\nexport type TeamMemberProfileUpdateOptions = {\n displayName?: string,\n profileImageUrl?: string | null,\n};\n\nexport type EditableTeamMemberProfile = TeamMemberProfile & {\n update(update: TeamMemberProfileUpdateOptions): Promise<void>,\n}\n\nexport type TeamUser = {\n id: string,\n teamProfile: TeamMemberProfile,\n}\n\n/**\n * A team invitation as seen from the team's perspective (ie. the sender).\n *\n * Returned by `team.listInvitations()`. Contains the recipient email and allows\n * revoking the invitation.\n */\nexport type SentTeamInvitation = {\n id: string,\n recipientEmail: string | null,\n expiresAt: Date,\n revoke(): Promise<void>,\n}\n\n/**\n * @deprecated Use `SentTeamInvitation` instead.\n */\nexport type TeamInvitation = SentTeamInvitation;\n\n/**\n * A team invitation as seen from the invited user's perspective (ie. the receiver).\n *\n * Returned by `user.listTeamInvitations()`. Contains information about teams that have\n * sent invitations to any of the user's verified email addresses, and allows accepting\n * the invitation to join the team.\n */\nexport type ReceivedTeamInvitation = {\n id: string,\n teamId: string,\n teamDisplayName: string,\n recipientEmail: string,\n expiresAt: Date,\n\n /**\n * Accepts the invitation, adding the current user to the team.\n *\n * The user must have a verified email address matching the invitation's recipient email.\n */\n accept(): Promise<void>,\n}\n\nexport type Team = {\n id: string,\n displayName: string,\n profileImageUrl: string | null,\n clientMetadata: any,\n clientReadOnlyMetadata: any,\n inviteUser(options: { email: string, callbackUrl?: string }): Promise<void>,\n listUsers(): Promise<TeamUser[]>,\n useUsers(): TeamUser[], // THIS_LINE_PLATFORM react-like\n listInvitations(): Promise<SentTeamInvitation[]>,\n useInvitations(): SentTeamInvitation[], // THIS_LINE_PLATFORM react-like\n update(update: TeamUpdateOptions): Promise<void>,\n delete(): Promise<void>,\n createApiKey(options: ApiKeyCreationOptions<\"team\">): Promise<TeamApiKeyFirstView>,\n} & AsyncStoreProperty<\"apiKeys\", [], TeamApiKey[], true> & Customer;\n\nexport type TeamUpdateOptions = {\n displayName?: string,\n profileImageUrl?: string | null,\n clientMetadata?: ReadonlyJson,\n};\nexport function teamUpdateOptionsToCrud(options: TeamUpdateOptions): TeamsCrud[\"Client\"][\"Update\"] {\n return {\n display_name: options.displayName,\n profile_image_url: options.profileImageUrl,\n client_metadata: options.clientMetadata,\n };\n}\n\nexport type TeamCreateOptions = {\n displayName: string,\n profileImageUrl?: string,\n}\nexport function teamCreateOptionsToCrud(options: TeamCreateOptions, creatorUserId: string): TeamsCrud[\"Client\"][\"Create\"] {\n return {\n display_name: options.displayName,\n profile_image_url: options.profileImageUrl,\n creator_user_id: creatorUserId,\n };\n}\n\n\nexport type ServerTeamMemberProfile = TeamMemberProfile;\n\nexport type ServerTeamUser = ServerUser & {\n teamProfile: ServerTeamMemberProfile,\n}\n\nexport type ServerTeam = {\n createdAt: Date,\n serverMetadata: any,\n listUsers(): Promise<ServerTeamUser[]>,\n useUsers(): ServerUser[], // THIS_LINE_PLATFORM react-like\n update(update: ServerTeamUpdateOptions): Promise<void>,\n delete(): Promise<void>,\n addUser(userId: string): Promise<void>,\n inviteUser(options: { email: string, callbackUrl?: string }): Promise<void>,\n removeUser(userId: string): Promise<void>,\n} & Team;\n\ntype ServerListUsersOptionsBase = {\n cursor?: string,\n limit?: number,\n orderBy?: 'signedUpAt' | 'lastActiveAt',\n desc?: boolean,\n /**\n * Free-text search. Matches user ID (exact UUID), display name, and contact channels (e.g. primary email).\n */\n query?: string,\n /**\n * Only return users who are members of the given team.\n */\n teamId?: string,\n /**\n * Whether to include restricted users (users who haven't completed onboarding requirements).\n * Defaults to false.\n */\n includeRestricted?: boolean,\n /**\n * Whether to include anonymous users (and restricted users).\n * Defaults to false.\n */\n includeAnonymous?: boolean,\n};\n\nexport type ServerListUsersOptions = ServerListUsersOptionsBase & (\n {\n onlyAnonymous?: false,\n } | {\n /**\n * Whether to return only anonymous users.\n * Requires includeAnonymous=true.\n * Defaults to false.\n */\n onlyAnonymous: true,\n includeAnonymous: true,\n }\n);\n\nexport type ServerListTeamsOptions = {\n orderBy?: 'createdAt',\n desc?: boolean,\n cursor?: string,\n limit?: number,\n /**\n * Free-text search. Matches team ID (exact UUID) and display name.\n */\n query?: string,\n};\n\nexport type ServerTeamCreateOptions = TeamCreateOptions & {\n creatorUserId?: string,\n};\nexport function serverTeamCreateOptionsToCrud(options: ServerTeamCreateOptions): TeamsCrud[\"Server\"][\"Create\"] {\n return {\n display_name: options.displayName,\n profile_image_url: options.profileImageUrl,\n creator_user_id: options.creatorUserId,\n };\n}\n\nexport type ServerTeamUpdateOptions = TeamUpdateOptions & {\n clientReadOnlyMetadata?: ReadonlyJson,\n serverMetadata?: ReadonlyJson,\n};\nexport function serverTeamUpdateOptionsToCrud(options: ServerTeamUpdateOptions): TeamsCrud[\"Server\"][\"Update\"] {\n return {\n display_name: options.displayName,\n profile_image_url: options.profileImageUrl,\n client_metadata: options.clientMetadata,\n client_read_only_metadata: options.clientReadOnlyMetadata,\n server_metadata: options.serverMetadata,\n };\n}\n"],"mappings":";;;AA6FA,SAAgB,wBAAwB,SAA2D;AACjG,QAAO;EACL,cAAc,QAAQ;EACtB,mBAAmB,QAAQ;EAC3B,iBAAiB,QAAQ;EAC1B;;AAOH,SAAgB,wBAAwB,SAA4B,eAAsD;AACxH,QAAO;EACL,cAAc,QAAQ;EACtB,mBAAmB,QAAQ;EAC3B,iBAAiB;EAClB;;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/lib/hexclave-app/teams/index.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { TeamsCrud } from \"@hexclave/shared/dist/interface/crud/teams\";\nimport { ReadonlyJson } from \"@hexclave/shared/dist/utils/json\";\n\nimport { ApiKeyCreationOptions, TeamApiKey, TeamApiKeyFirstView } from \"../api-keys\";\nimport { AsyncStoreProperty } from \"../common\";\nimport { Customer } from \"../customers\";\nimport { ServerUser } from \"../users\";\n\n\nexport type TeamMemberProfile = {\n displayName: string | null,\n profileImageUrl: string | null,\n}\n\nexport type TeamMemberProfileUpdateOptions = {\n displayName?: string,\n profileImageUrl?: string | null,\n};\n\nexport type EditableTeamMemberProfile = TeamMemberProfile & {\n update(update: TeamMemberProfileUpdateOptions): Promise<void>,\n}\n\nexport type TeamUser = {\n id: string,\n teamProfile: TeamMemberProfile,\n}\n\n/**\n * A team invitation as seen from the team's perspective (ie. the sender).\n *\n * Returned by `team.listInvitations()`. Contains the recipient email and allows\n * revoking the invitation.\n */\nexport type SentTeamInvitation = {\n id: string,\n recipientEmail: string | null,\n expiresAt: Date,\n revoke(): Promise<void>,\n}\n\n/**\n * @deprecated Use `SentTeamInvitation` instead.\n */\nexport type TeamInvitation = SentTeamInvitation;\n\n/**\n * A team invitation as seen from the invited user's perspective (ie. the receiver).\n *\n * Returned by `user.listTeamInvitations()`. Contains information about teams that have\n * sent invitations to any of the user's verified email addresses, and allows accepting\n * the invitation to join the team.\n */\nexport type ReceivedTeamInvitation = {\n id: string,\n teamId: string,\n teamDisplayName: string,\n recipientEmail: string,\n expiresAt: Date,\n\n /**\n * Accepts the invitation, adding the current user to the team.\n *\n * The user must have a verified email address matching the invitation's recipient email.\n */\n accept(): Promise<void>,\n}\n\nexport type Team = {\n id: string,\n displayName: string,\n profileImageUrl: string | null,\n clientMetadata: any,\n clientReadOnlyMetadata: any,\n inviteUser(options: { email: string, callbackUrl?: string }): Promise<void>,\n listUsers(): Promise<TeamUser[]>,\n useUsers(): TeamUser[], // THIS_LINE_PLATFORM react-like\n listInvitations(): Promise<SentTeamInvitation[]>,\n useInvitations(): SentTeamInvitation[], // THIS_LINE_PLATFORM react-like\n update(update: TeamUpdateOptions): Promise<void>,\n delete(): Promise<void>,\n createApiKey(options: ApiKeyCreationOptions<\"team\">): Promise<TeamApiKeyFirstView>,\n} & AsyncStoreProperty<\"apiKeys\", [], TeamApiKey[], true> & Customer;\n\nexport type TeamUpdateOptions = {\n displayName?: string,\n profileImageUrl?: string | null,\n clientMetadata?: ReadonlyJson,\n};\nexport function teamUpdateOptionsToCrud(options: TeamUpdateOptions): TeamsCrud[\"Client\"][\"Update\"] {\n return {\n display_name: options.displayName,\n profile_image_url: options.profileImageUrl,\n client_metadata: options.clientMetadata,\n };\n}\n\nexport type TeamCreateOptions = {\n displayName: string,\n profileImageUrl?: string,\n}\nexport function teamCreateOptionsToCrud(options: TeamCreateOptions, creatorUserId: string): TeamsCrud[\"Client\"][\"Create\"] {\n return {\n display_name: options.displayName,\n profile_image_url: options.profileImageUrl,\n creator_user_id: creatorUserId,\n };\n}\n\n\nexport type ServerTeamMemberProfile = TeamMemberProfile;\n\nexport type ServerTeamUser = ServerUser & {\n teamProfile: ServerTeamMemberProfile,\n}\n\nexport type ServerTeam = {\n createdAt: Date,\n serverMetadata: any,\n listUsers(): Promise<ServerTeamUser[]>,\n useUsers(): ServerUser[], // THIS_LINE_PLATFORM react-like\n update(update: ServerTeamUpdateOptions): Promise<void>,\n delete(): Promise<void>,\n addUser(userId: string): Promise<void>,\n inviteUser(options: { email: string, callbackUrl?: string }): Promise<void>,\n removeUser(userId: string): Promise<void>,\n} & Team;\n\ntype ServerListUsersOptionsBase = {\n cursor?: string,\n limit?: number,\n orderBy?: 'signedUpAt' | 'lastActiveAt',\n desc?: boolean,\n /**\n * Free-text search. Matches user ID (exact UUID), display name, and contact channels (e.g. primary email).\n */\n query?: string,\n /**\n * Exclude users whose primary email domain matches one of these exact domains.\n */\n excludedEmailDomains?: string[],\n /**\n * Only return users who are members of the given team.\n */\n teamId?: string,\n /**\n * Whether to include restricted users (users who haven't completed onboarding requirements).\n * Defaults to false.\n */\n includeRestricted?: boolean,\n /**\n * Whether to include anonymous users (and restricted users).\n * Defaults to false.\n */\n includeAnonymous?: boolean,\n};\n\nexport type ServerListUsersOptions = ServerListUsersOptionsBase & (\n {\n onlyAnonymous?: false,\n } | {\n /**\n * Whether to return only anonymous users.\n * Requires includeAnonymous=true.\n * Defaults to false.\n */\n onlyAnonymous: true,\n includeAnonymous: true,\n }\n);\n\nexport type ServerListTeamsOptions = {\n orderBy?: 'createdAt',\n desc?: boolean,\n cursor?: string,\n limit?: number,\n /**\n * Free-text search. Matches team ID (exact UUID) and display name.\n */\n query?: string,\n};\n\nexport type ServerTeamCreateOptions = TeamCreateOptions & {\n creatorUserId?: string,\n};\nexport function serverTeamCreateOptionsToCrud(options: ServerTeamCreateOptions): TeamsCrud[\"Server\"][\"Create\"] {\n return {\n display_name: options.displayName,\n profile_image_url: options.profileImageUrl,\n creator_user_id: options.creatorUserId,\n };\n}\n\nexport type ServerTeamUpdateOptions = TeamUpdateOptions & {\n clientReadOnlyMetadata?: ReadonlyJson,\n serverMetadata?: ReadonlyJson,\n};\nexport function serverTeamUpdateOptionsToCrud(options: ServerTeamUpdateOptions): TeamsCrud[\"Server\"][\"Update\"] {\n return {\n display_name: options.displayName,\n profile_image_url: options.profileImageUrl,\n client_metadata: options.clientMetadata,\n client_read_only_metadata: options.clientReadOnlyMetadata,\n server_metadata: options.serverMetadata,\n };\n}\n"],"mappings":";;;AA6FA,SAAgB,wBAAwB,SAA2D;AACjG,QAAO;EACL,cAAc,QAAQ;EACtB,mBAAmB,QAAQ;EAC3B,iBAAiB,QAAQ;EAC1B;;AAOH,SAAgB,wBAAwB,SAA4B,eAAsD;AACxH,QAAO;EACL,cAAc,QAAQ;EACtB,mBAAmB,QAAQ;EAC3B,iBAAiB;EAClB;;AA+EH,SAAgB,8BAA8B,SAAiE;AAC7G,QAAO;EACL,cAAc,QAAQ;EACtB,mBAAmB,QAAQ;EAC3B,iBAAiB,QAAQ;EAC1B;;AAOH,SAAgB,8BAA8B,SAAiE;AAC7G,QAAO;EACL,cAAc,QAAQ;EACtB,mBAAmB,QAAQ;EAC3B,iBAAiB,QAAQ;EACzB,2BAA2B,QAAQ;EACnC,iBAAiB,QAAQ;EAC1B"}
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
const require_chunk = require('../chunk-BE-pF4vm.js');
|
|
5
|
-
let _hexclave_shared_dist_utils_strings = require("@hexclave/shared/dist/utils/strings");
|
|
6
5
|
let _hexclave_ui = require("@hexclave/ui");
|
|
7
6
|
let react = require("react");
|
|
8
7
|
react = require_chunk.__toESM(react);
|
|
9
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
9
|
let color = require("color");
|
|
11
10
|
color = require_chunk.__toESM(color);
|
|
11
|
+
let _hexclave_shared_dist_utils_strings = require("@hexclave/shared/dist/utils/strings");
|
|
12
12
|
let ___generated_global_css_js = require("../generated/global-css.js");
|
|
13
13
|
let ___utils_browser_script_js = require("../utils/browser-script.js");
|
|
14
14
|
let ___utils_constants_js = require("../utils/constants.js");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_chunk = require('../chunk-BE-pF4vm.js');
|
|
3
|
+
let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
|
|
3
4
|
let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
|
|
4
5
|
let ___in_page_ui_dom_js = require("../in-page-ui/dom.js");
|
|
5
6
|
let ___in_page_ui_base_styles_js = require("../in-page-ui/base-styles.js");
|
|
6
|
-
let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
|
|
7
7
|
let _hexclave_shared_dist_utils_urls = require("@hexclave/shared/dist/utils/urls");
|
|
8
8
|
let ___generated_env_js = require("../generated/env.js");
|
|
9
9
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
|
|
3
3
|
"name": "@hexclave/react",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.32",
|
|
5
5
|
"repository": "https://github.com/hexclave/hexclave",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -74,8 +74,8 @@
|
|
|
74
74
|
"tailwindcss-animate": "^1.0.7",
|
|
75
75
|
"rrweb": "^1.1.3",
|
|
76
76
|
"yup": "^1.7.1",
|
|
77
|
-
"@hexclave/shared": "1.0.
|
|
78
|
-
"@hexclave/ui": "1.0.
|
|
77
|
+
"@hexclave/shared": "1.0.32",
|
|
78
|
+
"@hexclave/ui": "1.0.32"
|
|
79
79
|
},
|
|
80
80
|
"peerDependencies": {
|
|
81
81
|
"@types/react": ">=18.0.0",
|
|
@@ -9,6 +9,7 @@ import React, { act } from "react";
|
|
|
9
9
|
import { createRoot, type Root } from "react-dom/client";
|
|
10
10
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
11
11
|
import type { StackClientApp } from "../lib/hexclave-app/apps/interfaces/client-app";
|
|
12
|
+
import { hexclaveAppInternalsSymbol } from "../lib/hexclave-app/common";
|
|
12
13
|
import { TranslationProviderClient } from "../providers/translation-provider-client";
|
|
13
14
|
import { OAuthCallback } from "./oauth-callback";
|
|
14
15
|
|
|
@@ -44,6 +45,9 @@ function createAppTestDouble(options: {
|
|
|
44
45
|
callOAuthCallback: options.callOAuthCallback,
|
|
45
46
|
redirectToSignIn: vi.fn(async () => {}),
|
|
46
47
|
redirectToHome: vi.fn(async () => {}),
|
|
48
|
+
[hexclaveAppInternalsSymbol]: {
|
|
49
|
+
awaitPendingAuthResolutions: vi.fn(async () => {}),
|
|
50
|
+
},
|
|
47
51
|
};
|
|
48
52
|
|
|
49
53
|
// This test double intentionally implements only the StackClientApp surface
|
|
@@ -13,6 +13,7 @@ import { useEffect, useRef, useState } from "react";
|
|
|
13
13
|
import { useStackApp } from "..";
|
|
14
14
|
import { MaybeFullPage } from "../components/elements/maybe-full-page";
|
|
15
15
|
import { StyledLink } from "../components/link";
|
|
16
|
+
import { hexclaveAppInternalsSymbol } from "../lib/hexclave-app/common";
|
|
16
17
|
import { useTranslation } from "../lib/translations";
|
|
17
18
|
import { ErrorPage } from "./error-page";
|
|
18
19
|
|
|
@@ -27,6 +28,11 @@ export function OAuthCallback({ fullPage }: { fullPage?: boolean }) {
|
|
|
27
28
|
if (called.current) return;
|
|
28
29
|
called.current = true;
|
|
29
30
|
try {
|
|
31
|
+
// The startup handler in StackClientApp's constructor may have already consumed the
|
|
32
|
+
// one-time OAuth params (code + state cookie) via a microtask that fires before this
|
|
33
|
+
// macrotask-scheduled useEffect. Await its completion so we don't race: if it succeeds
|
|
34
|
+
// it will redirect and this page tears down; if it fails we fall through below.
|
|
35
|
+
await app[hexclaveAppInternalsSymbol].awaitPendingAuthResolutions();
|
|
30
36
|
const hasRedirected = await app.callOAuthCallback();
|
|
31
37
|
if (!hasRedirected) {
|
|
32
38
|
await app.redirectToSignIn({ noRedirectBack: true });
|
|
@@ -2644,16 +2644,11 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
|
|
|
2644
2644
|
return clientVersion;
|
|
2645
2645
|
}
|
|
2646
2646
|
|
|
2647
|
-
private _botChallengeSiteKeysWarned = false;
|
|
2648
2647
|
private _getBotChallengeSiteKeys(): { visibleSiteKey: string, invisibleSiteKey: string } | null {
|
|
2649
2648
|
if (!isBrowserLike()) return null;
|
|
2650
2649
|
|
|
2651
2650
|
const visibleSiteKey = envVars.HEXCLAVE_BOT_CHALLENGE_SITE_KEY;
|
|
2652
2651
|
if (!visibleSiteKey) {
|
|
2653
|
-
if (!this._botChallengeSiteKeysWarned) {
|
|
2654
|
-
this._botChallengeSiteKeysWarned = true;
|
|
2655
|
-
console.warn("[stack-auth] HEXCLAVE_BOT_CHALLENGE_SITE_KEY is not set — bot challenge fraud protection is disabled. Set the env variable to enable it.");
|
|
2656
|
-
}
|
|
2657
2652
|
return null;
|
|
2658
2653
|
}
|
|
2659
2654
|
|
|
@@ -4040,6 +4035,9 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
|
|
|
4040
4035
|
signInWithTokens: async (tokens: { accessToken: string, refreshToken: string }) => {
|
|
4041
4036
|
await this._signInToAccountWithTokens(tokens);
|
|
4042
4037
|
},
|
|
4038
|
+
awaitPendingAuthResolutions: async () => {
|
|
4039
|
+
await this._awaitPendingAuthResolutions();
|
|
4040
|
+
},
|
|
4043
4041
|
};
|
|
4044
4042
|
};
|
|
4045
4043
|
|