@hexclave/tanstack-start 1.0.55 → 1.0.57
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/{admin-app-impl-CFBIgDHN.d.ts → admin-app-impl-D94uBe2u.d.ts} +4 -4
- package/dist/{admin-app-impl-CFBIgDHN.d.ts.map → admin-app-impl-D94uBe2u.d.ts.map} +1 -1
- package/dist/clickmap/clickmap-core.d.ts +1 -1
- package/dist/clickmap/index.d.ts +1 -1
- package/dist/{client-app-CqiogvCi.d.ts → client-app-DI4pr0KJ.d.ts} +2 -1
- package/dist/{client-app-CqiogvCi.d.ts.map → client-app-DI4pr0KJ.d.ts.map} +1 -1
- package/dist/components/api-key-dialogs.d.ts +1 -1
- package/dist/components/selected-team-switcher.d.ts +1 -1
- package/dist/components/team-icon.d.ts +1 -1
- package/dist/components/team-switcher.d.ts +1 -1
- package/dist/components-page/account-settings/active-sessions/active-sessions-page.js +1 -1
- package/dist/components-page/account-settings/api-keys/api-keys-page.js +2 -2
- 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/passkey-section.js +1 -1
- package/dist/components-page/account-settings/email-and-auth/password-section.js +2 -2
- package/dist/components-page/account-settings/payments/payments-page.d.ts +1 -1
- package/dist/components-page/account-settings/payments/payments-panel.js +1 -1
- package/dist/components-page/account-settings/teams/leave-team-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-api-keys-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-api-keys-section.js +2 -2
- package/dist/components-page/account-settings/teams/team-creation-page.js +1 -1
- package/dist/components-page/account-settings/teams/team-display-name-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-member-invitation-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-member-invitation-section.js +1 -1
- package/dist/components-page/account-settings/teams/team-member-list-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-page.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-profile-image-section.d.ts +1 -1
- package/dist/components-page/account-settings/teams/team-profile-user-section.d.ts +1 -1
- package/dist/components-page/hexclave-handler-client.d.ts +1 -1
- package/dist/components-page/hexclave-handler.d.ts +1 -1
- package/dist/dev-tool/dev-tool-core.d.ts +1 -1
- package/dist/dev-tool/index.d.ts +1 -1
- package/dist/dev-tool/index.d.ts.map +1 -1
- package/dist/dev-tool/index.js +18 -1
- package/dist/dev-tool/index.js.map +1 -1
- package/dist/dev-tool/index.test.d.ts +1 -0
- package/dist/dev-tool/index.test.js +40 -0
- package/dist/dev-tool/index.test.js.map +1 -0
- package/dist/esm/components/api-key-dialogs.d.ts +1 -1
- package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js +1 -1
- package/dist/esm/components-page/account-settings/api-keys/api-keys-page.js +2 -2
- 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/passkey-section.js +1 -1
- package/dist/esm/components-page/account-settings/email-and-auth/password-section.js +2 -2
- package/dist/esm/components-page/account-settings/payments/payments-panel.js +1 -1
- package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js +2 -2
- 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/dev-tool/index.d.ts.map +1 -1
- package/dist/esm/dev-tool/index.js +18 -1
- package/dist/esm/dev-tool/index.js.map +1 -1
- package/dist/esm/dev-tool/index.test.d.ts +1 -0
- package/dist/esm/dev-tool/index.test.js +41 -0
- package/dist/esm/dev-tool/index.test.js.map +1 -0
- package/dist/esm/generated/quetzal-translations.d.ts +2 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +2 -2
- 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.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +1 -0
- 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.test.js +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.test.js +1 -1
- package/dist/esm/lib/hexclave-app/projects/index.d.ts +1 -0
- package/dist/esm/lib/hexclave-app/projects/index.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/projects/index.js.map +1 -1
- package/dist/esm/pushed-config-error-overlay/index.test.js +1 -1
- package/dist/generated/quetzal-translations.d.ts +1 -1
- package/dist/{hexclave-provider-CRjTv5L1.d.ts → hexclave-provider-Cbzn8XDz.d.ts} +3 -3
- package/dist/{hexclave-provider-CRjTv5L1.d.ts.map → hexclave-provider-Cbzn8XDz.d.ts.map} +1 -1
- package/dist/{hooks-FZEGOxTp.d.ts → hooks-BP37GS_H.d.ts} +2 -2
- package/dist/{hooks-FZEGOxTp.d.ts.map → hooks-BP37GS_H.d.ts.map} +1 -1
- package/dist/{index-DHE12H8g.d.ts → index-CDfsi7Kx.d.ts} +2 -2
- package/dist/{index-DHE12H8g.d.ts.map → index-CDfsi7Kx.d.ts.map} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +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.js +1 -0
- 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.test.js +1 -1
- package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/session-replay.test.js +1 -1
- package/dist/lib/hexclave-app/apps/index.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
- package/dist/lib/hexclave-app/index.d.ts +1 -1
- package/dist/lib/hexclave-app/projects/index.d.ts +1 -1
- package/dist/lib/hexclave-app/projects/index.js.map +1 -1
- package/dist/lib/hexclave-app/teams/index.d.ts +1 -1
- package/dist/lib/hexclave-app/users/index.d.ts +1 -1
- package/dist/lib/hooks.d.ts +1 -1
- package/dist/providers/hexclave-context.d.ts +1 -1
- package/dist/providers/hexclave-provider-client.d.ts +1 -1
- package/dist/providers/hexclave-provider.d.ts +1 -1
- package/dist/providers/translation-provider.d.ts +1 -1
- package/dist/pushed-config-error-overlay/index.d.ts +1 -1
- package/dist/pushed-config-error-overlay/index.test.js +1 -1
- package/dist/{quetzal-translations-CK45_4Dm.d.ts → quetzal-translations-XeH3zQ9l.d.ts} +3 -3
- package/dist/{quetzal-translations-CK45_4Dm.d.ts.map → quetzal-translations-XeH3zQ9l.d.ts.map} +1 -1
- package/dist/{translation-provider-DQ3BJepJ.d.ts → translation-provider-WOaZXqAz.d.ts} +2 -2
- package/dist/{translation-provider-DQ3BJepJ.d.ts.map → translation-provider-WOaZXqAz.d.ts.map} +1 -1
- package/package.json +3 -3
- package/src/dev-tool/index.test.ts +58 -0
- package/src/dev-tool/index.ts +27 -1
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +1 -0
- package/src/lib/hexclave-app/projects/index.ts +1 -0
package/dist/dev-tool/index.js
CHANGED
|
@@ -15,11 +15,13 @@ function getOverride() {
|
|
|
15
15
|
return null;
|
|
16
16
|
}
|
|
17
17
|
let activeDevToolOption = void 0;
|
|
18
|
+
let activeProjectIsDevelopmentEnvironment = false;
|
|
18
19
|
function shouldShow() {
|
|
19
20
|
const override = getOverride();
|
|
20
21
|
if (override !== null) return override;
|
|
21
22
|
if (!(0, ___in_page_ui_dom_js.canMountIntoDom)()) return false;
|
|
22
23
|
if (activeDevToolOption === true) return true;
|
|
24
|
+
if (activeProjectIsDevelopmentEnvironment) return true;
|
|
23
25
|
const nodeEnv = ___generated_env_js.envVars.NODE_ENV;
|
|
24
26
|
if (nodeEnv !== void 0) return nodeEnv === "development";
|
|
25
27
|
try {
|
|
@@ -74,10 +76,25 @@ function tryMount() {
|
|
|
74
76
|
function mountDevTool(app, devToolOption) {
|
|
75
77
|
activeApp = app;
|
|
76
78
|
activeDevToolOption = devToolOption === false ? void 0 : devToolOption ?? void 0;
|
|
79
|
+
activeProjectIsDevelopmentEnvironment = false;
|
|
77
80
|
tryMount();
|
|
81
|
+
queueMicrotask(() => {
|
|
82
|
+
(0, _hexclave_shared_dist_utils_promises.runAsynchronously)(async () => {
|
|
83
|
+
const project = await app.getProject();
|
|
84
|
+
if (activeApp !== app) return;
|
|
85
|
+
activeProjectIsDevelopmentEnvironment = project.isDevelopmentEnvironment;
|
|
86
|
+
if (activeProjectIsDevelopmentEnvironment && activeCleanup === null) tryMount();
|
|
87
|
+
}, {
|
|
88
|
+
noErrorLogging: true,
|
|
89
|
+
onError: (error) => {
|
|
90
|
+
(0, _hexclave_shared_dist_utils_errors.captureError)("dev-tool-project-detection", error);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
78
94
|
const myCleanup = activeCleanup;
|
|
79
95
|
return () => {
|
|
80
96
|
activeApp = null;
|
|
97
|
+
activeProjectIsDevelopmentEnvironment = false;
|
|
81
98
|
if (activeCleanup === myCleanup && myCleanup != null) {
|
|
82
99
|
activeCleanup = null;
|
|
83
100
|
myCleanup();
|
|
@@ -111,7 +128,7 @@ if (typeof window !== "undefined") window.HexclaveDevTool = window.HexclaveDevTo
|
|
|
111
128
|
activeCleanup();
|
|
112
129
|
activeCleanup = null;
|
|
113
130
|
}
|
|
114
|
-
console.log("[Stack DevTool] Reset to default (auto-detect based on NODE_ENV or localhost/file: origin).");
|
|
131
|
+
console.log("[Stack DevTool] Reset to default (auto-detect based on project, NODE_ENV, or localhost/file: origin).");
|
|
115
132
|
}
|
|
116
133
|
};
|
|
117
134
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["envVars"],"sources":["../../src/dev-tool/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//===========================================\n\nimport type { StackClientApp } from \"../lib/hexclave-app\";\nimport { captureError } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { isLocalhost } from \"@hexclave/shared/dist/utils/urls\";\nimport { canMountIntoDom } from \"../in-page-ui/dom\";\nimport { envVars } from \"../generated/env\";\nimport type { createDevTool as CreateDevToolFn } from \"./dev-tool-core\";\n\n// Hexclave rebrand: UI-only local pref — straight rename (one-time reset is harmless)\nconst OVERRIDE_KEY = '__hexclave-dev-tool-override';\n\nfunction getOverride(): boolean | null {\n try {\n const val = localStorage.getItem(OVERRIDE_KEY);\n if (val === 'true') return true;\n if (val === 'false') return false;\n } catch {}\n return null;\n}\n\nlet activeDevToolOption: true | \"auto\" | undefined = undefined;\n\nfunction shouldShow(): boolean {\n const override = getOverride();\n if (override !== null) return override;\n if (!canMountIntoDom()) return false;\n\n // If devTool was explicitly set to true, always show\n if (activeDevToolOption === true) return true;\n\n // \"auto\" behavior (the default):\n const nodeEnv = envVars.NODE_ENV;\n if (nodeEnv !== undefined) {\n // NODE_ENV is available (bundler/process env exists) — only show in development\n return nodeEnv === \"development\";\n }\n\n // NODE_ENV not found (no process.env/import.meta) — show on localhost or file: protocol\n try {\n const url = new URL(window.location.href);\n if (url.protocol === \"file:\") return true;\n } catch {}\n return isLocalhost(window.location.href);\n}\n\nlet activeCleanup: (() => void) | null = null;\nlet activeApp: StackClientApp<true> | null = null;\nlet mountGeneration = 0;\n\nlet createDevToolPromise: Promise<typeof CreateDevToolFn> | null = null;\nfunction loadCreateDevTool(): Promise<typeof CreateDevToolFn> {\n if (!createDevToolPromise) {\n createDevToolPromise = import(\"./dev-tool-core\").then(m => m.createDevTool).catch((err) => {\n createDevToolPromise = null;\n throw err;\n });\n }\n return createDevToolPromise;\n}\n\nfunction tryMount() {\n if (activeCleanup) {\n activeCleanup();\n activeCleanup = null;\n }\n\n if (!shouldShow() || !activeApp || !canMountIntoDom()) return;\n\n const generation = ++mountGeneration;\n const app = activeApp;\n\n runAsynchronously(async () => {\n const createDevTool = await loadCreateDevTool();\n if (generation !== mountGeneration) return;\n if (!shouldShow() || activeApp !== app || !canMountIntoDom()) return;\n activeCleanup = createDevTool(app);\n }, {\n noErrorLogging: true,\n onError: (error) => {\n captureError(\"dev-tool-mount\", error);\n },\n });\n}\n\n/**\n * Mounts the Hexclave dev tool on the page.\n *\n * Visibility is determined by the `devTool` option:\n * - `true`: always show\n * - `false`: never show (caller gates this — mountDevTool won't be called)\n * - `\"auto\"` / `undefined`: show based on NODE_ENV or localhost/file: heuristics\n *\n * Console commands (also work in production):\n * HexclaveDevTool.enable() — force-show the dev tool\n * HexclaveDevTool.disable() — force-hide the dev tool\n * HexclaveDevTool.reset() — revert to auto behavior\n */\nexport function mountDevTool(app: StackClientApp<true>, devToolOption?: boolean | \"auto\"): () => void {\n activeApp = app;\n activeDevToolOption = devToolOption === false ? undefined : devToolOption ?? undefined;\n tryMount();\n\n // Capture the cleanup created by THIS specific mount call so that React\n // StrictMode's double-invoke doesn't let the first effect's cleanup tear\n // down the second mount (which would cause the tool to disappear silently).\n const myCleanup = activeCleanup;\n\n return () => {\n activeApp = null;\n if (activeCleanup === myCleanup && myCleanup != null) {\n activeCleanup = null;\n myCleanup();\n }\n };\n}\n\n// Expose console commands: HexclaveDevTool.enable() / .disable() / .reset()\nif (typeof window !== 'undefined') {\n // Hexclave rebrand: expose under both the legacy and new global names.\n (window as any).HexclaveDevTool = (window as any).HexclaveDevTool = {\n enable() {\n try {\n localStorage.setItem(OVERRIDE_KEY, 'true');\n } catch {}\n tryMount();\n console.log('[Stack DevTool] Enabled. Refresh if the panel does not appear.');\n },\n disable() {\n try {\n localStorage.setItem(OVERRIDE_KEY, 'false');\n } catch {}\n if (activeCleanup) {\n activeCleanup();\n activeCleanup = null;\n }\n console.log('[Stack DevTool] Disabled.');\n },\n reset() {\n try {\n localStorage.removeItem(OVERRIDE_KEY);\n } catch {}\n if (shouldShow()) {\n tryMount();\n } else if (activeCleanup) {\n activeCleanup();\n activeCleanup = null;\n }\n console.log('[Stack DevTool] Reset to default (auto-detect based on NODE_ENV or localhost/file: origin).');\n },\n };\n}\n\n"],"mappings":";;;;;;;AAcA,MAAM,eAAe;AAErB,SAAS,cAA8B;CACrC,IAAI;EACF,MAAM,MAAM,aAAa,QAAQ,YAAY;EAC7C,IAAI,QAAQ,QAAQ,OAAO;EAC3B,IAAI,QAAQ,SAAS,OAAO;CAC9B,QAAQ,CAAC;CACT,OAAO;AACT;AAEA,IAAI,sBAAiD,KAAA;
|
|
1
|
+
{"version":3,"file":"index.js","names":["envVars"],"sources":["../../src/dev-tool/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//===========================================\n\nimport type { StackClientApp } from \"../lib/hexclave-app\";\nimport { captureError } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { isLocalhost } from \"@hexclave/shared/dist/utils/urls\";\nimport { canMountIntoDom } from \"../in-page-ui/dom\";\nimport { envVars } from \"../generated/env\";\nimport type { createDevTool as CreateDevToolFn } from \"./dev-tool-core\";\n\n// Hexclave rebrand: UI-only local pref — straight rename (one-time reset is harmless)\nconst OVERRIDE_KEY = '__hexclave-dev-tool-override';\n\nfunction getOverride(): boolean | null {\n try {\n const val = localStorage.getItem(OVERRIDE_KEY);\n if (val === 'true') return true;\n if (val === 'false') return false;\n } catch {}\n return null;\n}\n\nlet activeDevToolOption: true | \"auto\" | undefined = undefined;\nlet activeProjectIsDevelopmentEnvironment = false;\n\nfunction shouldShow(): boolean {\n const override = getOverride();\n if (override !== null) return override;\n if (!canMountIntoDom()) return false;\n\n // If devTool was explicitly set to true, always show\n if (activeDevToolOption === true) return true;\n\n // Development environment projects should expose the tool even when the\n // consuming app itself was built or hosted as production.\n if (activeProjectIsDevelopmentEnvironment) return true;\n\n // \"auto\" behavior (the default):\n const nodeEnv = envVars.NODE_ENV;\n if (nodeEnv !== undefined) {\n // NODE_ENV is available (bundler/process env exists) — only show in development\n return nodeEnv === \"development\";\n }\n\n // NODE_ENV not found (no process.env/import.meta) — show on localhost or file: protocol\n try {\n const url = new URL(window.location.href);\n if (url.protocol === \"file:\") return true;\n } catch {}\n return isLocalhost(window.location.href);\n}\n\nlet activeCleanup: (() => void) | null = null;\nlet activeApp: StackClientApp<true> | null = null;\nlet mountGeneration = 0;\n\nlet createDevToolPromise: Promise<typeof CreateDevToolFn> | null = null;\nfunction loadCreateDevTool(): Promise<typeof CreateDevToolFn> {\n if (!createDevToolPromise) {\n createDevToolPromise = import(\"./dev-tool-core\").then(m => m.createDevTool).catch((err) => {\n createDevToolPromise = null;\n throw err;\n });\n }\n return createDevToolPromise;\n}\n\nfunction tryMount() {\n if (activeCleanup) {\n activeCleanup();\n activeCleanup = null;\n }\n\n if (!shouldShow() || !activeApp || !canMountIntoDom()) return;\n\n const generation = ++mountGeneration;\n const app = activeApp;\n\n runAsynchronously(async () => {\n const createDevTool = await loadCreateDevTool();\n if (generation !== mountGeneration) return;\n if (!shouldShow() || activeApp !== app || !canMountIntoDom()) return;\n activeCleanup = createDevTool(app);\n }, {\n noErrorLogging: true,\n onError: (error) => {\n captureError(\"dev-tool-mount\", error);\n },\n });\n}\n\n/**\n * Mounts the Hexclave dev tool on the page.\n *\n * Visibility is determined by the `devTool` option:\n * - `true`: always show\n * - `false`: never show (caller gates this — mountDevTool won't be called)\n * - `\"auto\"` / `undefined`: show based on NODE_ENV or localhost/file: heuristics\n *\n * Console commands (also work in production):\n * HexclaveDevTool.enable() — force-show the dev tool\n * HexclaveDevTool.disable() — force-hide the dev tool\n * HexclaveDevTool.reset() — revert to auto behavior\n */\nexport function mountDevTool(app: StackClientApp<true>, devToolOption?: boolean | \"auto\"): () => void {\n activeApp = app;\n activeDevToolOption = devToolOption === false ? undefined : devToolOption ?? undefined;\n activeProjectIsDevelopmentEnvironment = false;\n tryMount();\n\n // The project endpoint is also the source of config warnings, so this uses\n // the backend's development-environment flag instead of inferring it from\n // the SDK's build or the current page's origin.\n queueMicrotask(() => {\n runAsynchronously(async () => {\n const project = await app.getProject();\n if (activeApp !== app) return;\n activeProjectIsDevelopmentEnvironment = project.isDevelopmentEnvironment;\n if (activeProjectIsDevelopmentEnvironment && activeCleanup === null) {\n tryMount();\n }\n }, {\n noErrorLogging: true,\n onError: (error) => {\n captureError(\"dev-tool-project-detection\", error);\n },\n });\n });\n\n // Capture the cleanup created by THIS specific mount call so that React\n // StrictMode's double-invoke doesn't let the first effect's cleanup tear\n // down the second mount (which would cause the tool to disappear silently).\n const myCleanup = activeCleanup;\n\n return () => {\n activeApp = null;\n activeProjectIsDevelopmentEnvironment = false;\n if (activeCleanup === myCleanup && myCleanup != null) {\n activeCleanup = null;\n myCleanup();\n }\n };\n}\n\n// Expose console commands: HexclaveDevTool.enable() / .disable() / .reset()\nif (typeof window !== 'undefined') {\n // Hexclave rebrand: expose under both the legacy and new global names.\n (window as any).HexclaveDevTool = (window as any).HexclaveDevTool = {\n enable() {\n try {\n localStorage.setItem(OVERRIDE_KEY, 'true');\n } catch {}\n tryMount();\n console.log('[Stack DevTool] Enabled. Refresh if the panel does not appear.');\n },\n disable() {\n try {\n localStorage.setItem(OVERRIDE_KEY, 'false');\n } catch {}\n if (activeCleanup) {\n activeCleanup();\n activeCleanup = null;\n }\n console.log('[Stack DevTool] Disabled.');\n },\n reset() {\n try {\n localStorage.removeItem(OVERRIDE_KEY);\n } catch {}\n if (shouldShow()) {\n tryMount();\n } else if (activeCleanup) {\n activeCleanup();\n activeCleanup = null;\n }\n console.log('[Stack DevTool] Reset to default (auto-detect based on project, NODE_ENV, or localhost/file: origin).');\n },\n };\n}\n\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
let vitest = require("vitest");
|
|
2
|
+
let ___lib_hexclave_app_index_js = require("../lib/hexclave-app/index.js");
|
|
3
|
+
let __dev_tool_core_js = require("./dev-tool-core.js");
|
|
4
|
+
let __index_js = require("./index.js");
|
|
5
|
+
//#region src/dev-tool/index.test.ts
|
|
6
|
+
vitest.vi.mock("./dev-tool-core", () => ({ createDevTool: vitest.vi.fn(() => () => {}) }));
|
|
7
|
+
(0, vitest.describe)("dev tool visibility", () => {
|
|
8
|
+
(0, vitest.afterEach)(() => {
|
|
9
|
+
vitest.vi.unstubAllEnvs();
|
|
10
|
+
vitest.vi.unstubAllGlobals();
|
|
11
|
+
vitest.vi.clearAllMocks();
|
|
12
|
+
});
|
|
13
|
+
(0, vitest.it)("shows for a development environment project in a production-hosted app", async () => {
|
|
14
|
+
const app = new ___lib_hexclave_app_index_js.StackClientApp({
|
|
15
|
+
baseUrl: "https://api.example.com",
|
|
16
|
+
projectId: "00000000-0000-4000-8000-000000000000",
|
|
17
|
+
publishableClientKey: "stack-pk-test",
|
|
18
|
+
tokenStore: "memory",
|
|
19
|
+
redirectMethod: "none",
|
|
20
|
+
devTool: false
|
|
21
|
+
});
|
|
22
|
+
const getProject = vitest.vi.fn(async () => ({ isDevelopmentEnvironment: true }));
|
|
23
|
+
Reflect.set(app, "getProject", getProject);
|
|
24
|
+
vitest.vi.stubEnv("NODE_ENV", "production");
|
|
25
|
+
vitest.vi.stubGlobal("window", { location: { href: "https://example.com" } });
|
|
26
|
+
vitest.vi.stubGlobal("document", {
|
|
27
|
+
body: { appendChild: () => {} },
|
|
28
|
+
createElement: () => ({})
|
|
29
|
+
});
|
|
30
|
+
vitest.vi.stubGlobal("localStorage", { getItem: () => null });
|
|
31
|
+
(0, __index_js.mountDevTool)(app);
|
|
32
|
+
await vitest.vi.waitFor(() => {
|
|
33
|
+
(0, vitest.expect)(getProject).toHaveBeenCalledOnce();
|
|
34
|
+
(0, vitest.expect)(__dev_tool_core_js.createDevTool).toHaveBeenCalledOnce();
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
//#endregion
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","names":["vi","StackClientApp","createDevTool"],"sources":["../../src/dev-tool/index.test.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 { afterEach, describe, expect, it, vi } from \"vitest\";\nimport { StackClientApp } from \"../lib/hexclave-app\";\nimport { createDevTool } from \"./dev-tool-core\";\nimport { mountDevTool } from \".\";\n\nvi.mock(\"./dev-tool-core\", () => ({\n createDevTool: vi.fn(() => () => {}),\n}));\n\ndescribe(\"dev tool visibility\", () => {\n afterEach(() => {\n vi.unstubAllEnvs();\n vi.unstubAllGlobals();\n vi.clearAllMocks();\n });\n\n it(\"shows for a development environment project in a production-hosted app\", async () => {\n const app = new StackClientApp({\n baseUrl: \"https://api.example.com\",\n projectId: \"00000000-0000-4000-8000-000000000000\",\n publishableClientKey: \"stack-pk-test\",\n tokenStore: \"memory\",\n redirectMethod: \"none\",\n devTool: false,\n });\n const getProject = vi.fn(async () => ({\n isDevelopmentEnvironment: true,\n }));\n Reflect.set(app, \"getProject\", getProject);\n\n vi.stubEnv(\"NODE_ENV\", \"production\");\n vi.stubGlobal(\"window\", {\n location: {\n href: \"https://example.com\",\n },\n });\n vi.stubGlobal(\"document\", {\n body: {\n appendChild: () => {},\n },\n createElement: () => ({}),\n });\n vi.stubGlobal(\"localStorage\", {\n getItem: () => null,\n });\n\n mountDevTool(app);\n\n await vi.waitFor(() => {\n expect(getProject).toHaveBeenCalledOnce();\n expect(createDevTool).toHaveBeenCalledOnce();\n });\n });\n});\n"],"mappings":";;;;;AASAA,OAAAA,GAAG,KAAK,0BAA0B,EAChC,eAAeA,OAAAA,GAAG,eAAe,CAAC,CAAC,EACrC,EAAE;qBAEO,6BAA6B;CACpC,CAAA,GAAA,OAAA,UAAA,OAAgB;EACd,OAAA,GAAG,cAAc;EACjB,OAAA,GAAG,iBAAiB;EACpB,OAAA,GAAG,cAAc;CACnB,CAAC;CAED,CAAA,GAAA,OAAA,GAAA,CAAG,0EAA0E,YAAY;EACvF,MAAM,MAAM,IAAIC,6BAAAA,eAAe;GAC7B,SAAS;GACT,WAAW;GACX,sBAAsB;GACtB,YAAY;GACZ,gBAAgB;GAChB,SAAS;EACX,CAAC;EACD,MAAM,aAAaD,OAAAA,GAAG,GAAG,aAAa,EACpC,0BAA0B,KAC5B,EAAE;EACF,QAAQ,IAAI,KAAK,cAAc,UAAU;EAEzC,OAAA,GAAG,QAAQ,YAAY,YAAY;EACnC,OAAA,GAAG,WAAW,UAAU,EACtB,UAAU,EACR,MAAM,sBACR,EACF,CAAC;EACD,OAAA,GAAG,WAAW,YAAY;GACxB,MAAM,EACJ,mBAAmB,CAAC,EACtB;GACA,sBAAsB,CAAC;EACzB,CAAC;EACD,OAAA,GAAG,WAAW,gBAAgB,EAC5B,eAAe,KACjB,CAAC;EAED,CAAA,GAAA,WAAA,aAAA,CAAa,GAAG;EAEhB,MAAMA,OAAAA,GAAG,cAAc;GACrB,CAAA,GAAA,OAAA,OAAA,CAAO,UAAU,CAAC,CAAC,qBAAqB;GACxC,CAAA,GAAA,OAAA,OAAA,CAAOE,mBAAAA,aAAa,CAAC,CAAC,qBAAqB;EAC7C,CAAC;CACH,CAAC;AACH,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { ApiKey, ApiKeyCreationOptions, ApiKeyType } from "../lib/hexclave-app/a
|
|
|
3
3
|
//#region src/components/api-key-dialogs.d.ts
|
|
4
4
|
declare const neverInMs: number;
|
|
5
5
|
declare const expiresInOptions: {
|
|
6
|
-
readonly [x: number]: "
|
|
6
|
+
readonly [x: number]: "1 day" | "7 days" | "30 days" | "90 days" | "1 year" | "Never";
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
9
|
* Dialog for creating a new API key
|
|
@@ -3,10 +3,10 @@ import { captureError } from "@hexclave/shared/dist/utils/errors";
|
|
|
3
3
|
import { ActionCell, Badge, Button, Skeleton, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from "@hexclave/ui";
|
|
4
4
|
import { useEffect, useState } from "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { fromNow } from "@hexclave/shared/dist/utils/dates";
|
|
6
7
|
import { useUser } from "../../../lib/hooks.js";
|
|
7
8
|
import { useTranslation } from "../../../lib/translations.js";
|
|
8
9
|
import { PageLayout } from "../page-layout.js";
|
|
9
|
-
import { fromNow } from "@hexclave/shared/dist/utils/dates";
|
|
10
10
|
//#region src/components-page/account-settings/active-sessions/active-sessions-page.tsx
|
|
11
11
|
function ActiveSessionsPage(props) {
|
|
12
12
|
const { t } = useTranslation();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Button } from "@hexclave/ui";
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
-
import { CreateApiKeyDialog, ShowApiKeyDialog } from "../../../components/api-key-dialogs.js";
|
|
5
|
-
import { ApiKeyTable } from "../../../components/api-key-table.js";
|
|
6
4
|
import { useUser } from "../../../lib/hooks.js";
|
|
7
5
|
import { useTranslation } from "../../../lib/translations.js";
|
|
8
6
|
import { PageLayout } from "../page-layout.js";
|
|
7
|
+
import { CreateApiKeyDialog, ShowApiKeyDialog } from "../../../components/api-key-dialogs.js";
|
|
8
|
+
import { ApiKeyTable } from "../../../components/api-key-table.js";
|
|
9
9
|
//#region src/components-page/account-settings/api-keys/api-keys-page.tsx
|
|
10
10
|
function ApiKeysPage(props) {
|
|
11
11
|
const { t } = useTranslation();
|
|
@@ -7,8 +7,8 @@ import { useForm } from "react-hook-form";
|
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { useUser } from "../../../lib/hooks.js";
|
|
9
9
|
import { useTranslation } from "../../../lib/translations.js";
|
|
10
|
-
import { FormWarningText } from "../../../components/elements/form-warning.js";
|
|
11
10
|
import { KnownErrors } from "@hexclave/shared/dist/known-errors";
|
|
11
|
+
import { FormWarningText } from "../../../components/elements/form-warning.js";
|
|
12
12
|
//#region src/components-page/account-settings/email-and-auth/emails-section.tsx
|
|
13
13
|
function EmailsSection(props) {
|
|
14
14
|
const { t } = useTranslation();
|
|
@@ -5,11 +5,11 @@ import { useEffect, useState } from "react";
|
|
|
5
5
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { useStackApp, useUser } from "../../../lib/hooks.js";
|
|
7
7
|
import { useTranslation } from "../../../lib/translations.js";
|
|
8
|
-
import { Section } from "../section.js";
|
|
9
8
|
import { createTOTPKeyURI, verifyTOTP } from "@oslojs/otp";
|
|
10
9
|
import { useAsyncCallback } from "@hexclave/shared/dist/hooks/use-async-callback";
|
|
11
10
|
import { generateRandomValues } from "@hexclave/shared/dist/utils/crypto";
|
|
12
11
|
import * as QRCode from "qrcode";
|
|
12
|
+
import { Section } from "../section.js";
|
|
13
13
|
//#region src/components-page/account-settings/email-and-auth/mfa-section.tsx
|
|
14
14
|
function MfaSection(props) {
|
|
15
15
|
const { t } = useTranslation();
|
|
@@ -3,8 +3,8 @@ import { useState } from "react";
|
|
|
3
3
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
import { useUser } from "../../../lib/hooks.js";
|
|
5
5
|
import { useTranslation } from "../../../lib/translations.js";
|
|
6
|
-
import { useStackApp as useStackApp$1 } from "../../../index.js";
|
|
7
6
|
import { Section } from "../section.js";
|
|
7
|
+
import { useStackApp as useStackApp$1 } from "../../../index.js";
|
|
8
8
|
//#region src/components-page/account-settings/email-and-auth/passkey-section.tsx
|
|
9
9
|
function PasskeySection(props) {
|
|
10
10
|
const { t } = useTranslation();
|
|
@@ -9,9 +9,9 @@ import { getPasswordError } from "@hexclave/shared/dist/helpers/password";
|
|
|
9
9
|
import * as yup from "yup";
|
|
10
10
|
import { useUser } from "../../../lib/hooks.js";
|
|
11
11
|
import { useTranslation } from "../../../lib/translations.js";
|
|
12
|
-
import { useStackApp as useStackApp$1 } from "../../../index.js";
|
|
13
|
-
import { Section } from "../section.js";
|
|
14
12
|
import { FormWarningText } from "../../../components/elements/form-warning.js";
|
|
13
|
+
import { Section } from "../section.js";
|
|
14
|
+
import { useStackApp as useStackApp$1 } from "../../../index.js";
|
|
15
15
|
//#region src/components-page/account-settings/email-and-auth/password-section.tsx
|
|
16
16
|
function PasswordSection(props) {
|
|
17
17
|
const { t } = useTranslation();
|
|
@@ -6,11 +6,11 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
import { KnownErrors } from "@hexclave/shared";
|
|
7
7
|
import { Result } from "@hexclave/shared/dist/utils/results";
|
|
8
8
|
import { useTranslation } from "../../../lib/translations.js";
|
|
9
|
+
import { Section } from "../section.js";
|
|
9
10
|
import { useStackApp } from "../../../index.js";
|
|
10
11
|
import { CardElement, Elements, useElements, useStripe } from "@stripe/react-stripe-js";
|
|
11
12
|
import { loadStripe } from "@stripe/stripe-js";
|
|
12
13
|
import { envVars } from "../../../generated/env.js";
|
|
13
|
-
import { Section } from "../section.js";
|
|
14
14
|
//#region src/components-page/account-settings/payments/payments-panel.tsx
|
|
15
15
|
function formatPaymentMethod(pm) {
|
|
16
16
|
return [
|
|
@@ -2,10 +2,10 @@ import { HexclaveAssertionError } from "@hexclave/shared/dist/utils/errors";
|
|
|
2
2
|
import { Button } from "@hexclave/ui";
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { CreateApiKeyDialog, ShowApiKeyDialog } from "../../../components/api-key-dialogs.js";
|
|
6
|
-
import { ApiKeyTable } from "../../../components/api-key-table.js";
|
|
7
5
|
import { useStackApp, useUser } from "../../../lib/hooks.js";
|
|
8
6
|
import { useTranslation } from "../../../lib/translations.js";
|
|
7
|
+
import { CreateApiKeyDialog, ShowApiKeyDialog } from "../../../components/api-key-dialogs.js";
|
|
8
|
+
import { ApiKeyTable } from "../../../components/api-key-table.js";
|
|
9
9
|
import { Section } from "../section.js";
|
|
10
10
|
//#region src/components-page/account-settings/teams/team-api-keys-section.tsx
|
|
11
11
|
function TeamApiKeysSection(props) {
|
|
@@ -8,8 +8,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
import { useStackApp, useUser } from "../../../lib/hooks.js";
|
|
9
9
|
import { useTranslation } from "../../../lib/translations.js";
|
|
10
10
|
import { PageLayout } from "../page-layout.js";
|
|
11
|
-
import { Section } from "../section.js";
|
|
12
11
|
import { FormWarningText } from "../../../components/elements/form-warning.js";
|
|
12
|
+
import { Section } from "../section.js";
|
|
13
13
|
import { MessageCard } from "../../../components/message-cards/message-card.js";
|
|
14
14
|
//#region src/components-page/account-settings/teams/team-creation-page.tsx
|
|
15
15
|
function TeamCreationPage(props) {
|
|
@@ -8,8 +8,8 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
import { Trash } from "lucide-react";
|
|
9
9
|
import { useUser } from "../../../lib/hooks.js";
|
|
10
10
|
import { useTranslation } from "../../../lib/translations.js";
|
|
11
|
-
import { Section } from "../section.js";
|
|
12
11
|
import { FormWarningText } from "../../../components/elements/form-warning.js";
|
|
12
|
+
import { Section } from "../section.js";
|
|
13
13
|
//#region src/components-page/account-settings/teams/team-member-invitation-section.tsx
|
|
14
14
|
function TeamMemberInvitationSection(props) {
|
|
15
15
|
if (!useUser({ or: "redirect" }).usePermission(props.team, "$invite_members")) return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/dev-tool/index.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/dev-tool/index.ts"],"mappings":";;;;;AA2GA;;;;;;;;AAAwF;;;iBAAxE,YAAA,CAAa,GAAA,EAAK,cAAc,QAAQ,aAAA"}
|
|
@@ -14,11 +14,13 @@ function getOverride() {
|
|
|
14
14
|
return null;
|
|
15
15
|
}
|
|
16
16
|
let activeDevToolOption = void 0;
|
|
17
|
+
let activeProjectIsDevelopmentEnvironment = false;
|
|
17
18
|
function shouldShow() {
|
|
18
19
|
const override = getOverride();
|
|
19
20
|
if (override !== null) return override;
|
|
20
21
|
if (!canMountIntoDom()) return false;
|
|
21
22
|
if (activeDevToolOption === true) return true;
|
|
23
|
+
if (activeProjectIsDevelopmentEnvironment) return true;
|
|
22
24
|
const nodeEnv = envVars.NODE_ENV;
|
|
23
25
|
if (nodeEnv !== void 0) return nodeEnv === "development";
|
|
24
26
|
try {
|
|
@@ -73,10 +75,25 @@ function tryMount() {
|
|
|
73
75
|
function mountDevTool(app, devToolOption) {
|
|
74
76
|
activeApp = app;
|
|
75
77
|
activeDevToolOption = devToolOption === false ? void 0 : devToolOption ?? void 0;
|
|
78
|
+
activeProjectIsDevelopmentEnvironment = false;
|
|
76
79
|
tryMount();
|
|
80
|
+
queueMicrotask(() => {
|
|
81
|
+
runAsynchronously(async () => {
|
|
82
|
+
const project = await app.getProject();
|
|
83
|
+
if (activeApp !== app) return;
|
|
84
|
+
activeProjectIsDevelopmentEnvironment = project.isDevelopmentEnvironment;
|
|
85
|
+
if (activeProjectIsDevelopmentEnvironment && activeCleanup === null) tryMount();
|
|
86
|
+
}, {
|
|
87
|
+
noErrorLogging: true,
|
|
88
|
+
onError: (error) => {
|
|
89
|
+
captureError("dev-tool-project-detection", error);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
});
|
|
77
93
|
const myCleanup = activeCleanup;
|
|
78
94
|
return () => {
|
|
79
95
|
activeApp = null;
|
|
96
|
+
activeProjectIsDevelopmentEnvironment = false;
|
|
80
97
|
if (activeCleanup === myCleanup && myCleanup != null) {
|
|
81
98
|
activeCleanup = null;
|
|
82
99
|
myCleanup();
|
|
@@ -110,7 +127,7 @@ if (typeof window !== "undefined") window.HexclaveDevTool = window.HexclaveDevTo
|
|
|
110
127
|
activeCleanup();
|
|
111
128
|
activeCleanup = null;
|
|
112
129
|
}
|
|
113
|
-
console.log("[Stack DevTool] Reset to default (auto-detect based on NODE_ENV or localhost/file: origin).");
|
|
130
|
+
console.log("[Stack DevTool] Reset to default (auto-detect based on project, NODE_ENV, or localhost/file: origin).");
|
|
114
131
|
}
|
|
115
132
|
};
|
|
116
133
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/dev-tool/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//===========================================\n\nimport type { StackClientApp } from \"../lib/hexclave-app\";\nimport { captureError } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { isLocalhost } from \"@hexclave/shared/dist/utils/urls\";\nimport { canMountIntoDom } from \"../in-page-ui/dom\";\nimport { envVars } from \"../generated/env\";\nimport type { createDevTool as CreateDevToolFn } from \"./dev-tool-core\";\n\n// Hexclave rebrand: UI-only local pref — straight rename (one-time reset is harmless)\nconst OVERRIDE_KEY = '__hexclave-dev-tool-override';\n\nfunction getOverride(): boolean | null {\n try {\n const val = localStorage.getItem(OVERRIDE_KEY);\n if (val === 'true') return true;\n if (val === 'false') return false;\n } catch {}\n return null;\n}\n\nlet activeDevToolOption: true | \"auto\" | undefined = undefined;\n\nfunction shouldShow(): boolean {\n const override = getOverride();\n if (override !== null) return override;\n if (!canMountIntoDom()) return false;\n\n // If devTool was explicitly set to true, always show\n if (activeDevToolOption === true) return true;\n\n // \"auto\" behavior (the default):\n const nodeEnv = envVars.NODE_ENV;\n if (nodeEnv !== undefined) {\n // NODE_ENV is available (bundler/process env exists) — only show in development\n return nodeEnv === \"development\";\n }\n\n // NODE_ENV not found (no process.env/import.meta) — show on localhost or file: protocol\n try {\n const url = new URL(window.location.href);\n if (url.protocol === \"file:\") return true;\n } catch {}\n return isLocalhost(window.location.href);\n}\n\nlet activeCleanup: (() => void) | null = null;\nlet activeApp: StackClientApp<true> | null = null;\nlet mountGeneration = 0;\n\nlet createDevToolPromise: Promise<typeof CreateDevToolFn> | null = null;\nfunction loadCreateDevTool(): Promise<typeof CreateDevToolFn> {\n if (!createDevToolPromise) {\n createDevToolPromise = import(\"./dev-tool-core\").then(m => m.createDevTool).catch((err) => {\n createDevToolPromise = null;\n throw err;\n });\n }\n return createDevToolPromise;\n}\n\nfunction tryMount() {\n if (activeCleanup) {\n activeCleanup();\n activeCleanup = null;\n }\n\n if (!shouldShow() || !activeApp || !canMountIntoDom()) return;\n\n const generation = ++mountGeneration;\n const app = activeApp;\n\n runAsynchronously(async () => {\n const createDevTool = await loadCreateDevTool();\n if (generation !== mountGeneration) return;\n if (!shouldShow() || activeApp !== app || !canMountIntoDom()) return;\n activeCleanup = createDevTool(app);\n }, {\n noErrorLogging: true,\n onError: (error) => {\n captureError(\"dev-tool-mount\", error);\n },\n });\n}\n\n/**\n * Mounts the Hexclave dev tool on the page.\n *\n * Visibility is determined by the `devTool` option:\n * - `true`: always show\n * - `false`: never show (caller gates this — mountDevTool won't be called)\n * - `\"auto\"` / `undefined`: show based on NODE_ENV or localhost/file: heuristics\n *\n * Console commands (also work in production):\n * HexclaveDevTool.enable() — force-show the dev tool\n * HexclaveDevTool.disable() — force-hide the dev tool\n * HexclaveDevTool.reset() — revert to auto behavior\n */\nexport function mountDevTool(app: StackClientApp<true>, devToolOption?: boolean | \"auto\"): () => void {\n activeApp = app;\n activeDevToolOption = devToolOption === false ? undefined : devToolOption ?? undefined;\n tryMount();\n\n // Capture the cleanup created by THIS specific mount call so that React\n // StrictMode's double-invoke doesn't let the first effect's cleanup tear\n // down the second mount (which would cause the tool to disappear silently).\n const myCleanup = activeCleanup;\n\n return () => {\n activeApp = null;\n if (activeCleanup === myCleanup && myCleanup != null) {\n activeCleanup = null;\n myCleanup();\n }\n };\n}\n\n// Expose console commands: HexclaveDevTool.enable() / .disable() / .reset()\nif (typeof window !== 'undefined') {\n // Hexclave rebrand: expose under both the legacy and new global names.\n (window as any).HexclaveDevTool = (window as any).HexclaveDevTool = {\n enable() {\n try {\n localStorage.setItem(OVERRIDE_KEY, 'true');\n } catch {}\n tryMount();\n console.log('[Stack DevTool] Enabled. Refresh if the panel does not appear.');\n },\n disable() {\n try {\n localStorage.setItem(OVERRIDE_KEY, 'false');\n } catch {}\n if (activeCleanup) {\n activeCleanup();\n activeCleanup = null;\n }\n console.log('[Stack DevTool] Disabled.');\n },\n reset() {\n try {\n localStorage.removeItem(OVERRIDE_KEY);\n } catch {}\n if (shouldShow()) {\n tryMount();\n } else if (activeCleanup) {\n activeCleanup();\n activeCleanup = null;\n }\n console.log('[Stack DevTool] Reset to default (auto-detect based on NODE_ENV or localhost/file: origin).');\n },\n };\n}\n\n"],"mappings":";;;;;;AAcA,MAAM,eAAe;AAErB,SAAS,cAA8B;CACrC,IAAI;EACF,MAAM,MAAM,aAAa,QAAQ,YAAY;EAC7C,IAAI,QAAQ,QAAQ,OAAO;EAC3B,IAAI,QAAQ,SAAS,OAAO;CAC9B,QAAQ,CAAC;CACT,OAAO;AACT;AAEA,IAAI,sBAAiD,KAAA;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/dev-tool/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//===========================================\n\nimport type { StackClientApp } from \"../lib/hexclave-app\";\nimport { captureError } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { isLocalhost } from \"@hexclave/shared/dist/utils/urls\";\nimport { canMountIntoDom } from \"../in-page-ui/dom\";\nimport { envVars } from \"../generated/env\";\nimport type { createDevTool as CreateDevToolFn } from \"./dev-tool-core\";\n\n// Hexclave rebrand: UI-only local pref — straight rename (one-time reset is harmless)\nconst OVERRIDE_KEY = '__hexclave-dev-tool-override';\n\nfunction getOverride(): boolean | null {\n try {\n const val = localStorage.getItem(OVERRIDE_KEY);\n if (val === 'true') return true;\n if (val === 'false') return false;\n } catch {}\n return null;\n}\n\nlet activeDevToolOption: true | \"auto\" | undefined = undefined;\nlet activeProjectIsDevelopmentEnvironment = false;\n\nfunction shouldShow(): boolean {\n const override = getOverride();\n if (override !== null) return override;\n if (!canMountIntoDom()) return false;\n\n // If devTool was explicitly set to true, always show\n if (activeDevToolOption === true) return true;\n\n // Development environment projects should expose the tool even when the\n // consuming app itself was built or hosted as production.\n if (activeProjectIsDevelopmentEnvironment) return true;\n\n // \"auto\" behavior (the default):\n const nodeEnv = envVars.NODE_ENV;\n if (nodeEnv !== undefined) {\n // NODE_ENV is available (bundler/process env exists) — only show in development\n return nodeEnv === \"development\";\n }\n\n // NODE_ENV not found (no process.env/import.meta) — show on localhost or file: protocol\n try {\n const url = new URL(window.location.href);\n if (url.protocol === \"file:\") return true;\n } catch {}\n return isLocalhost(window.location.href);\n}\n\nlet activeCleanup: (() => void) | null = null;\nlet activeApp: StackClientApp<true> | null = null;\nlet mountGeneration = 0;\n\nlet createDevToolPromise: Promise<typeof CreateDevToolFn> | null = null;\nfunction loadCreateDevTool(): Promise<typeof CreateDevToolFn> {\n if (!createDevToolPromise) {\n createDevToolPromise = import(\"./dev-tool-core\").then(m => m.createDevTool).catch((err) => {\n createDevToolPromise = null;\n throw err;\n });\n }\n return createDevToolPromise;\n}\n\nfunction tryMount() {\n if (activeCleanup) {\n activeCleanup();\n activeCleanup = null;\n }\n\n if (!shouldShow() || !activeApp || !canMountIntoDom()) return;\n\n const generation = ++mountGeneration;\n const app = activeApp;\n\n runAsynchronously(async () => {\n const createDevTool = await loadCreateDevTool();\n if (generation !== mountGeneration) return;\n if (!shouldShow() || activeApp !== app || !canMountIntoDom()) return;\n activeCleanup = createDevTool(app);\n }, {\n noErrorLogging: true,\n onError: (error) => {\n captureError(\"dev-tool-mount\", error);\n },\n });\n}\n\n/**\n * Mounts the Hexclave dev tool on the page.\n *\n * Visibility is determined by the `devTool` option:\n * - `true`: always show\n * - `false`: never show (caller gates this — mountDevTool won't be called)\n * - `\"auto\"` / `undefined`: show based on NODE_ENV or localhost/file: heuristics\n *\n * Console commands (also work in production):\n * HexclaveDevTool.enable() — force-show the dev tool\n * HexclaveDevTool.disable() — force-hide the dev tool\n * HexclaveDevTool.reset() — revert to auto behavior\n */\nexport function mountDevTool(app: StackClientApp<true>, devToolOption?: boolean | \"auto\"): () => void {\n activeApp = app;\n activeDevToolOption = devToolOption === false ? undefined : devToolOption ?? undefined;\n activeProjectIsDevelopmentEnvironment = false;\n tryMount();\n\n // The project endpoint is also the source of config warnings, so this uses\n // the backend's development-environment flag instead of inferring it from\n // the SDK's build or the current page's origin.\n queueMicrotask(() => {\n runAsynchronously(async () => {\n const project = await app.getProject();\n if (activeApp !== app) return;\n activeProjectIsDevelopmentEnvironment = project.isDevelopmentEnvironment;\n if (activeProjectIsDevelopmentEnvironment && activeCleanup === null) {\n tryMount();\n }\n }, {\n noErrorLogging: true,\n onError: (error) => {\n captureError(\"dev-tool-project-detection\", error);\n },\n });\n });\n\n // Capture the cleanup created by THIS specific mount call so that React\n // StrictMode's double-invoke doesn't let the first effect's cleanup tear\n // down the second mount (which would cause the tool to disappear silently).\n const myCleanup = activeCleanup;\n\n return () => {\n activeApp = null;\n activeProjectIsDevelopmentEnvironment = false;\n if (activeCleanup === myCleanup && myCleanup != null) {\n activeCleanup = null;\n myCleanup();\n }\n };\n}\n\n// Expose console commands: HexclaveDevTool.enable() / .disable() / .reset()\nif (typeof window !== 'undefined') {\n // Hexclave rebrand: expose under both the legacy and new global names.\n (window as any).HexclaveDevTool = (window as any).HexclaveDevTool = {\n enable() {\n try {\n localStorage.setItem(OVERRIDE_KEY, 'true');\n } catch {}\n tryMount();\n console.log('[Stack DevTool] Enabled. Refresh if the panel does not appear.');\n },\n disable() {\n try {\n localStorage.setItem(OVERRIDE_KEY, 'false');\n } catch {}\n if (activeCleanup) {\n activeCleanup();\n activeCleanup = null;\n }\n console.log('[Stack DevTool] Disabled.');\n },\n reset() {\n try {\n localStorage.removeItem(OVERRIDE_KEY);\n } catch {}\n if (shouldShow()) {\n tryMount();\n } else if (activeCleanup) {\n activeCleanup();\n activeCleanup = null;\n }\n console.log('[Stack DevTool] Reset to default (auto-detect based on project, NODE_ENV, or localhost/file: origin).');\n },\n };\n}\n\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { StackClientApp } from "../lib/hexclave-app/index.js";
|
|
3
|
+
import { createDevTool } from "./dev-tool-core.js";
|
|
4
|
+
import { mountDevTool } from "./index.js";
|
|
5
|
+
//#region src/dev-tool/index.test.ts
|
|
6
|
+
vi.mock("./dev-tool-core", () => ({ createDevTool: vi.fn(() => () => {}) }));
|
|
7
|
+
describe("dev tool visibility", () => {
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
vi.unstubAllEnvs();
|
|
10
|
+
vi.unstubAllGlobals();
|
|
11
|
+
vi.clearAllMocks();
|
|
12
|
+
});
|
|
13
|
+
it("shows for a development environment project in a production-hosted app", async () => {
|
|
14
|
+
const app = new StackClientApp({
|
|
15
|
+
baseUrl: "https://api.example.com",
|
|
16
|
+
projectId: "00000000-0000-4000-8000-000000000000",
|
|
17
|
+
publishableClientKey: "stack-pk-test",
|
|
18
|
+
tokenStore: "memory",
|
|
19
|
+
redirectMethod: "none",
|
|
20
|
+
devTool: false
|
|
21
|
+
});
|
|
22
|
+
const getProject = vi.fn(async () => ({ isDevelopmentEnvironment: true }));
|
|
23
|
+
Reflect.set(app, "getProject", getProject);
|
|
24
|
+
vi.stubEnv("NODE_ENV", "production");
|
|
25
|
+
vi.stubGlobal("window", { location: { href: "https://example.com" } });
|
|
26
|
+
vi.stubGlobal("document", {
|
|
27
|
+
body: { appendChild: () => {} },
|
|
28
|
+
createElement: () => ({})
|
|
29
|
+
});
|
|
30
|
+
vi.stubGlobal("localStorage", { getItem: () => null });
|
|
31
|
+
mountDevTool(app);
|
|
32
|
+
await vi.waitFor(() => {
|
|
33
|
+
expect(getProject).toHaveBeenCalledOnce();
|
|
34
|
+
expect(createDevTool).toHaveBeenCalledOnce();
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
//#endregion
|
|
39
|
+
export {};
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","names":[],"sources":["../../../src/dev-tool/index.test.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 { afterEach, describe, expect, it, vi } from \"vitest\";\nimport { StackClientApp } from \"../lib/hexclave-app\";\nimport { createDevTool } from \"./dev-tool-core\";\nimport { mountDevTool } from \".\";\n\nvi.mock(\"./dev-tool-core\", () => ({\n createDevTool: vi.fn(() => () => {}),\n}));\n\ndescribe(\"dev tool visibility\", () => {\n afterEach(() => {\n vi.unstubAllEnvs();\n vi.unstubAllGlobals();\n vi.clearAllMocks();\n });\n\n it(\"shows for a development environment project in a production-hosted app\", async () => {\n const app = new StackClientApp({\n baseUrl: \"https://api.example.com\",\n projectId: \"00000000-0000-4000-8000-000000000000\",\n publishableClientKey: \"stack-pk-test\",\n tokenStore: \"memory\",\n redirectMethod: \"none\",\n devTool: false,\n });\n const getProject = vi.fn(async () => ({\n isDevelopmentEnvironment: true,\n }));\n Reflect.set(app, \"getProject\", getProject);\n\n vi.stubEnv(\"NODE_ENV\", \"production\");\n vi.stubGlobal(\"window\", {\n location: {\n href: \"https://example.com\",\n },\n });\n vi.stubGlobal(\"document\", {\n body: {\n appendChild: () => {},\n },\n createElement: () => ({}),\n });\n vi.stubGlobal(\"localStorage\", {\n getItem: () => null,\n });\n\n mountDevTool(app);\n\n await vi.waitFor(() => {\n expect(getProject).toHaveBeenCalledOnce();\n expect(createDevTool).toHaveBeenCalledOnce();\n });\n });\n});\n"],"mappings":";;;;;AASA,GAAG,KAAK,0BAA0B,EAChC,eAAe,GAAG,eAAe,CAAC,CAAC,EACrC,EAAE;AAEF,SAAS,6BAA6B;CACpC,gBAAgB;EACd,GAAG,cAAc;EACjB,GAAG,iBAAiB;EACpB,GAAG,cAAc;CACnB,CAAC;CAED,GAAG,0EAA0E,YAAY;EACvF,MAAM,MAAM,IAAI,eAAe;GAC7B,SAAS;GACT,WAAW;GACX,sBAAsB;GACtB,YAAY;GACZ,gBAAgB;GAChB,SAAS;EACX,CAAC;EACD,MAAM,aAAa,GAAG,GAAG,aAAa,EACpC,0BAA0B,KAC5B,EAAE;EACF,QAAQ,IAAI,KAAK,cAAc,UAAU;EAEzC,GAAG,QAAQ,YAAY,YAAY;EACnC,GAAG,WAAW,UAAU,EACtB,UAAU,EACR,MAAM,sBACR,EACF,CAAC;EACD,GAAG,WAAW,YAAY;GACxB,MAAM,EACJ,mBAAmB,CAAC,EACtB;GACA,sBAAsB,CAAC;EACzB,CAAC;EACD,GAAG,WAAW,gBAAgB,EAC5B,eAAe,KACjB,CAAC;EAED,aAAa,GAAG;EAEhB,MAAM,GAAG,cAAc;GACrB,OAAO,UAAU,CAAC,CAAC,qBAAqB;GACxC,OAAO,aAAa,CAAC,CAAC,qBAAqB;EAC7C,CAAC;CACH,CAAC;AACH,CAAC"}
|