@hexclave/tanstack-start 1.0.56 → 1.0.58

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/{admin-app-impl-CU4o5_CU.d.ts → admin-app-impl-CBI31nSt.d.ts} +8 -8
  2. package/dist/{admin-app-impl-CU4o5_CU.d.ts.map → admin-app-impl-CBI31nSt.d.ts.map} +1 -1
  3. package/dist/clickmap/clickmap-core.d.ts +1 -1
  4. package/dist/clickmap/index.d.ts +1 -1
  5. package/dist/{client-app-CqiogvCi.d.ts → client-app-DI4pr0KJ.d.ts} +2 -1
  6. package/dist/{client-app-CqiogvCi.d.ts.map → client-app-DI4pr0KJ.d.ts.map} +1 -1
  7. package/dist/components/selected-team-switcher.d.ts +1 -1
  8. package/dist/components/team-icon.d.ts +1 -1
  9. package/dist/components/team-switcher.d.ts +1 -1
  10. package/dist/components-page/account-settings/payments/payments-page.d.ts +1 -1
  11. package/dist/components-page/account-settings/teams/leave-team-section.d.ts +1 -1
  12. package/dist/components-page/account-settings/teams/team-api-keys-section.d.ts +1 -1
  13. package/dist/components-page/account-settings/teams/team-api-keys-section.js +1 -1
  14. package/dist/components-page/account-settings/teams/team-display-name-section.d.ts +1 -1
  15. package/dist/components-page/account-settings/teams/team-member-invitation-section.d.ts +1 -1
  16. package/dist/components-page/account-settings/teams/team-member-list-section.d.ts +1 -1
  17. package/dist/components-page/account-settings/teams/team-page.d.ts +1 -1
  18. package/dist/components-page/account-settings/teams/team-profile-image-section.d.ts +1 -1
  19. package/dist/components-page/account-settings/teams/team-profile-user-section.d.ts +1 -1
  20. package/dist/components-page/hexclave-handler-client.d.ts +1 -1
  21. package/dist/components-page/hexclave-handler.d.ts +1 -1
  22. package/dist/dev-tool/dev-tool-core.d.ts +1 -1
  23. package/dist/dev-tool/index.d.ts +1 -1
  24. package/dist/dev-tool/index.d.ts.map +1 -1
  25. package/dist/dev-tool/index.js +18 -1
  26. package/dist/dev-tool/index.js.map +1 -1
  27. package/dist/dev-tool/index.test.d.ts +1 -0
  28. package/dist/dev-tool/index.test.js +40 -0
  29. package/dist/dev-tool/index.test.js.map +1 -0
  30. package/dist/esm/components-page/account-settings/teams/team-api-keys-section.js +1 -1
  31. package/dist/esm/dev-tool/index.d.ts.map +1 -1
  32. package/dist/esm/dev-tool/index.js +18 -1
  33. package/dist/esm/dev-tool/index.js.map +1 -1
  34. package/dist/esm/dev-tool/index.test.d.ts +1 -0
  35. package/dist/esm/dev-tool/index.test.js +41 -0
  36. package/dist/esm/dev-tool/index.test.js.map +1 -0
  37. package/dist/esm/generated/quetzal-translations.d.ts +2 -2
  38. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +4 -4
  39. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  40. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +2 -2
  41. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  42. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +1 -0
  43. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  44. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
  45. package/dist/esm/lib/hexclave-app/projects/index.d.ts +1 -0
  46. package/dist/esm/lib/hexclave-app/projects/index.d.ts.map +1 -1
  47. package/dist/esm/lib/hexclave-app/projects/index.js.map +1 -1
  48. package/dist/esm/pushed-config-error-overlay/index.test.js +1 -1
  49. package/dist/generated/quetzal-translations.d.ts +1 -1
  50. package/dist/{hexclave-provider-D9KWfw3n.d.ts → hexclave-provider-Cvys7M-U.d.ts} +3 -3
  51. package/dist/{hexclave-provider-D9KWfw3n.d.ts.map → hexclave-provider-Cvys7M-U.d.ts.map} +1 -1
  52. package/dist/{hooks-FZEGOxTp.d.ts → hooks-BP37GS_H.d.ts} +2 -2
  53. package/dist/{hooks-FZEGOxTp.d.ts.map → hooks-BP37GS_H.d.ts.map} +1 -1
  54. package/dist/{index-DHE12H8g.d.ts → index-CDfsi7Kx.d.ts} +2 -2
  55. package/dist/{index-DHE12H8g.d.ts.map → index-CDfsi7Kx.d.ts.map} +1 -1
  56. package/dist/index.d.ts +4 -4
  57. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
  58. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
  59. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +1 -0
  60. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  61. package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
  62. package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
  63. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
  64. package/dist/lib/hexclave-app/apps/index.d.ts +1 -1
  65. package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +1 -1
  66. package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -1
  67. package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
  68. package/dist/lib/hexclave-app/index.d.ts +1 -1
  69. package/dist/lib/hexclave-app/projects/index.d.ts +1 -1
  70. package/dist/lib/hexclave-app/projects/index.js.map +1 -1
  71. package/dist/lib/hexclave-app/teams/index.d.ts +1 -1
  72. package/dist/lib/hexclave-app/users/index.d.ts +1 -1
  73. package/dist/lib/hooks.d.ts +1 -1
  74. package/dist/providers/hexclave-context.d.ts +1 -1
  75. package/dist/providers/hexclave-provider-client.d.ts +1 -1
  76. package/dist/providers/hexclave-provider.d.ts +1 -1
  77. package/dist/providers/translation-provider.d.ts +1 -1
  78. package/dist/pushed-config-error-overlay/index.d.ts +1 -1
  79. package/dist/pushed-config-error-overlay/index.test.js +1 -1
  80. package/dist/{quetzal-translations-XeH3zQ9l.d.ts → quetzal-translations-C5DKC5UR.d.ts} +3 -3
  81. package/dist/{quetzal-translations-XeH3zQ9l.d.ts.map → quetzal-translations-C5DKC5UR.d.ts.map} +1 -1
  82. package/dist/{translation-provider-WOaZXqAz.d.ts → translation-provider-CHdpSoRh.d.ts} +2 -2
  83. package/dist/{translation-provider-WOaZXqAz.d.ts.map → translation-provider-CHdpSoRh.d.ts.map} +1 -1
  84. package/package.json +3 -3
  85. package/src/dev-tool/index.test.ts +58 -0
  86. package/src/dev-tool/index.ts +27 -1
  87. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +1 -0
  88. package/src/lib/hexclave-app/projects/index.ts +1 -0
