@hexclave/next 1.0.13 → 1.0.15
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.d.ts +15 -0
- package/dist/clickmap/clickmap-core.d.ts.map +1 -0
- package/dist/clickmap/clickmap-core.js +1527 -0
- package/dist/clickmap/clickmap-core.js.map +1 -0
- package/dist/clickmap/clickmap-styles.d.ts +5 -0
- package/dist/clickmap/clickmap-styles.d.ts.map +1 -0
- package/dist/clickmap/clickmap-styles.js +1095 -0
- package/dist/clickmap/clickmap-styles.js.map +1 -0
- package/dist/clickmap/index.d.ts +16 -0
- package/dist/clickmap/index.d.ts.map +1 -0
- package/dist/clickmap/index.js +74 -0
- package/dist/clickmap/index.js.map +1 -0
- 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/message-cards/known-error-message-card.d.ts +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-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.d.ts.map +1 -1
- package/dist/components-page/forgot-password.js +2 -3
- package/dist/components-page/forgot-password.js.map +1 -1
- package/dist/components-page/hexclave-handler-client.d.ts +1 -1
- package/dist/components-page/mfa.js +4 -19
- package/dist/components-page/mfa.js.map +1 -1
- package/dist/components-page/oauth-callback.js +1 -1
- package/dist/components-page/onboarding.js +1 -1
- package/dist/components-page/password-reset.d.ts.map +1 -1
- package/dist/components-page/password-reset.js +5 -7
- package/dist/components-page/password-reset.js.map +1 -1
- package/dist/components-page/team-creation.js +1 -1
- package/dist/dev-tool/dev-tool-core.d.ts.map +1 -1
- package/dist/dev-tool/dev-tool-core.js +258 -262
- package/dist/dev-tool/dev-tool-core.js.map +1 -1
- package/dist/dev-tool/dev-tool-styles.d.ts +1 -1
- package/dist/dev-tool/dev-tool-styles.d.ts.map +1 -1
- package/dist/dev-tool/dev-tool-styles.js +13 -143
- package/dist/dev-tool/dev-tool-styles.js.map +1 -1
- package/dist/dev-tool/index.d.ts.map +1 -1
- package/dist/dev-tool/index.js +5 -12
- package/dist/dev-tool/index.js.map +1 -1
- package/dist/esm/clickmap/clickmap-core.d.ts +15 -0
- package/dist/esm/clickmap/clickmap-core.d.ts.map +1 -0
- package/dist/esm/clickmap/clickmap-core.js +1525 -0
- package/dist/esm/clickmap/clickmap-core.js.map +1 -0
- package/dist/esm/clickmap/clickmap-styles.d.ts +5 -0
- package/dist/esm/clickmap/clickmap-styles.d.ts.map +1 -0
- package/dist/esm/clickmap/clickmap-styles.js +1093 -0
- package/dist/esm/clickmap/clickmap-styles.js.map +1 -0
- package/dist/esm/clickmap/index.d.ts +16 -0
- package/dist/esm/clickmap/index.d.ts.map +1 -0
- package/dist/esm/clickmap/index.js +72 -0
- package/dist/esm/clickmap/index.js.map +1 -0
- 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-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.d.ts.map +1 -1
- package/dist/esm/components-page/forgot-password.js +2 -3
- package/dist/esm/components-page/forgot-password.js.map +1 -1
- package/dist/esm/components-page/hexclave-handler-client.d.ts +1 -1
- package/dist/esm/components-page/mfa.js +4 -19
- package/dist/esm/components-page/mfa.js.map +1 -1
- package/dist/esm/components-page/oauth-callback.js +1 -1
- package/dist/esm/components-page/onboarding.js +1 -1
- package/dist/esm/components-page/password-reset.d.ts.map +1 -1
- package/dist/esm/components-page/password-reset.js +5 -7
- package/dist/esm/components-page/password-reset.js.map +1 -1
- package/dist/esm/components-page/team-creation.js +1 -1
- package/dist/esm/dev-tool/dev-tool-core.d.ts.map +1 -1
- package/dist/esm/dev-tool/dev-tool-core.js +35 -39
- package/dist/esm/dev-tool/dev-tool-core.js.map +1 -1
- package/dist/esm/dev-tool/dev-tool-styles.d.ts +1 -1
- package/dist/esm/dev-tool/dev-tool-styles.d.ts.map +1 -1
- package/dist/esm/dev-tool/dev-tool-styles.js +13 -143
- package/dist/esm/dev-tool/dev-tool-styles.js.map +1 -1
- package/dist/esm/dev-tool/index.d.ts.map +1 -1
- package/dist/esm/dev-tool/index.js +2 -9
- package/dist/esm/dev-tool/index.js.map +1 -1
- package/dist/esm/generated/global-css.d.ts +1 -1
- package/dist/esm/generated/global-css.js +1 -1
- package/dist/esm/generated/global-css.js.map +1 -1
- package/dist/esm/generated/quetzal-translations.d.ts +2 -2
- package/dist/esm/in-page-ui/base-styles.d.ts +5 -0
- package/dist/esm/in-page-ui/base-styles.d.ts.map +1 -0
- package/dist/esm/in-page-ui/base-styles.js +166 -0
- package/dist/esm/in-page-ui/base-styles.js.map +1 -0
- package/dist/esm/in-page-ui/dom.d.ts +15 -0
- package/dist/esm/in-page-ui/dom.d.ts.map +1 -0
- package/dist/esm/in-page-ui/dom.js +44 -0
- package/dist/esm/in-page-ui/dom.js.map +1 -0
- package/dist/esm/lib/auth.js +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +5 -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/admin-app-impl.js +20 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.js.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 +4 -2
- 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.d.ts +13 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.js +146 -14
- package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.test.js +221 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.test.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.js +1 -1
- package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.d.ts +5 -0
- package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.js.map +1 -1
- package/dist/esm/providers/theme-provider.js +1 -1
- package/dist/generated/global-css.d.ts +1 -1
- package/dist/generated/global-css.js +1 -1
- package/dist/generated/global-css.js.map +1 -1
- package/dist/generated/quetzal-translations.d.ts +2 -2
- package/dist/in-page-ui/base-styles.d.ts +5 -0
- package/dist/in-page-ui/base-styles.d.ts.map +1 -0
- package/dist/in-page-ui/base-styles.js +168 -0
- package/dist/in-page-ui/base-styles.js.map +1 -0
- package/dist/in-page-ui/dom.d.ts +15 -0
- package/dist/in-page-ui/dom.d.ts.map +1 -0
- package/dist/in-page-ui/dom.js +51 -0
- package/dist/in-page-ui/dom.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/integrations/convex/component/convex.config.d.ts +1 -1
- package/dist/lib/auth.js +1 -1
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +5 -1
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js +20 -0
- package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +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 +4 -2
- 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.d.ts +13 -0
- package/dist/lib/hexclave-app/apps/implementations/event-tracker.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/event-tracker.js +146 -14
- package/dist/lib/hexclave-app/apps/implementations/event-tracker.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/event-tracker.test.js +221 -0
- package/dist/lib/hexclave-app/apps/implementations/event-tracker.test.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
- package/dist/lib/hexclave-app/apps/implementations/session-replay.js +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +5 -0
- package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts.map +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/admin-app.js.map +1 -1
- package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
- package/dist/lib/hexclave-app/common.d.ts +1 -1
- package/dist/providers/hexclave-provider-client.d.ts +1 -1
- package/dist/providers/theme-provider.js +1 -1
- package/dist/{storage-CKzvsBxG.d.ts → storage-ksajV_p6.d.ts} +1 -1
- package/dist/{storage-CKzvsBxG.d.ts.map → storage-ksajV_p6.d.ts.map} +1 -1
- package/package.json +4 -4
- package/src/clickmap/clickmap-core.ts +1997 -0
- package/src/clickmap/clickmap-styles.ts +1102 -0
- package/src/clickmap/index.ts +95 -0
- package/src/components-page/forgot-password.tsx +1 -2
- package/src/components-page/mfa.tsx +12 -21
- package/src/components-page/password-reset.tsx +4 -6
- package/src/dev-tool/dev-tool-core.ts +38 -65
- package/src/dev-tool/dev-tool-styles.ts +13 -142
- package/src/dev-tool/index.ts +1 -14
- package/src/in-page-ui/base-styles.ts +171 -0
- package/src/in-page-ui/dom.ts +80 -0
- package/src/lib/hexclave-app/apps/implementations/admin-app-impl.ts +23 -1
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +7 -0
- package/src/lib/hexclave-app/apps/implementations/event-tracker.test.ts +287 -0
- package/src/lib/hexclave-app/apps/implementations/event-tracker.ts +226 -16
- package/src/lib/hexclave-app/apps/interfaces/admin-app.ts +3 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-tracker.test.js","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/implementations/event-tracker.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//===========================================\n// @vitest-environment jsdom\n\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { afterEach, describe, expect, it, vi } from \"vitest\";\nimport { EventTracker } from \"./event-tracker\";\n\nasync function advancePastFlush() {\n await vi.advanceTimersByTimeAsync(10_000);\n await Promise.resolve();\n}\n\nfunction getSentEventTypes(sentBodies: string[]) {\n const [body] = sentBodies;\n\n const payload = JSON.parse(body);\n if (typeof payload !== \"object\" || payload === null || !(\"events\" in payload) || !Array.isArray(payload.events)) {\n throw new Error(\"Expected analytics batch payload to include an events array.\");\n }\n\n return (payload.events as { event_type: string }[]).map((event) => event.event_type);\n}\n\ndescribe(\"EventTracker\", () => {\n afterEach(() => {\n vi.useRealTimers();\n });\n\n it(\"captures events when browser globals are exposed as accessor descriptors\", async () => {\n vi.useFakeTimers();\n document.body.innerHTML = \"<button>Open project</button>\";\n\n const screenDescriptor = Object.getOwnPropertyDescriptor(window, \"screen\");\n const historyDescriptor = Object.getOwnPropertyDescriptor(window, \"history\");\n expect(screenDescriptor?.value).toBeUndefined();\n expect(historyDescriptor?.value).toBeUndefined();\n expect(screenDescriptor?.get).toBeTypeOf(\"function\");\n expect(historyDescriptor?.get).toBeTypeOf(\"function\");\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n document.querySelector(\"button\")?.dispatchEvent(new MouseEvent(\"click\", {\n bubbles: true,\n clientX: 12,\n clientY: 34,\n }));\n\n await advancePastFlush();\n\n expect(getSentEventTypes(sentBodies)).toMatchInlineSnapshot(`\n [\n \"$page-view\",\n \"$click\",\n ]\n `);\n } finally {\n tracker.stop();\n }\n });\n\n it(\"captures client-side navigations when history is exposed as an accessor descriptor\", async () => {\n vi.useFakeTimers();\n\n const historyDescriptor = Object.getOwnPropertyDescriptor(window, \"history\");\n expect(historyDescriptor?.value).toBeUndefined();\n expect(historyDescriptor?.get).toBeTypeOf(\"function\");\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n window.history.pushState({}, \"\", \"/projects/test-project\");\n\n await advancePastFlush();\n\n expect(getSentEventTypes(sentBodies)).toMatchInlineSnapshot(`\n [\n \"$page-view\",\n \"$page-view\",\n ]\n `);\n } finally {\n tracker.stop();\n }\n });\n});\n"],"mappings":";;;;;;AAUA,eAAe,mBAAmB;AAChC,OAAM,GAAG,yBAAyB,IAAO;AACzC,OAAM,QAAQ,SAAS;;AAGzB,SAAS,kBAAkB,YAAsB;CAC/C,MAAM,CAAC,QAAQ;CAEf,MAAM,UAAU,KAAK,MAAM,KAAK;AAChC,KAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,EAAE,YAAY,YAAY,CAAC,MAAM,QAAQ,QAAQ,OAAO,CAC7G,OAAM,IAAI,MAAM,+DAA+D;AAGjF,QAAQ,QAAQ,OAAoC,KAAK,UAAU,MAAM,WAAW;;AAGtF,SAAS,sBAAsB;AAC7B,iBAAgB;AACd,KAAG,eAAe;GAClB;AAEF,IAAG,4EAA4E,YAAY;AACzF,KAAG,eAAe;AAClB,WAAS,KAAK,YAAY;EAE1B,MAAM,mBAAmB,OAAO,yBAAyB,QAAQ,SAAS;EAC1E,MAAM,oBAAoB,OAAO,yBAAyB,QAAQ,UAAU;AAC5E,SAAO,kBAAkB,MAAM,CAAC,eAAe;AAC/C,SAAO,mBAAmB,MAAM,CAAC,eAAe;AAChD,SAAO,kBAAkB,IAAI,CAAC,WAAW,WAAW;AACpD,SAAO,mBAAmB,IAAI,CAAC,WAAW,WAAW;EAErD,MAAM,aAAuB,EAAE;EAC/B,MAAM,UAAU,IAAI,aAAa;GAC/B,WAAW;GACX,WAAW,OAAO,SAAS;AACzB,eAAW,KAAK,KAAK;AACrB,WAAO,OAAO,GAAG,IAAI,UAAU,CAAC;;GAEnC,CAAC;AAEF,MAAI;AACF,WAAQ,OAAO;AACf,YAAS,cAAc,SAAS,EAAE,cAAc,IAAI,WAAW,SAAS;IACtE,SAAS;IACT,SAAS;IACT,SAAS;IACV,CAAC,CAAC;AAEH,SAAM,kBAAkB;AAExB,UAAO,kBAAkB,WAAW,CAAC,CAAC,sBAAsB;;;;;QAK1D;YACM;AACR,WAAQ,MAAM;;GAEhB;AAEF,IAAG,sFAAsF,YAAY;AACnG,KAAG,eAAe;EAElB,MAAM,oBAAoB,OAAO,yBAAyB,QAAQ,UAAU;AAC5E,SAAO,mBAAmB,MAAM,CAAC,eAAe;AAChD,SAAO,mBAAmB,IAAI,CAAC,WAAW,WAAW;EAErD,MAAM,aAAuB,EAAE;EAC/B,MAAM,UAAU,IAAI,aAAa;GAC/B,WAAW;GACX,WAAW,OAAO,SAAS;AACzB,eAAW,KAAK,KAAK;AACrB,WAAO,OAAO,GAAG,IAAI,UAAU,CAAC;;GAEnC,CAAC;AAEF,MAAI;AACF,WAAQ,OAAO;AACf,UAAO,QAAQ,UAAU,EAAE,EAAE,IAAI,yBAAyB;AAE1D,SAAM,kBAAkB;AAExB,UAAO,kBAAkB,WAAW,CAAC,CAAC,sBAAsB;;;;;QAK1D;YACM;AACR,WAAQ,MAAM;;GAEhB;EACF"}
|
|
1
|
+
{"version":3,"file":"event-tracker.test.js","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/implementations/event-tracker.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//===========================================\n// @vitest-environment jsdom\n\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { afterEach, describe, expect, it, vi } from \"vitest\";\nimport { EventTracker } from \"./event-tracker\";\n\nasync function advancePastFlush() {\n await vi.advanceTimersByTimeAsync(10_000);\n await Promise.resolve();\n}\n\nfunction getSentEventTypes(sentBodies: string[]) {\n const [body] = sentBodies;\n\n const payload = JSON.parse(body);\n if (typeof payload !== \"object\" || payload === null || !(\"events\" in payload) || !Array.isArray(payload.events)) {\n throw new Error(\"Expected analytics batch payload to include an events array.\");\n }\n\n return (payload.events as { event_type: string }[]).map((event) => event.event_type);\n}\n\ndescribe(\"EventTracker\", () => {\n afterEach(() => {\n vi.useRealTimers();\n });\n\n it(\"captures events when browser globals are exposed as accessor descriptors\", async () => {\n vi.useFakeTimers();\n document.body.innerHTML = \"<button>Open project</button>\";\n\n const screenDescriptor = Object.getOwnPropertyDescriptor(window, \"screen\");\n const historyDescriptor = Object.getOwnPropertyDescriptor(window, \"history\");\n expect(screenDescriptor?.value).toBeUndefined();\n expect(historyDescriptor?.value).toBeUndefined();\n expect(screenDescriptor?.get).toBeTypeOf(\"function\");\n expect(historyDescriptor?.get).toBeTypeOf(\"function\");\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n document.querySelector(\"button\")?.dispatchEvent(new MouseEvent(\"click\", {\n bubbles: true,\n clientX: 12,\n clientY: 34,\n }));\n\n await advancePastFlush();\n\n // Dead-click classification marks the buffered $click in place —\n // exactly one click event either way.\n expect(getSentEventTypes(sentBodies)).toMatchInlineSnapshot(`\n [\n \"$page-view\",\n \"$click\",\n ]\n `);\n } finally {\n tracker.stop();\n }\n });\n\n it(\"emits a PostHog-style elements_chain plus scaled pointer coords for $click\", async () => {\n vi.useFakeTimers();\n document.body.innerHTML = `\n <main>\n <section class=\"card panel\">\n <button id=\"save-btn\" data-testid=\"save\" aria-label=\"Save project\">Save changes</button>\n </section>\n </main>\n `;\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n const button = document.querySelector(\"#save-btn\");\n if (button == null) throw new Error(\"button missing\");\n button.dispatchEvent(new MouseEvent(\"click\", {\n bubbles: true,\n clientX: 100,\n clientY: 200,\n }));\n\n await advancePastFlush();\n\n const payload = JSON.parse(sentBodies[0] ?? \"{}\") as { events: { event_type: string, data: Record<string, unknown> }[] };\n const click = payload.events.find((event) => event.event_type === \"$click\");\n if (click == null) throw new Error(\"no $click event captured\");\n\n // elements_chain encodes the target leaf plus a few ancestors. Leaf is\n // first; segments are `;`-delimited. Assert against substrings rather\n // than the full string so jsdom layout quirks don't make this flaky.\n const chain = click.data.elements_chain;\n expect(typeof chain).toBe(\"string\");\n expect(chain).toContain('button');\n expect(chain).toContain('attr__id=\"save-btn\"');\n expect(chain).toContain('attr__data-testid=\"save\"');\n expect(chain).toContain('attr__aria-label=\"Save project\"');\n expect(chain).toContain('text=\"Save changes\"');\n // Ancestor section is in the chain too.\n expect(chain).toContain(\"section\");\n\n // Pre-scaled coords land in clickmap_events.pointer_*. SCALE_FACTOR=16.\n expect(click.data.x_scaled).toBe(Math.round(100 / 16));\n expect(click.data.y_scaled).toBe(Math.round(200 / 16));\n expect(click.data.client_y_scaled).toBe(Math.round(200 / 16));\n expect(click.data.scale_factor).toBe(16);\n expect(click.data.pointer_relative_x).toBeCloseTo(100 / window.innerWidth, 4);\n expect(click.data.pointer_target_fixed).toBe(0);\n\n // Legacy CSS selector still emitted for back-compat. The builder prefers\n // data-testid over id, so we assert against that anchor rather than #id.\n expect(click.data.selector).toContain('data-testid=\"save\"');\n expect(click.data.tag_name).toBe(\"button\");\n } finally {\n tracker.stop();\n }\n });\n\n it(\"ignores clicks inside the Hexclave dev tool\", async () => {\n vi.useFakeTimers();\n document.body.innerHTML = `\n <div id=\"__hexclave-dev-tool-root\">\n <button>Clickmap toolbar control</button>\n </div>\n `;\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n document.querySelector(\"button\")?.dispatchEvent(new MouseEvent(\"click\", {\n bubbles: true,\n clientX: 100,\n clientY: 200,\n }));\n\n await advancePastFlush();\n\n expect(getSentEventTypes(sentBodies)).toMatchInlineSnapshot(`\n [\n \"$page-view\",\n ]\n `);\n } finally {\n tracker.stop();\n }\n });\n\n it(\"flags pointer_target_fixed when the target sits under a fixed-position ancestor\", async () => {\n vi.useFakeTimers();\n document.body.innerHTML = `\n <header style=\"position: fixed; top: 0\">\n <button id=\"cta\">Sign up</button>\n </header>\n `;\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n document.querySelector(\"#cta\")?.dispatchEvent(new MouseEvent(\"click\", { bubbles: true }));\n await advancePastFlush();\n\n const payload = JSON.parse(sentBodies[0] ?? \"{}\") as { events: { event_type: string, data: Record<string, unknown> }[] };\n const click = payload.events.find((event) => event.event_type === \"$click\");\n expect(click?.data.pointer_target_fixed).toBe(1);\n } finally {\n tracker.stop();\n }\n });\n\n it(\"flags a click with no observable effect as dead on its single $click event\", async () => {\n vi.useFakeTimers();\n document.body.innerHTML = \"<button id=\\\"dead\\\">Does nothing</button>\";\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n const clickAtMs = Date.now();\n document.querySelector(\"#dead\")?.dispatchEvent(new MouseEvent(\"click\", {\n bubbles: true,\n clientX: 10,\n clientY: 20,\n }));\n\n await advancePastFlush();\n\n const payload = JSON.parse(sentBodies[0] ?? \"{}\") as { events: { event_type: string, event_at_ms: number, data: Record<string, unknown> }[] };\n const clicks = payload.events.filter((event) => event.event_type === \"$click\");\n expect(clicks).toHaveLength(1);\n const click = clicks[0];\n\n // One event per physical click: the buffered $click is marked dead in\n // place, still timestamped at the original click rather than at\n // classification time (~3s later).\n expect(click.data.dead).toBe(1);\n expect(click.event_at_ms).toBe(clickAtMs);\n } finally {\n tracker.stop();\n }\n });\n\n it(\"does not flag a click as dead when it mutates the DOM\", async () => {\n vi.useFakeTimers();\n document.body.innerHTML = \"<button id=\\\"live\\\">Adds content</button><div id=\\\"out\\\"></div>\";\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n const button = document.querySelector(\"#live\");\n if (button == null) throw new Error(\"button missing\");\n button.addEventListener(\"click\", () => {\n document.querySelector(\"#out\")?.appendChild(document.createElement(\"p\"));\n });\n button.dispatchEvent(new MouseEvent(\"click\", { bubbles: true }));\n // Let the MutationObserver microtask run so the mutation is recorded\n // before the dead-click sweeps start.\n await Promise.resolve();\n\n await advancePastFlush();\n\n const payload = JSON.parse(sentBodies[0] ?? \"{}\") as { events: { event_type: string, data: Record<string, unknown> }[] };\n const clicks = payload.events.filter((event) => event.event_type === \"$click\");\n expect(clicks).toHaveLength(1);\n expect(clicks[0].data.dead).toBeUndefined();\n } finally {\n tracker.stop();\n }\n });\n\n it(\"drains held clicks as alive on pagehide so navigation clicks are never lost\", async () => {\n vi.useFakeTimers();\n document.body.innerHTML = \"<a id=\\\"nav\\\" href=\\\"/pricing\\\">Pricing</a>\";\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n const clickAtMs = Date.now();\n document.querySelector(\"#nav\")?.dispatchEvent(new MouseEvent(\"click\", { bubbles: true }));\n\n // Navigation fires pagehide well before any classification sweep — the\n // keepalive flush ships the still-unclassified click as a plain (alive)\n // $click.\n window.dispatchEvent(new Event(\"pagehide\"));\n await Promise.resolve();\n await Promise.resolve();\n\n const payload = JSON.parse(sentBodies[0] ?? \"{}\") as { events: { event_type: string, event_at_ms: number, data: Record<string, unknown> }[] };\n const clicks = payload.events.filter((event) => event.event_type === \"$click\");\n expect(clicks).toHaveLength(1);\n expect(clicks[0].data.dead).toBeUndefined();\n expect(clicks[0].event_at_ms).toBe(clickAtMs);\n } finally {\n tracker.stop();\n }\n });\n\n it(\"holds an unclassified click out of a flush and ships it on the next one\", async () => {\n vi.useFakeTimers();\n document.body.innerHTML = \"<button id=\\\"late\\\">Late click</button>\";\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n // Click 500ms before the 10s flush tick: classification cannot finish\n // in time, so the flush must hold the click back rather than send it\n // unclassified.\n await vi.advanceTimersByTimeAsync(9_500);\n document.querySelector(\"#late\")?.dispatchEvent(new MouseEvent(\"click\", { bubbles: true }));\n await vi.advanceTimersByTimeAsync(500);\n\n expect(getSentEventTypes(sentBodies)).toMatchInlineSnapshot(`\n [\n \"$page-view\",\n ]\n `);\n\n // By the next flush the sweep has classified it (dead — nothing\n // observable happened) and it ships marked.\n await vi.advanceTimersByTimeAsync(10_000);\n const second = JSON.parse(sentBodies[1] ?? \"{}\") as { events: { event_type: string, data: Record<string, unknown> }[] };\n expect(second.events.map((event) => event.event_type)).toMatchInlineSnapshot(`\n [\n \"$click\",\n ]\n `);\n expect(second.events[0].data.dead).toBe(1);\n } finally {\n tracker.stop();\n }\n });\n\n it(\"captures client-side navigations when history is exposed as an accessor descriptor\", async () => {\n vi.useFakeTimers();\n\n const historyDescriptor = Object.getOwnPropertyDescriptor(window, \"history\");\n expect(historyDescriptor?.value).toBeUndefined();\n expect(historyDescriptor?.get).toBeTypeOf(\"function\");\n\n const sentBodies: string[] = [];\n const tracker = new EventTracker({\n projectId: \"internal\",\n sendBatch: async (body) => {\n sentBodies.push(body);\n return Result.ok(new Response());\n },\n });\n\n try {\n tracker.start();\n window.history.pushState({}, \"\", \"/projects/test-project\");\n\n await advancePastFlush();\n\n expect(getSentEventTypes(sentBodies)).toMatchInlineSnapshot(`\n [\n \"$page-view\",\n \"$page-view\",\n ]\n `);\n } finally {\n tracker.stop();\n }\n });\n});\n"],"mappings":"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"}
|
|
@@ -70,7 +70,7 @@ declare class _HexclaveServerAppImplIncomplete<HasTokenStore extends boolean, Pr
|
|
|
70
70
|
protected _serverNotificationCategoryFromCrud(userId: string, crud: NotificationPreferenceCrud['Server']['Read']): NotificationCategory;
|
|
71
71
|
protected _serverOAuthProviderFromCrud(crud: OAuthProviderCrud['Server']['Read']): {
|
|
72
72
|
id: string;
|
|
73
|
-
type: "google" | "github" | "microsoft" | "spotify" | "facebook" | "discord" | "gitlab" | "bitbucket" | "linkedin" | "apple" | "
|
|
73
|
+
type: "x" | "google" | "github" | "microsoft" | "spotify" | "facebook" | "discord" | "gitlab" | "bitbucket" | "linkedin" | "apple" | "twitch";
|
|
74
74
|
userId: string;
|
|
75
75
|
accountId: string;
|
|
76
76
|
email: string | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { HexclaveAssertionError, captureError, throwErr } from "@hexclave/shared/dist/utils/errors";
|
|
2
1
|
import { runAsynchronously } from "@hexclave/shared/dist/utils/promises";
|
|
2
|
+
import { HexclaveAssertionError, captureError, throwErr } from "@hexclave/shared/dist/utils/errors";
|
|
3
3
|
import { useMemo } from "react";
|
|
4
4
|
import { HexclaveServerInterface, KnownErrors } from "@hexclave/shared";
|
|
5
5
|
import { suspend } from "@hexclave/shared/dist/utils/react";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { captureWarning } from "@hexclave/shared/dist/utils/errors";
|
|
2
1
|
import { runAsynchronously } from "@hexclave/shared/dist/utils/promises";
|
|
2
|
+
import { captureWarning } from "@hexclave/shared/dist/utils/errors";
|
|
3
3
|
import { Result } from "@hexclave/shared/dist/utils/results";
|
|
4
4
|
import { isBrowserLike } from "@hexclave/shared/dist/utils/env";
|
|
5
5
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AnalyticsClickmapOptions, AnalyticsClickmapResponse, AnalyticsClickmapTokenResponse } from "@hexclave/shared/dist/interface/admin-metrics";
|
|
1
2
|
import { Result } from "@hexclave/shared/dist/utils/results";
|
|
2
3
|
import { InternalSession } from "@hexclave/shared/dist/sessions";
|
|
3
4
|
import { AsyncStoreProperty, EmailConfig } from "../../common";
|
|
@@ -234,6 +235,10 @@ type StackAdminApp<HasTokenStore extends boolean = boolean, ProjectId extends st
|
|
|
234
235
|
refundTransactionId: string;
|
|
235
236
|
}>;
|
|
236
237
|
queryAnalytics(options: AnalyticsQueryOptions): Promise<AnalyticsQueryResponse>;
|
|
238
|
+
getAnalyticsClickmap(options: AnalyticsClickmapOptions): Promise<AnalyticsClickmapResponse>;
|
|
239
|
+
createAnalyticsClickmapToken(options: {
|
|
240
|
+
origin: string;
|
|
241
|
+
}): Promise<AnalyticsClickmapTokenResponse>;
|
|
237
242
|
listSessionReplays(options?: ListSessionReplaysOptions$1): Promise<ListSessionReplaysResult$1>;
|
|
238
243
|
getSessionReplay(sessionReplayId: string): Promise<AdminSessionReplay$1>;
|
|
239
244
|
listSessionReplayChunks(sessionReplayId: string, options?: ListSessionReplayChunksOptions$1): Promise<ListSessionReplayChunksResult$1>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-app.d.ts","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/interfaces/admin-app.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"admin-app.d.ts","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/interfaces/admin-app.ts"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-app.js","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/interfaces/admin-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 { AnalyticsQueryOptions, AnalyticsQueryResponse } from \"@hexclave/shared/dist/interface/crud/analytics\";\nimport type { AdminGetSessionReplayChunkEventsResponse, AdminGetSessionReplayAllEventsResponse } from \"@hexclave/shared/dist/interface/crud/session-replays\";\nimport type { Transaction, TransactionType } from \"@hexclave/shared/dist/interface/crud/transactions\";\nimport { InternalSession } from \"@hexclave/shared/dist/sessions\";\nimport type { MoneyAmount } from \"@hexclave/shared/dist/utils/currency-constants\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { AsyncStoreProperty, EmailConfig } from \"../../common\";\nimport { AdminEmailOutbox, AdminSentEmail } from \"../../email\";\nimport { InternalApiKey, InternalApiKeyCreateOptions, InternalApiKeyFirstView } from \"../../internal-api-keys\";\nimport { AdminProjectPermission, AdminProjectPermissionDefinition, AdminProjectPermissionDefinitionCreateOptions, AdminProjectPermissionDefinitionUpdateOptions, AdminTeamPermission, AdminTeamPermissionDefinition, AdminTeamPermissionDefinitionCreateOptions, AdminTeamPermissionDefinitionUpdateOptions } from \"../../permissions\";\nimport { AdminProject } from \"../../projects\";\nimport { _HexclaveAdminAppImpl } from \"../implementations\";\nimport { StackServerApp, StackServerAppConstructorOptions } from \"./server-app\";\n\nexport type EmailOutboxListOptions = {\n status?: string,\n simpleStatus?: string,\n limit?: number,\n cursor?: string,\n};\n\nexport type EmailOutboxListResult = {\n items: AdminEmailOutbox[],\n nextCursor: string | null,\n};\n\nexport type EmailOutboxUpdateOptions = {\n isPaused?: boolean,\n scheduledAtMillis?: number,\n cancel?: boolean,\n tsxSource?: string,\n themeId?: string | null,\n};\n\nexport type ManagedEmailProviderSetupResult = {\n domainId: string,\n subdomain: string,\n senderLocalPart: string,\n nameServerRecords: string[],\n status: ManagedEmailProviderStatus[\"status\"],\n};\n\nexport type ManagedEmailProviderStatus = {\n status: \"pending_dns\" | \"pending_verification\" | \"verified\" | \"applied\" | \"failed\",\n};\n\nexport type ManagedEmailProviderListItem = {\n domainId: string,\n subdomain: string,\n senderLocalPart: string,\n status: ManagedEmailProviderStatus[\"status\"],\n nameServerRecords: string[],\n};\n\nimport type { AdminSessionReplay, ListSessionReplayChunksOptions, ListSessionReplayChunksResult, ListSessionReplaysOptions, ListSessionReplaysResult, SessionReplayAllEventsResult } from \"../../session-replays\";\nexport type { AdminSessionReplay, AdminSessionReplayChunk, ListSessionReplaysOptions, ListSessionReplaysResult, ListSessionReplayChunksOptions, ListSessionReplayChunksResult, SessionReplayAllEventsResult } from \"../../session-replays\";\n\n\n/** @deprecated Use `HexclaveAdminAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackAdminAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = (\n & StackServerAppConstructorOptions<HasTokenStore, ProjectId>\n & {\n superSecretAdminKey?: string,\n projectOwnerSession?: InternalSession | (() => Promise<string | null>),\n }\n);\n\n\n/** @deprecated Use `HexclaveAdminApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackAdminApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = (\n & AsyncStoreProperty<\"project\", [], AdminProject, false>\n & AsyncStoreProperty<\"internalApiKeys\", [], InternalApiKey[], true>\n & AsyncStoreProperty<\"teamPermissionDefinitions\", [], AdminTeamPermissionDefinition[], true>\n & AsyncStoreProperty<\"projectPermissionDefinitions\", [], AdminProjectPermissionDefinition[], true>\n & AsyncStoreProperty<\"emailThemes\", [], { id: string, displayName: string }[], true>\n & AsyncStoreProperty<\"emailPreview\", [{ themeId?: string | null | false, themeTsxSource?: string, templateId?: string, templateTsxSource?: string }], string, false>\n & AsyncStoreProperty<\"emailPreviewWithEditableMarkers\", [{ themeId?: string | null | false, themeTsxSource?: string, templateId?: string, templateTsxSource?: string, editableSource?: 'template' | 'theme' | 'both' }], { html: string, editableRegions?: Record<string, unknown> }, false> // THIS_LINE_PLATFORM react-like\n & AsyncStoreProperty<\"emailTemplates\", [], { id: string, displayName: string, themeId?: string, tsxSource: string }[], true>\n & AsyncStoreProperty<\"emailDrafts\", [], { id: string, displayName: string, themeId: string | undefined | false, tsxSource: string, sentAt: Date | null }[], true>\n & AsyncStoreProperty<\"stripeAccountInfo\", [], { account_id: string, charges_enabled: boolean, details_submitted: boolean, payouts_enabled: boolean } | null, false>\n & AsyncStoreProperty<\n \"transactions\",\n [{\n cursor?: string,\n limit?: number,\n type?: TransactionType,\n customerType?: 'user' | 'team' | 'custom',\n customerId?: string,\n }],\n { transactions: Transaction[], nextCursor: string | null },\n true\n >\n & {\n createInternalApiKey(options: InternalApiKeyCreateOptions): Promise<InternalApiKeyFirstView>,\n\n createTeamPermissionDefinition(data: AdminTeamPermissionDefinitionCreateOptions): Promise<AdminTeamPermission>,\n updateTeamPermissionDefinition(permissionId: string, data: AdminTeamPermissionDefinitionUpdateOptions): Promise<void>,\n deleteTeamPermissionDefinition(permissionId: string): Promise<void>,\n /**\n * @param options.query Free-text search; matches against permission ID and description.\n */\n listTeamPermissionDefinitionsPaginated(options: { limit: number, cursor?: string, query?: string }): Promise<{ items: AdminTeamPermissionDefinition[], nextCursor: string | null }>,\n\n createProjectPermissionDefinition(data: AdminProjectPermissionDefinitionCreateOptions): Promise<AdminProjectPermission>,\n updateProjectPermissionDefinition(permissionId: string, data: AdminProjectPermissionDefinitionUpdateOptions): Promise<void>,\n deleteProjectPermissionDefinition(permissionId: string): Promise<void>,\n\n useSvixToken(): { token: string, url: string | undefined }, // THIS_LINE_PLATFORM react-like\n\n sendTestEmail(options: {\n recipientEmail: string,\n emailConfig: EmailConfig,\n }): Promise<Result<undefined, { errorMessage: string }>>,\n\n sendTestWebhook(options: { endpointId: string }): Promise<Result<undefined, { errorMessage: string }>>,\n\n sendSignInInvitationEmail(email: string, callbackUrl: string): Promise<void>,\n\n listSentEmails(): Promise<AdminSentEmail[]>,\n setupManagedEmailProvider(options: { subdomain: string, senderLocalPart: string }): Promise<ManagedEmailProviderSetupResult>,\n checkManagedEmailStatus(options: { domainId: string, subdomain: string, senderLocalPart: string }): Promise<ManagedEmailProviderStatus>,\n listManagedEmailDomains(): Promise<ManagedEmailProviderListItem[]>,\n applyManagedEmailProvider(options: { domainId: string }): Promise<{ status: \"applied\" }>,\n deleteManagedEmailDomain(options: { resendDomainId: string }): Promise<{ status: \"deleted\" }>,\n\n useEmailTheme(id: string): { displayName: string, tsxSource: string }, // THIS_LINE_PLATFORM react-like\n createEmailTheme(displayName: string): Promise<{ id: string }>,\n updateEmailTheme(id: string, tsxSource: string): Promise<void>,\n deleteEmailTheme(id: string): Promise<void>,\n saveChatMessage(threadId: string, message: any): Promise<void>,\n listChatMessages(threadId: string): Promise<{ messages: Array<any> }>,\n rewriteTemplateSourceWithAI(templateTsxSource: string): Promise<{ tsxSource: string }>,\n updateEmailTemplate(id: string, tsxSource: string, themeId: string | null | false): Promise<{ renderedHtml: string }>,\n createEmailTemplate(displayName: string): Promise<{ id: string }>,\n deleteEmailTemplate(id: string): Promise<void>,\n\n setupPayments(): Promise<{ url: string }>,\n createStripeWidgetAccountSession(): Promise<{ client_secret: string }>,\n getPaymentMethodConfigs(): Promise<{ configId: string, methods: Array<{ id: string, name: string, enabled: boolean, available: boolean, overridable: boolean }> } | null>,\n updatePaymentMethodConfigs(configId: string, updates: Record<string, 'on' | 'off'>): Promise<void>,\n createEmailDraft(options: { displayName: string, themeId?: string | undefined | false, tsxSource?: string }): Promise<{ id: string }>,\n updateEmailDraft(id: string, data: { displayName?: string, themeId?: string | undefined | false, tsxSource?: string }): Promise<void>,\n deleteEmailDraft(id: string): Promise<void>,\n refreshEmailDrafts(): Promise<void>,\n createItemQuantityChange(options: (\n { userId: string, itemId: string, quantity: number, expiresAt?: string, description?: string } |\n { teamId: string, itemId: string, quantity: number, expiresAt?: string, description?: string } |\n { customCustomerId: string, itemId: string, quantity: number, expiresAt?: string, description?: string }\n )): Promise<void>,\n refundTransaction(options: {\n type: \"subscription\" | \"one-time-purchase\",\n id: string,\n invoiceId?: string,\n amountUsd: MoneyAmount,\n endAction?: \"now\" | \"at-period-end\",\n }): Promise<{ refundTransactionId: string }>,\n queryAnalytics(options: AnalyticsQueryOptions): Promise<AnalyticsQueryResponse>,\n\n listSessionReplays(options?: ListSessionReplaysOptions): Promise<ListSessionReplaysResult>,\n getSessionReplay(sessionReplayId: string): Promise<AdminSessionReplay>,\n listSessionReplayChunks(sessionReplayId: string, options?: ListSessionReplayChunksOptions): Promise<ListSessionReplayChunksResult>,\n getSessionReplayChunkEvents(sessionReplayId: string, chunkId: string): Promise<AdminGetSessionReplayChunkEventsResponse>,\n getSessionReplayEvents(sessionReplayId: string, options?: { offset?: number, limit?: number }): Promise<SessionReplayAllEventsResult>,\n\n // Email Outbox methods\n listOutboxEmails(options?: EmailOutboxListOptions): Promise<EmailOutboxListResult>,\n getOutboxEmail(id: string): Promise<AdminEmailOutbox>,\n updateOutboxEmail(id: string, options: EmailOutboxUpdateOptions): Promise<AdminEmailOutbox>,\n pauseOutboxEmail(id: string): Promise<AdminEmailOutbox>,\n unpauseOutboxEmail(id: string): Promise<AdminEmailOutbox>,\n cancelOutboxEmail(id: string): Promise<AdminEmailOutbox>,\n }\n & StackServerApp<HasTokenStore, ProjectId>\n);\n/** @deprecated Use `HexclaveAdminAppConstructor` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackAdminAppConstructor = {\n new <\n HasTokenStore extends boolean,\n ProjectId extends string\n >(options: StackAdminAppConstructorOptions<HasTokenStore, ProjectId>): StackAdminApp<HasTokenStore, ProjectId>,\n new(options: StackAdminAppConstructorOptions<boolean, string>): StackAdminApp<boolean, string>,\n};\nexport type HexclaveAdminAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackAdminAppConstructorOptions<HasTokenStore, ProjectId>;\nexport type HexclaveAdminApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = StackAdminApp<HasTokenStore, ProjectId>;\nexport type HexclaveAdminAppConstructor = StackAdminAppConstructor;\nexport const HexclaveAdminApp: HexclaveAdminAppConstructor = _HexclaveAdminAppImpl;\n/** @deprecated Use `HexclaveAdminApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport const StackAdminApp: StackAdminAppConstructor = HexclaveAdminApp;\n"],"mappings":";;;AA6LA,MAAa,mBAAgD;;AAE7D,MAAa,gBAA0C"}
|
|
1
|
+
{"version":3,"file":"admin-app.js","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/interfaces/admin-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 type { AnalyticsClickmapOptions, AnalyticsClickmapResponse, AnalyticsClickmapTokenResponse } from \"@hexclave/shared/dist/interface/admin-metrics\";\nimport { AnalyticsQueryOptions, AnalyticsQueryResponse } from \"@hexclave/shared/dist/interface/crud/analytics\";\nimport type { AdminGetSessionReplayChunkEventsResponse, AdminGetSessionReplayAllEventsResponse } from \"@hexclave/shared/dist/interface/crud/session-replays\";\nimport type { Transaction, TransactionType } from \"@hexclave/shared/dist/interface/crud/transactions\";\nimport { InternalSession } from \"@hexclave/shared/dist/sessions\";\nimport type { MoneyAmount } from \"@hexclave/shared/dist/utils/currency-constants\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { AsyncStoreProperty, EmailConfig } from \"../../common\";\nimport { AdminEmailOutbox, AdminSentEmail } from \"../../email\";\nimport { InternalApiKey, InternalApiKeyCreateOptions, InternalApiKeyFirstView } from \"../../internal-api-keys\";\nimport { AdminProjectPermission, AdminProjectPermissionDefinition, AdminProjectPermissionDefinitionCreateOptions, AdminProjectPermissionDefinitionUpdateOptions, AdminTeamPermission, AdminTeamPermissionDefinition, AdminTeamPermissionDefinitionCreateOptions, AdminTeamPermissionDefinitionUpdateOptions } from \"../../permissions\";\nimport { AdminProject } from \"../../projects\";\nimport { _HexclaveAdminAppImpl } from \"../implementations\";\nimport { StackServerApp, StackServerAppConstructorOptions } from \"./server-app\";\n\nexport type EmailOutboxListOptions = {\n status?: string,\n simpleStatus?: string,\n limit?: number,\n cursor?: string,\n};\n\nexport type EmailOutboxListResult = {\n items: AdminEmailOutbox[],\n nextCursor: string | null,\n};\n\nexport type EmailOutboxUpdateOptions = {\n isPaused?: boolean,\n scheduledAtMillis?: number,\n cancel?: boolean,\n tsxSource?: string,\n themeId?: string | null,\n};\n\nexport type ManagedEmailProviderSetupResult = {\n domainId: string,\n subdomain: string,\n senderLocalPart: string,\n nameServerRecords: string[],\n status: ManagedEmailProviderStatus[\"status\"],\n};\n\nexport type ManagedEmailProviderStatus = {\n status: \"pending_dns\" | \"pending_verification\" | \"verified\" | \"applied\" | \"failed\",\n};\n\nexport type ManagedEmailProviderListItem = {\n domainId: string,\n subdomain: string,\n senderLocalPart: string,\n status: ManagedEmailProviderStatus[\"status\"],\n nameServerRecords: string[],\n};\n\nimport type { AdminSessionReplay, ListSessionReplayChunksOptions, ListSessionReplayChunksResult, ListSessionReplaysOptions, ListSessionReplaysResult, SessionReplayAllEventsResult } from \"../../session-replays\";\nexport type { AdminSessionReplay, AdminSessionReplayChunk, ListSessionReplaysOptions, ListSessionReplaysResult, ListSessionReplayChunksOptions, ListSessionReplayChunksResult, SessionReplayAllEventsResult } from \"../../session-replays\";\n\n\n/** @deprecated Use `HexclaveAdminAppConstructorOptions` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackAdminAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = (\n & StackServerAppConstructorOptions<HasTokenStore, ProjectId>\n & {\n superSecretAdminKey?: string,\n projectOwnerSession?: InternalSession | (() => Promise<string | null>),\n }\n);\n\n\n/** @deprecated Use `HexclaveAdminApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackAdminApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = (\n & AsyncStoreProperty<\"project\", [], AdminProject, false>\n & AsyncStoreProperty<\"internalApiKeys\", [], InternalApiKey[], true>\n & AsyncStoreProperty<\"teamPermissionDefinitions\", [], AdminTeamPermissionDefinition[], true>\n & AsyncStoreProperty<\"projectPermissionDefinitions\", [], AdminProjectPermissionDefinition[], true>\n & AsyncStoreProperty<\"emailThemes\", [], { id: string, displayName: string }[], true>\n & AsyncStoreProperty<\"emailPreview\", [{ themeId?: string | null | false, themeTsxSource?: string, templateId?: string, templateTsxSource?: string }], string, false>\n & AsyncStoreProperty<\"emailPreviewWithEditableMarkers\", [{ themeId?: string | null | false, themeTsxSource?: string, templateId?: string, templateTsxSource?: string, editableSource?: 'template' | 'theme' | 'both' }], { html: string, editableRegions?: Record<string, unknown> }, false> // THIS_LINE_PLATFORM react-like\n & AsyncStoreProperty<\"emailTemplates\", [], { id: string, displayName: string, themeId?: string, tsxSource: string }[], true>\n & AsyncStoreProperty<\"emailDrafts\", [], { id: string, displayName: string, themeId: string | undefined | false, tsxSource: string, sentAt: Date | null }[], true>\n & AsyncStoreProperty<\"stripeAccountInfo\", [], { account_id: string, charges_enabled: boolean, details_submitted: boolean, payouts_enabled: boolean } | null, false>\n & AsyncStoreProperty<\n \"transactions\",\n [{\n cursor?: string,\n limit?: number,\n type?: TransactionType,\n customerType?: 'user' | 'team' | 'custom',\n customerId?: string,\n }],\n { transactions: Transaction[], nextCursor: string | null },\n true\n >\n & {\n createInternalApiKey(options: InternalApiKeyCreateOptions): Promise<InternalApiKeyFirstView>,\n\n createTeamPermissionDefinition(data: AdminTeamPermissionDefinitionCreateOptions): Promise<AdminTeamPermission>,\n updateTeamPermissionDefinition(permissionId: string, data: AdminTeamPermissionDefinitionUpdateOptions): Promise<void>,\n deleteTeamPermissionDefinition(permissionId: string): Promise<void>,\n /**\n * @param options.query Free-text search; matches against permission ID and description.\n */\n listTeamPermissionDefinitionsPaginated(options: { limit: number, cursor?: string, query?: string }): Promise<{ items: AdminTeamPermissionDefinition[], nextCursor: string | null }>,\n\n createProjectPermissionDefinition(data: AdminProjectPermissionDefinitionCreateOptions): Promise<AdminProjectPermission>,\n updateProjectPermissionDefinition(permissionId: string, data: AdminProjectPermissionDefinitionUpdateOptions): Promise<void>,\n deleteProjectPermissionDefinition(permissionId: string): Promise<void>,\n\n useSvixToken(): { token: string, url: string | undefined }, // THIS_LINE_PLATFORM react-like\n\n sendTestEmail(options: {\n recipientEmail: string,\n emailConfig: EmailConfig,\n }): Promise<Result<undefined, { errorMessage: string }>>,\n\n sendTestWebhook(options: { endpointId: string }): Promise<Result<undefined, { errorMessage: string }>>,\n\n sendSignInInvitationEmail(email: string, callbackUrl: string): Promise<void>,\n\n listSentEmails(): Promise<AdminSentEmail[]>,\n setupManagedEmailProvider(options: { subdomain: string, senderLocalPart: string }): Promise<ManagedEmailProviderSetupResult>,\n checkManagedEmailStatus(options: { domainId: string, subdomain: string, senderLocalPart: string }): Promise<ManagedEmailProviderStatus>,\n listManagedEmailDomains(): Promise<ManagedEmailProviderListItem[]>,\n applyManagedEmailProvider(options: { domainId: string }): Promise<{ status: \"applied\" }>,\n deleteManagedEmailDomain(options: { resendDomainId: string }): Promise<{ status: \"deleted\" }>,\n\n useEmailTheme(id: string): { displayName: string, tsxSource: string }, // THIS_LINE_PLATFORM react-like\n createEmailTheme(displayName: string): Promise<{ id: string }>,\n updateEmailTheme(id: string, tsxSource: string): Promise<void>,\n deleteEmailTheme(id: string): Promise<void>,\n saveChatMessage(threadId: string, message: any): Promise<void>,\n listChatMessages(threadId: string): Promise<{ messages: Array<any> }>,\n rewriteTemplateSourceWithAI(templateTsxSource: string): Promise<{ tsxSource: string }>,\n updateEmailTemplate(id: string, tsxSource: string, themeId: string | null | false): Promise<{ renderedHtml: string }>,\n createEmailTemplate(displayName: string): Promise<{ id: string }>,\n deleteEmailTemplate(id: string): Promise<void>,\n\n setupPayments(): Promise<{ url: string }>,\n createStripeWidgetAccountSession(): Promise<{ client_secret: string }>,\n getPaymentMethodConfigs(): Promise<{ configId: string, methods: Array<{ id: string, name: string, enabled: boolean, available: boolean, overridable: boolean }> } | null>,\n updatePaymentMethodConfigs(configId: string, updates: Record<string, 'on' | 'off'>): Promise<void>,\n createEmailDraft(options: { displayName: string, themeId?: string | undefined | false, tsxSource?: string }): Promise<{ id: string }>,\n updateEmailDraft(id: string, data: { displayName?: string, themeId?: string | undefined | false, tsxSource?: string }): Promise<void>,\n deleteEmailDraft(id: string): Promise<void>,\n refreshEmailDrafts(): Promise<void>,\n createItemQuantityChange(options: (\n { userId: string, itemId: string, quantity: number, expiresAt?: string, description?: string } |\n { teamId: string, itemId: string, quantity: number, expiresAt?: string, description?: string } |\n { customCustomerId: string, itemId: string, quantity: number, expiresAt?: string, description?: string }\n )): Promise<void>,\n refundTransaction(options: {\n type: \"subscription\" | \"one-time-purchase\",\n id: string,\n invoiceId?: string,\n amountUsd: MoneyAmount,\n endAction?: \"now\" | \"at-period-end\",\n }): Promise<{ refundTransactionId: string }>,\n queryAnalytics(options: AnalyticsQueryOptions): Promise<AnalyticsQueryResponse>,\n getAnalyticsClickmap(options: AnalyticsClickmapOptions): Promise<AnalyticsClickmapResponse>,\n createAnalyticsClickmapToken(options: { origin: string }): Promise<AnalyticsClickmapTokenResponse>,\n\n listSessionReplays(options?: ListSessionReplaysOptions): Promise<ListSessionReplaysResult>,\n getSessionReplay(sessionReplayId: string): Promise<AdminSessionReplay>,\n listSessionReplayChunks(sessionReplayId: string, options?: ListSessionReplayChunksOptions): Promise<ListSessionReplayChunksResult>,\n getSessionReplayChunkEvents(sessionReplayId: string, chunkId: string): Promise<AdminGetSessionReplayChunkEventsResponse>,\n getSessionReplayEvents(sessionReplayId: string, options?: { offset?: number, limit?: number }): Promise<SessionReplayAllEventsResult>,\n\n // Email Outbox methods\n listOutboxEmails(options?: EmailOutboxListOptions): Promise<EmailOutboxListResult>,\n getOutboxEmail(id: string): Promise<AdminEmailOutbox>,\n updateOutboxEmail(id: string, options: EmailOutboxUpdateOptions): Promise<AdminEmailOutbox>,\n pauseOutboxEmail(id: string): Promise<AdminEmailOutbox>,\n unpauseOutboxEmail(id: string): Promise<AdminEmailOutbox>,\n cancelOutboxEmail(id: string): Promise<AdminEmailOutbox>,\n }\n & StackServerApp<HasTokenStore, ProjectId>\n);\n/** @deprecated Use `HexclaveAdminAppConstructor` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport type StackAdminAppConstructor = {\n new <\n HasTokenStore extends boolean,\n ProjectId extends string\n >(options: StackAdminAppConstructorOptions<HasTokenStore, ProjectId>): StackAdminApp<HasTokenStore, ProjectId>,\n new(options: StackAdminAppConstructorOptions<boolean, string>): StackAdminApp<boolean, string>,\n};\nexport type HexclaveAdminAppConstructorOptions<HasTokenStore extends boolean, ProjectId extends string> = StackAdminAppConstructorOptions<HasTokenStore, ProjectId>;\nexport type HexclaveAdminApp<HasTokenStore extends boolean = boolean, ProjectId extends string = string> = StackAdminApp<HasTokenStore, ProjectId>;\nexport type HexclaveAdminAppConstructor = StackAdminAppConstructor;\nexport const HexclaveAdminApp: HexclaveAdminAppConstructor = _HexclaveAdminAppImpl;\n/** @deprecated Use `HexclaveAdminApp` from the `@hexclave/*` package instead — same symbol, new brand name. See https://docs.hexclave.com/migration. */\nexport const StackAdminApp: StackAdminAppConstructor = HexclaveAdminApp;\n"],"mappings":";;;AAgMA,MAAa,mBAAgD;;AAE7D,MAAa,gBAA0C"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { deindent } from "@hexclave/shared/dist/utils/strings";
|
|
3
4
|
import { TooltipProvider } from "@hexclave/ui";
|
|
4
5
|
import React from "react";
|
|
5
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
import Color from "color";
|
|
7
|
-
import { deindent } from "@hexclave/shared/dist/utils/strings";
|
|
8
8
|
import { globalCSS } from "../generated/global-css.js";
|
|
9
9
|
import { BrowserScript } from "../utils/browser-script.js";
|
|
10
10
|
import { DEFAULT_THEME } from "../utils/constants.js";
|