mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 06:30:03 +00:00
fix(studio): guard import.meta.env access for non-Vite bundlers
import.meta.env is undefined in Next.js Turbopack/Webpack, causing "Cannot read properties of undefined" when the studio telemetry client loads. Wrap accesses in try-catch so they gracefully fall back. Also hardcode the PostHog API key and host — they're public write-only values with no reason to be overridable via env.
This commit is contained in:
@@ -2,20 +2,11 @@
|
||||
|
||||
import { describe, expect, it, vi, beforeEach } from "vitest";
|
||||
|
||||
// `shouldTrack()` reads `POSTHOG_API_KEY` from module-level const that's
|
||||
// evaluated at module load time, so changing `import.meta.env` after import
|
||||
// has no effect on the key. Each test resets module cache and re-imports.
|
||||
// `shouldTrack()` reads module-level constants evaluated at module load time,
|
||||
// so changing env after import has no effect. Each test resets module cache.
|
||||
|
||||
const OPT_OUT_KEY = "hyperframes-studio:telemetryDisabled";
|
||||
|
||||
function setKey(value: string | undefined): void {
|
||||
if (value === undefined) {
|
||||
delete (import.meta.env as Record<string, unknown>).VITE_HYPERFRAMES_POSTHOG_KEY;
|
||||
} else {
|
||||
(import.meta.env as Record<string, unknown>).VITE_HYPERFRAMES_POSTHOG_KEY = value;
|
||||
}
|
||||
}
|
||||
|
||||
function setNoTelemetry(value: string | undefined): void {
|
||||
if (value === undefined) {
|
||||
delete (import.meta.env as Record<string, unknown>).VITE_HYPERFRAMES_NO_TELEMETRY;
|
||||
@@ -37,29 +28,16 @@ async function loadShouldTrack(): Promise<() => boolean> {
|
||||
describe("studio client shouldTrack", () => {
|
||||
beforeEach(() => {
|
||||
setDev(false);
|
||||
setKey("phc_test_key");
|
||||
setNoTelemetry(undefined);
|
||||
localStorage.clear();
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
it("returns true when key is configured, not in dev mode, and no opt-outs", async () => {
|
||||
it("returns true when not in dev mode and no opt-outs", async () => {
|
||||
const shouldTrack = await loadShouldTrack();
|
||||
expect(shouldTrack()).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false when API key does not start with phc_", async () => {
|
||||
setKey("not_a_real_key");
|
||||
const shouldTrack = await loadShouldTrack();
|
||||
expect(shouldTrack()).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false when API key is empty string", async () => {
|
||||
setKey("");
|
||||
const shouldTrack = await loadShouldTrack();
|
||||
expect(shouldTrack()).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false when user has opted out via localStorage", async () => {
|
||||
localStorage.setItem(OPT_OUT_KEY, "1");
|
||||
const shouldTrack = await loadShouldTrack();
|
||||
@@ -93,7 +71,6 @@ describe("studio client shouldTrack", () => {
|
||||
it("memoizes its decision after the first call", async () => {
|
||||
const shouldTrack = await loadShouldTrack();
|
||||
const first = shouldTrack();
|
||||
// Flip an underlying input — memoized return must not change.
|
||||
localStorage.setItem(OPT_OUT_KEY, "1");
|
||||
expect(shouldTrack()).toBe(first);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user