@@ -4,9 +4,9 @@ import { useState } from "react";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { useStackApp, useUser } from "../../../lib/hooks.js";
6
6
  import { useTranslation } from "../../../lib/translations.js";
7
+ import { Section } from "../section.js";
7
8
  import { CreateApiKeyDialog, ShowApiKeyDialog } from "../../../components/api-key-dialogs.js";
8
9
  import { ApiKeyTable } from "../../../components/api-key-table.js";
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) {
12
12
  const user = useUser({ or: "redirect" });
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/dev-tool/index.ts"],"mappings":";;;;;AAsGA;;;;;;;;AAAwF;;;iBAAxE,YAAA,CAAa,GAAA,EAAK,cAAc,QAAQ,aAAA"}
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;AAErD,SAAS,aAAsB;CAC7B,MAAM,WAAW,YAAY;CAC7B,IAAI,aAAa,MAAM,OAAO;CAC9B,IAAI,CAAC,gBAAgB,GAAG,OAAO;CAG/B,IAAI,wBAAwB,MAAM,OAAO;CAGzC,MAAM,UAAU,QAAQ;CACxB,IAAI,YAAY,KAAA,GAEd,OAAO,YAAY;CAIrB,IAAI;EAEF,IAAI,IADY,IAAI,OAAO,SAAS,IAC9B,CAAC,CAAC,aAAa,SAAS,OAAO;CACvC,QAAQ,CAAC;CACT,OAAO,YAAY,OAAO,SAAS,IAAI;AACzC;AAEA,IAAI,gBAAqC;AACzC,IAAI,YAAyC;AAC7C,IAAI,kBAAkB;AAEtB,IAAI,uBAA+D;AACnE,SAAS,oBAAqD;CAC5D,IAAI,CAAC,sBACH,uBAAuB,OAAO,qBAAkB,CAAC,MAAK,MAAK,EAAE,aAAa,CAAC,CAAC,OAAO,QAAQ;EACzF,uBAAuB;EACvB,MAAM;CACR,CAAC;CAEH,OAAO;AACT;AAEA,SAAS,WAAW;CAClB,IAAI,eAAe;EACjB,cAAc;EACd,gBAAgB;CAClB;CAEA,IAAI,CAAC,WAAW,KAAK,CAAC,aAAa,CAAC,gBAAgB,GAAG;CAEvD,MAAM,aAAa,EAAE;CACrB,MAAM,MAAM;CAEZ,kBAAkB,YAAY;EAC5B,MAAM,gBAAgB,MAAM,kBAAkB;EAC9C,IAAI,eAAe,iBAAiB;EACpC,IAAI,CAAC,WAAW,KAAK,cAAc,OAAO,CAAC,gBAAgB,GAAG;EAC9D,gBAAgB,cAAc,GAAG;CACnC,GAAG;EACD,gBAAgB;EAChB,UAAU,UAAU;GAClB,aAAa,kBAAkB,KAAK;EACtC;CACF,CAAC;AACH;;;;;;;;;;;;;;AAeA,SAAgB,aAAa,KAA2B,eAA8C;CACpG,YAAY;CACZ,sBAAsB,kBAAkB,QAAQ,KAAA,IAAY,iBAAiB,KAAA;CAC7E,SAAS;CAKT,MAAM,YAAY;CAElB,aAAa;EACX,YAAY;EACZ,IAAI,kBAAkB,aAAa,aAAa,MAAM;GACpD,gBAAgB;GAChB,UAAU;EACZ;CACF;AACF;AAGA,IAAI,OAAO,WAAW,aAEpB,OAAgB,kBAAkB,OAAgB,kBAAkB;CAClE,SAAS;EACP,IAAI;GACF,aAAa,QAAQ,cAAc,MAAM;EAC3C,QAAQ,CAAC;EACT,SAAS;EACT,QAAQ,IAAI,gEAAgE;CAC9E;CACA,UAAU;EACR,IAAI;GACF,aAAa,QAAQ,cAAc,OAAO;EAC5C,QAAQ,CAAC;EACT,IAAI,eAAe;GACjB,cAAc;GACd,gBAAgB;EAClB;EACA,QAAQ,IAAI,2BAA2B;CACzC;CACA,QAAQ;EACN,IAAI;GACF,aAAa,WAAW,YAAY;EACtC,QAAQ,CAAC;EACT,IAAI,WAAW,GACb,SAAS;OACJ,IAAI,eAAe;GACxB,cAAc;GACd,gBAAgB;EAClB;EACA,QAAQ,IAAI,6FAA6F;CAC3G;AACF"}
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":";;;;;;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;AACrD,IAAI,wCAAwC;AAE5C,SAAS,aAAsB;CAC7B,MAAM,WAAW,YAAY;CAC7B,IAAI,aAAa,MAAM,OAAO;CAC9B,IAAI,CAAC,gBAAgB,GAAG,OAAO;CAG/B,IAAI,wBAAwB,MAAM,OAAO;CAIzC,IAAI,uCAAuC,OAAO;CAGlD,MAAM,UAAU,QAAQ;CACxB,IAAI,YAAY,KAAA,GAEd,OAAO,YAAY;CAIrB,IAAI;EAEF,IAAI,IADY,IAAI,OAAO,SAAS,IAC9B,CAAC,CAAC,aAAa,SAAS,OAAO;CACvC,QAAQ,CAAC;CACT,OAAO,YAAY,OAAO,SAAS,IAAI;AACzC;AAEA,IAAI,gBAAqC;AACzC,IAAI,YAAyC;AAC7C,IAAI,kBAAkB;AAEtB,IAAI,uBAA+D;AACnE,SAAS,oBAAqD;CAC5D,IAAI,CAAC,sBACH,uBAAuB,OAAO,qBAAkB,CAAC,MAAK,MAAK,EAAE,aAAa,CAAC,CAAC,OAAO,QAAQ;EACzF,uBAAuB;EACvB,MAAM;CACR,CAAC;CAEH,OAAO;AACT;AAEA,SAAS,WAAW;CAClB,IAAI,eAAe;EACjB,cAAc;EACd,gBAAgB;CAClB;CAEA,IAAI,CAAC,WAAW,KAAK,CAAC,aAAa,CAAC,gBAAgB,GAAG;CAEvD,MAAM,aAAa,EAAE;CACrB,MAAM,MAAM;CAEZ,kBAAkB,YAAY;EAC5B,MAAM,gBAAgB,MAAM,kBAAkB;EAC9C,IAAI,eAAe,iBAAiB;EACpC,IAAI,CAAC,WAAW,KAAK,cAAc,OAAO,CAAC,gBAAgB,GAAG;EAC9D,gBAAgB,cAAc,GAAG;CACnC,GAAG;EACD,gBAAgB;EAChB,UAAU,UAAU;GAClB,aAAa,kBAAkB,KAAK;EACtC;CACF,CAAC;AACH;;;;;;;;;;;;;;AAeA,SAAgB,aAAa,KAA2B,eAA8C;CACpG,YAAY;CACZ,sBAAsB,kBAAkB,QAAQ,KAAA,IAAY,iBAAiB,KAAA;CAC7E,wCAAwC;CACxC,SAAS;CAKT,qBAAqB;EACnB,kBAAkB,YAAY;GAC5B,MAAM,UAAU,MAAM,IAAI,WAAW;GACrC,IAAI,cAAc,KAAK;GACvB,wCAAwC,QAAQ;GAChD,IAAI,yCAAyC,kBAAkB,MAC7D,SAAS;EAEb,GAAG;GACD,gBAAgB;GAChB,UAAU,UAAU;IAClB,aAAa,8BAA8B,KAAK;GAClD;EACF,CAAC;CACH,CAAC;CAKD,MAAM,YAAY;CAElB,aAAa;EACX,YAAY;EACZ,wCAAwC;EACxC,IAAI,kBAAkB,aAAa,aAAa,MAAM;GACpD,gBAAgB;GAChB,UAAU;EACZ;CACF;AACF;AAGA,IAAI,OAAO,WAAW,aAEpB,OAAgB,kBAAkB,OAAgB,kBAAkB;CAClE,SAAS;EACP,IAAI;GACF,aAAa,QAAQ,cAAc,MAAM;EAC3C,QAAQ,CAAC;EACT,SAAS;EACT,QAAQ,IAAI,gEAAgE;CAC9E;CACA,UAAU;EACR,IAAI;GACF,aAAa,QAAQ,cAAc,OAAO;EAC5C,QAAQ,CAAC;EACT,IAAI,eAAe;GACjB,cAAc;GACd,gBAAgB;EAClB;EACA,QAAQ,IAAI,2BAA2B;CACzC;CACA,QAAQ;EACN,IAAI;GACF,aAAa,WAAW,YAAY;EACtC,QAAQ,CAAC;EACT,IAAI,WAAW,GACb,SAAS;OACJ,IAAI,eAAe;GACxB,cAAc;GACd,gBAAgB;EAClB;EACA,QAAQ,IAAI,uGAAuG;CACrH;AACF"}
@@ -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"}