@hexclave/next 1.0.76 → 1.0.77
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-CsH-gVGz.d.ts → admin-app-impl-CxDpE89P.d.ts} +12 -10
- package/dist/admin-app-impl-CxDpE89P.d.ts.map +1 -0
- package/dist/clickmap/clickmap-core.d.ts +1 -1
- package/dist/clickmap/index.d.ts +1 -1
- package/dist/{client-app-BCT5p_70.d.ts → client-app-wFodsYml.d.ts} +4 -1
- package/dist/client-app-wFodsYml.d.ts.map +1 -0
- package/dist/common-BK_sydxF.d.ts.map +1 -1
- package/dist/components/api-key-dialogs.d.ts +1 -1
- package/dist/components/elements/sidebar-layout.d.ts.map +1 -1
- package/dist/components/elements/sidebar-layout.js +12 -2
- package/dist/components/elements/sidebar-layout.js.map +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/payments/payments-page.d.ts +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-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-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/components-page/team-invitation-cache.d.ts +5 -0
- package/dist/components-page/team-invitation-cache.d.ts.map +1 -0
- package/dist/components-page/team-invitation-cache.js +12 -0
- package/dist/components-page/team-invitation-cache.js.map +1 -0
- package/dist/components-page/team-invitation-cache.test.d.ts +1 -0
- package/dist/components-page/team-invitation-cache.test.js +23 -0
- package/dist/components-page/team-invitation-cache.test.js.map +1 -0
- package/dist/components-page/team-invitation.js +8 -7
- package/dist/components-page/team-invitation.js.map +1 -1
- package/dist/dev-tool/dev-tool-core.d.ts +1 -1
- package/dist/dev-tool/index.d.ts +1 -1
- package/dist/esm/components/api-key-dialogs.d.ts +1 -1
- package/dist/esm/components/elements/sidebar-layout.d.ts.map +1 -1
- package/dist/esm/components/elements/sidebar-layout.js +12 -2
- package/dist/esm/components/elements/sidebar-layout.js.map +1 -1
- package/dist/esm/components-page/team-invitation-cache.d.ts +5 -0
- package/dist/esm/components-page/team-invitation-cache.d.ts.map +1 -0
- package/dist/esm/components-page/team-invitation-cache.js +11 -0
- package/dist/esm/components-page/team-invitation-cache.js.map +1 -0
- package/dist/esm/components-page/team-invitation-cache.test.d.ts +1 -0
- package/dist/esm/components-page/team-invitation-cache.test.js +24 -0
- package/dist/esm/components-page/team-invitation-cache.test.js.map +1 -0
- package/dist/esm/components-page/team-invitation.d.ts.map +1 -1
- package/dist/esm/components-page/team-invitation.js +8 -7
- package/dist/esm/components-page/team-invitation.js.map +1 -1
- package/dist/esm/generated/quetzal-translations.d.ts +2 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +4 -4
- 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.automatic-side-effects.test.js +30 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +5 -3
- 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 +94 -21
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.d.ts +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js +83 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js.map +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.d.ts +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js +120 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js.map +1 -0
- package/dist/esm/lib/hexclave-app/apps/implementations/common.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/common.js +4 -3
- package/dist/esm/lib/hexclave-app/apps/implementations/common.js.map +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/index.js +1 -1
- package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +2 -2
- package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
- package/dist/esm/lib/hexclave-app/teams/index.d.ts +3 -0
- package/dist/esm/lib/hexclave-app/teams/index.d.ts.map +1 -1
- package/dist/esm/lib/hexclave-app/teams/index.js.map +1 -1
- package/dist/esm/utils/monkey-patch.d.ts +7 -0
- package/dist/esm/utils/monkey-patch.d.ts.map +1 -0
- package/dist/esm/utils/monkey-patch.js +20 -0
- package/dist/esm/utils/monkey-patch.js.map +1 -0
- package/dist/esm/utils/react.d.ts +17 -0
- package/dist/esm/utils/react.d.ts.map +1 -0
- package/dist/esm/utils/react.js +60 -0
- package/dist/esm/utils/react.js.map +1 -0
- package/dist/generated/quetzal-translations.d.ts +1 -1
- package/dist/{hexclave-provider-BA97jMlx.d.ts → hexclave-provider-CMz2mt4I.d.ts} +3 -3
- package/dist/{hexclave-provider-BA97jMlx.d.ts.map → hexclave-provider-CMz2mt4I.d.ts.map} +1 -1
- package/dist/{hooks-CUe5bc3s.d.ts → hooks-CUHt4Y9C.d.ts} +2 -2
- package/dist/{hooks-CUe5bc3s.d.ts.map → hooks-CUHt4Y9C.d.ts.map} +1 -1
- package/dist/{index-CvB7XacB.d.ts → index-fR0LkUK7.d.ts} +2 -2
- package/dist/{index-CvB7XacB.d.ts.map → index-fR0LkUK7.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.automatic-side-effects.test.js +29 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +2 -2
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +93 -19
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.d.ts +1 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js +82 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.js.map +1 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.d.ts +1 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js +119 -0
- package/dist/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.js.map +1 -0
- package/dist/lib/hexclave-app/apps/implementations/common.js +4 -3
- package/dist/lib/hexclave-app/apps/implementations/common.js.map +1 -1
- package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
- package/dist/lib/hexclave-app/apps/implementations/index.js +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/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/teams/index.d.ts +1 -1
- package/dist/lib/hexclave-app/teams/index.js.map +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/{quetzal-translations-CK45_4Dm.d.ts → quetzal-translations-B2jT2SWm.d.ts} +3 -3
- package/dist/{quetzal-translations-CK45_4Dm.d.ts.map → quetzal-translations-B2jT2SWm.d.ts.map} +1 -1
- package/dist/team-invitation-B5Ol7vdd.d.ts.map +1 -1
- package/dist/{translation-provider-DQ3BJepJ.d.ts → translation-provider-6505O9P2.d.ts} +2 -2
- package/dist/{translation-provider-DQ3BJepJ.d.ts.map → translation-provider-6505O9P2.d.ts.map} +1 -1
- package/dist/utils/monkey-patch.d.ts +7 -0
- package/dist/utils/monkey-patch.d.ts.map +1 -0
- package/dist/utils/monkey-patch.js +23 -0
- package/dist/utils/monkey-patch.js.map +1 -0
- package/dist/utils/react.d.ts +17 -0
- package/dist/utils/react.d.ts.map +1 -0
- package/dist/utils/react.js +63 -0
- package/dist/utils/react.js.map +1 -0
- package/package.json +4 -4
- package/src/components/elements/sidebar-layout.tsx +16 -1
- package/src/components-page/team-invitation-cache.test.ts +25 -0
- package/src/components-page/team-invitation-cache.ts +13 -0
- package/src/components-page/team-invitation.tsx +16 -7
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.ts +38 -1
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +2 -3
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.sign-out.test.ts +96 -0
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +134 -24
- package/src/lib/hexclave-app/apps/implementations/client-app-impl.untrusted-redirect-card.test.ts +146 -0
- package/src/lib/hexclave-app/apps/implementations/common.ts +2 -1
- package/src/lib/hexclave-app/teams/index.ts +3 -0
- package/src/utils/monkey-patch.tsx +31 -0
- package/src/utils/react.tsx +93 -0
- package/dist/admin-app-impl-CsH-gVGz.d.ts.map +0 -1
- package/dist/client-app-BCT5p_70.d.ts.map +0 -1
package/dist/dev-tool/index.d.ts
CHANGED
|
@@ -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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidebar-layout.d.ts","names":[],"sources":["../../../../src/components/elements/sidebar-layout.tsx"],"mappings":";;;KAaY,WAAA;EACV,KAAA,EAAO,KAAA,CAAM,SAAA;EACb,IAAA;EACA,WAAA,GAAc,KAAA,CAAM,SAAA;EACpB,EAAA;EACA,IAAA,GAAO,KAAA,CAAM,SAAA;EACb,OAAA,GAAU,KAAA,CAAM,SAAA;EAChB,YAAA,GAAe,KAAA,CAAM,SAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"sidebar-layout.d.ts","names":[],"sources":["../../../../src/components/elements/sidebar-layout.tsx"],"mappings":";;;KAaY,WAAA;EACV,KAAA,EAAO,KAAA,CAAM,SAAA;EACb,IAAA;EACA,WAAA,GAAc,KAAA,CAAM,SAAA;EACpB,EAAA;EACA,IAAA,GAAO,KAAA,CAAM,SAAA;EACb,OAAA,GAAU,KAAA,CAAM,SAAA;EAChB,YAAA,GAAe,KAAA,CAAM,SAAA;AAAA;AAAA,iBAkBP,aAAA,CAAc,KAAA;EAAS,KAAA,EAAO,WAAA;EAAe,KAAA,GAAQ,SAAS;EAAE,SAAA;AAAA,gCAAoB,GAAA,CAAA,OAAA"}
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Button, Typography, cn } from "@hexclave/ui";
|
|
3
|
-
import "react";
|
|
3
|
+
import React from "react";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { XIcon } from "lucide-react";
|
|
6
|
-
import { useHash } from "@hexclave/shared/dist/hooks/use-hash";
|
|
7
6
|
import { useStackApp } from "../../index.js";
|
|
7
|
+
import { suspendIfSsr } from "../../utils/react.js";
|
|
8
8
|
//#region src/components/elements/sidebar-layout.tsx
|
|
9
|
+
function normalizeHash(hash) {
|
|
10
|
+
return hash.startsWith("#") ? hash.slice(1) : hash;
|
|
11
|
+
}
|
|
12
|
+
function useHash() {
|
|
13
|
+
suspendIfSsr();
|
|
14
|
+
return React.useSyncExternalStore((onStoreChange) => {
|
|
15
|
+
window.addEventListener("hashchange", onStoreChange);
|
|
16
|
+
return () => window.removeEventListener("hashchange", onStoreChange);
|
|
17
|
+
}, () => normalizeHash(window.location.hash));
|
|
18
|
+
}
|
|
9
19
|
function SidebarLayout(props) {
|
|
10
20
|
const hash = useHash();
|
|
11
21
|
const selectedIndex = props.items.findIndex((item) => item.id && item.id === hash);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidebar-layout.js","names":[],"sources":["../../../../src/components/elements/sidebar-layout.tsx"],"sourcesContent":["'use client';\n\n\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 {
|
|
1
|
+
{"version":3,"file":"sidebar-layout.js","names":[],"sources":["../../../../src/components/elements/sidebar-layout.tsx"],"sourcesContent":["'use client';\n\n\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 { Button, Typography, cn } from '@hexclave/ui';\nimport { XIcon } from 'lucide-react';\nimport React, { ReactNode } from 'react';\nimport { useStackApp } from '../..';\nimport { suspendIfSsr } from '../../utils/react';\n\nexport type SidebarItem = {\n title: React.ReactNode,\n type: 'item' | 'divider',\n description?: React.ReactNode,\n id?: string,\n icon?: React.ReactNode,\n content?: React.ReactNode,\n contentTitle?: React.ReactNode,\n}\n\nfunction normalizeHash(hash: string) {\n return hash.startsWith(\"#\") ? hash.slice(1) : hash;\n}\n\nfunction useHash() {\n suspendIfSsr();\n return React.useSyncExternalStore(\n (onStoreChange) => {\n window.addEventListener(\"hashchange\", onStoreChange);\n return () => window.removeEventListener(\"hashchange\", onStoreChange);\n },\n () => normalizeHash(window.location.hash),\n );\n}\n\nexport function SidebarLayout(props: { items: SidebarItem[], title?: ReactNode, className?: string }) {\n const hash = useHash();\n const selectedIndex = props.items.findIndex(item => item.id && (item.id === hash));\n return (\n <>\n <div className={cn(\"hidden sm:flex stack-scope h-full\", props.className)}>\n <DesktopLayout items={props.items} title={props.title} selectedIndex={selectedIndex} />\n </div>\n <div className={cn(\"sm:hidden stack-scope h-full\", props.className)}>\n <MobileLayout items={props.items} title={props.title} selectedIndex={selectedIndex} />\n </div>\n </>\n );\n}\n\nfunction Items(props: { items: SidebarItem[], selectedIndex: number }) {\n const app = useStackApp();\n const navigate = app.useNavigate();\n\n\n const activeItemIndex = props.selectedIndex === -1 ? 0 : props.selectedIndex;\n\n return props.items.map((item, index) => (\n item.type === 'item' ?\n <Button\n key={index}\n variant='ghost'\n size='sm'\n className={cn(\n activeItemIndex === index && \"sm:bg-muted\",\n \"justify-start text-md text-zinc-800 dark:text-zinc-300 px-2 text-left\",\n )}\n onClick={() => {\n if (item.id) {\n navigate('#' + item.id);\n }\n }}\n >\n {item.icon}\n {item.title}\n </Button> :\n <Typography key={index}>\n {item.title}\n </Typography>\n ));\n\n}\n\nfunction DesktopLayout(props: { items: SidebarItem[], title?: ReactNode, selectedIndex: number }) {\n const selectedItem = props.items[props.selectedIndex === -1 ? 0 : props.selectedIndex];\n\n return (\n <div className=\"stack-scope flex w-full h-full max-w-full relative\">\n <div className=\"flex max-w-[200px] min-w-[200px] border-r flex-col items-stretch gap-2 p-2 overflow-y-auto\">\n {props.title && <div className='mb-2 ml-2'>\n <Typography type='h2' className=\"text-lg font-semibold text-zinc-800 dark:text-zinc-300\">{props.title}</Typography>\n </div>}\n\n <Items items={props.items} selectedIndex={props.selectedIndex} />\n </div>\n <div className=\"flex-1 w-0 flex justify-center gap-4 py-2 px-4\">\n <div className='flex flex-col max-w-[800px] w-[800px]'>\n <div className='mt-4 mb-6'>\n <Typography type='h4' className='font-semibold'>{selectedItem.title}</Typography>\n {selectedItem.description && <Typography variant='secondary' type='label'>{selectedItem.description}</Typography>}\n </div>\n <div className='flex-1'>\n {selectedItem.content}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction MobileLayout(props: { items: SidebarItem[], title?: ReactNode, selectedIndex: number }) {\n const selectedItem = props.items[props.selectedIndex];\n const app = useStackApp();\n const navigate = app.useNavigate();\n\n if (props.selectedIndex === -1) {\n return (\n <div className=\"flex flex-col gap-2 p-2\">\n {props.title && <div className='mb-2 ml-2'>\n <Typography type='h2' className=\"text-lg font-semibold text-zinc-800 dark:text-zinc-300\">{props.title}</Typography>\n </div>}\n\n <Items items={props.items} selectedIndex={props.selectedIndex} />\n </div>\n );\n } else {\n return (\n <div className=\"flex-1 flex flex-col gap-4 py-2 px-4\">\n <div className='flex flex-col'>\n <div className='flex justify-between'>\n <Typography type='h4' className='font-semibold'>{selectedItem.title}</Typography>\n <Button\n variant='ghost'\n size='icon'\n onClick={() => { navigate('#'); }}\n >\n <XIcon className='h-5 w-5' />\n </Button>\n </div>\n {selectedItem.description && <Typography variant='secondary' type='label'>{selectedItem.description}</Typography>}\n </div>\n <div className='flex-1'>\n {selectedItem.content}\n </div>\n </div>\n );\n }\n}\n"],"mappings":";;;;;;;;AAuBA,SAAS,cAAc,MAAc;CACnC,OAAO,KAAK,WAAW,GAAG,IAAI,KAAK,MAAM,CAAC,IAAI;AAChD;AAEA,SAAS,UAAU;CACjB,aAAa;CACb,OAAO,MAAM,sBACV,kBAAkB;EACjB,OAAO,iBAAiB,cAAc,aAAa;EACnD,aAAa,OAAO,oBAAoB,cAAc,aAAa;CACrE,SACM,cAAc,OAAO,SAAS,IAAI,CAC1C;AACF;AAEA,SAAgB,cAAc,OAAwE;CACpG,MAAM,OAAO,QAAQ;CACrB,MAAM,gBAAgB,MAAM,MAAM,WAAU,SAAQ,KAAK,MAAO,KAAK,OAAO,IAAK;CACjF,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,OAAD;EAAK,WAAW,GAAG,qCAAqC,MAAM,SAAS;YACrE,oBAAC,eAAD;GAAe,OAAO,MAAM;GAAO,OAAO,MAAM;GAAsB;EAAgB,CAAA;CACnF,CAAA,GACL,oBAAC,OAAD;EAAK,WAAW,GAAG,gCAAgC,MAAM,SAAS;YAChE,oBAAC,cAAD;GAAc,OAAO,MAAM;GAAO,OAAO,MAAM;GAAsB;EAAgB,CAAA;CAClF,CAAA,CACL,EAAA,CAAA;AAEN;AAEA,SAAS,MAAM,OAAwD;CAErE,MAAM,WADM,YACO,CAAC,CAAC,YAAY;CAGjC,MAAM,kBAAkB,MAAM,kBAAkB,KAAK,IAAI,MAAM;CAE/D,OAAO,MAAM,MAAM,KAAK,MAAM,UAC5B,KAAK,SAAS,SACZ,qBAAC,QAAD;EAEE,SAAQ;EACR,MAAK;EACL,WAAW,GACT,oBAAoB,SAAS,eAC7B,uEACF;EACA,eAAe;GACb,IAAI,KAAK,IACP,SAAS,MAAM,KAAK,EAAE;EAE1B;YAZF,CAcG,KAAK,MACL,KAAK,KACA;IAfD,KAeC,IACR,oBAAC,YAAD,EAAA,UACG,KAAK,MACI,GAFK,KAEL,CACf;AAEH;AAEA,SAAS,cAAc,OAA2E;CAChG,MAAM,eAAe,MAAM,MAAM,MAAM,kBAAkB,KAAK,IAAI,MAAM;CAExE,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,MAAM,SAAS,oBAAC,OAAD;IAAK,WAAU;cAC7B,oBAAC,YAAD;KAAY,MAAK;KAAK,WAAU;eAA0D,MAAM;IAAkB,CAAA;GAC/G,CAAA,GAEL,oBAAC,OAAD;IAAO,OAAO,MAAM;IAAO,eAAe,MAAM;GAAgB,CAAA,CAC7D;MACL,oBAAC,OAAD;GAAK,WAAU;aACb,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,qBAAC,OAAD;KAAK,WAAU;eAAf,CACE,oBAAC,YAAD;MAAY,MAAK;MAAK,WAAU;gBAAiB,aAAa;KAAkB,CAAA,GAC/E,aAAa,eAAe,oBAAC,YAAD;MAAY,SAAQ;MAAY,MAAK;gBAAS,aAAa;KAAwB,CAAA,CAC7G;QACL,oBAAC,OAAD;KAAK,WAAU;eACZ,aAAa;IACX,CAAA,CACF;;EACF,CAAA,CACF;;AAET;AAEA,SAAS,aAAa,OAA2E;CAC/F,MAAM,eAAe,MAAM,MAAM,MAAM;CAEvC,MAAM,WADM,YACO,CAAC,CAAC,YAAY;CAEjC,IAAI,MAAM,kBAAkB,IAC1B,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACG,MAAM,SAAS,oBAAC,OAAD;GAAK,WAAU;aAC7B,oBAAC,YAAD;IAAY,MAAK;IAAK,WAAU;cAA0D,MAAM;GAAkB,CAAA;EAC/G,CAAA,GAEL,oBAAC,OAAD;GAAO,OAAO,MAAM;GAAO,eAAe,MAAM;EAAgB,CAAA,CAC7D;;MAGP,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,YAAD;KAAY,MAAK;KAAK,WAAU;eAAiB,aAAa;IAAkB,CAAA,GAChF,oBAAC,QAAD;KACE,SAAQ;KACR,MAAK;KACL,eAAe;MAAE,SAAS,GAAG;KAAG;eAEhC,oBAAC,OAAD,EAAO,WAAU,UAAW,CAAA;IACtB,CAAA,CACL;OACJ,aAAa,eAAe,oBAAC,YAAD;IAAY,SAAQ;IAAY,MAAK;cAAS,aAAa;GAAwB,CAAA,CAC7G;MACL,oBAAC,OAAD;GAAK,WAAU;aACZ,aAAa;EACX,CAAA,CACF;;AAGX"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
//#region src/components-page/team-invitation-cache.d.ts
|
|
2
|
+
declare function cacheTeamInvitationOperation<TApp extends object, TResult>(operation: (app: TApp, code: string) => Promise<TResult>): (app: TApp, session: object, code: string) => Promise<TResult>;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { cacheTeamInvitationOperation };
|
|
5
|
+
//# sourceMappingURL=team-invitation-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-invitation-cache.d.ts","names":[],"sources":["../../../src/components-page/team-invitation-cache.ts"],"mappings":";iBAMgB,4BAAA,+BACd,SAAA,GAAY,GAAA,EAAK,IAAA,EAAM,IAAA,aAAiB,OAAA,CAAQ,OAAA,KAC9C,GAAA,EAAK,IAAA,EAAM,OAAA,UAAiB,IAAA,aAAiB,OAAA,CAAQ,OAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { cacheFunction } from "@hexclave/shared/dist/utils/caches";
|
|
2
|
+
//#region src/components-page/team-invitation-cache.ts
|
|
3
|
+
function cacheTeamInvitationOperation(operation) {
|
|
4
|
+
return cacheFunction(async (app, _session, code) => {
|
|
5
|
+
return await operation(app, code);
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { cacheTeamInvitationOperation };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=team-invitation-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-invitation-cache.js","names":[],"sources":["../../../src/components-page/team-invitation-cache.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 { cacheFunction } from \"@hexclave/shared/dist/utils/caches\";\n\nexport function cacheTeamInvitationOperation<TApp extends object, TResult>(\n operation: (app: TApp, code: string) => Promise<TResult>,\n): (app: TApp, session: object, code: string) => Promise<TResult> {\n return cacheFunction(async (app: TApp, _session: object, code: string) => {\n return await operation(app, code);\n });\n}\n"],"mappings":";;AAMA,SAAgB,6BACd,WACgE;CAChE,OAAO,cAAc,OAAO,KAAW,UAAkB,SAAiB;EACxE,OAAO,MAAM,UAAU,KAAK,IAAI;CAClC,CAAC;AACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { cacheTeamInvitationOperation } from "./team-invitation-cache.js";
|
|
3
|
+
//#region src/components-page/team-invitation-cache.test.ts
|
|
4
|
+
describe("cacheTeamInvitationOperation", () => {
|
|
5
|
+
it("reuses results within a session but not across sessions", async () => {
|
|
6
|
+
let resultNumber = 0;
|
|
7
|
+
const operation = vi.fn(async (_app, _code) => {
|
|
8
|
+
resultNumber += 1;
|
|
9
|
+
return resultNumber;
|
|
10
|
+
});
|
|
11
|
+
const cachedOperation = cacheTeamInvitationOperation(operation);
|
|
12
|
+
const app = {};
|
|
13
|
+
const firstSession = {};
|
|
14
|
+
const secondSession = {};
|
|
15
|
+
await expect(cachedOperation(app, firstSession, "shared-code")).resolves.toBe(1);
|
|
16
|
+
await expect(cachedOperation(app, firstSession, "shared-code")).resolves.toBe(1);
|
|
17
|
+
await expect(cachedOperation(app, secondSession, "shared-code")).resolves.toBe(2);
|
|
18
|
+
expect(operation).toHaveBeenCalledTimes(2);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
//#endregion
|
|
22
|
+
export {};
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=team-invitation-cache.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-invitation-cache.test.js","names":[],"sources":["../../../src/components-page/team-invitation-cache.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 { describe, expect, it, vi } from \"vitest\";\nimport { cacheTeamInvitationOperation } from \"./team-invitation-cache\";\n\ndescribe(\"cacheTeamInvitationOperation\", () => {\n it(\"reuses results within a session but not across sessions\", async () => {\n let resultNumber = 0;\n const operation = vi.fn(async (_app: object, _code: string) => {\n resultNumber += 1;\n return resultNumber;\n });\n const cachedOperation = cacheTeamInvitationOperation(operation);\n const app = {};\n const firstSession = {};\n const secondSession = {};\n\n await expect(cachedOperation(app, firstSession, \"shared-code\")).resolves.toBe(1);\n await expect(cachedOperation(app, firstSession, \"shared-code\")).resolves.toBe(1);\n await expect(cachedOperation(app, secondSession, \"shared-code\")).resolves.toBe(2);\n expect(operation).toHaveBeenCalledTimes(2);\n });\n});\n"],"mappings":";;;AAOA,SAAS,sCAAsC;CAC7C,GAAG,2DAA2D,YAAY;EACxE,IAAI,eAAe;EACnB,MAAM,YAAY,GAAG,GAAG,OAAO,MAAc,UAAkB;GAC7D,gBAAgB;GAChB,OAAO;EACT,CAAC;EACD,MAAM,kBAAkB,6BAA6B,SAAS;EAC9D,MAAM,MAAM,CAAC;EACb,MAAM,eAAe,CAAC;EACtB,MAAM,gBAAgB,CAAC;EAEvB,MAAM,OAAO,gBAAgB,KAAK,cAAc,aAAa,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC;EAC/E,MAAM,OAAO,gBAAgB,KAAK,cAAc,aAAa,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC;EAC/E,MAAM,OAAO,gBAAgB,KAAK,eAAe,aAAa,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC;EAChF,OAAO,SAAS,CAAC,CAAC,sBAAsB,CAAC;CAC3C,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-invitation.d.ts","names":[],"sources":["../../../src/components-page/team-invitation.tsx"],"mappings":";
|
|
1
|
+
{"version":3,"file":"team-invitation.d.ts","names":[],"sources":["../../../src/components-page/team-invitation.tsx"],"mappings":";iBA2EgB,cAAA;EAAiB,QAAA;EAAgB;AAAA;EAAkB,QAAA;EAAoB,YAAA,EAAc,MAAA;AAAA,gCAAwB,GAAA,CAAA,OAAA"}
|
|
@@ -8,12 +8,12 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
import { KnownErrors } from "@hexclave/shared";
|
|
9
9
|
import { use } from "@hexclave/shared/dist/utils/react";
|
|
10
10
|
import { PredefinedMessageCard } from "../components/message-cards/predefined-message-card.js";
|
|
11
|
-
import {
|
|
11
|
+
import { cacheTeamInvitationOperation } from "./team-invitation-cache.js";
|
|
12
12
|
//#region src/components-page/team-invitation.tsx
|
|
13
|
-
const cachedVerifyInvitation =
|
|
13
|
+
const cachedVerifyInvitation = cacheTeamInvitationOperation(async (hexclaveApp, code) => {
|
|
14
14
|
return await hexclaveApp.verifyTeamInvitationCode(code);
|
|
15
15
|
});
|
|
16
|
-
const cachedGetInvitationDetails =
|
|
16
|
+
const cachedGetInvitationDetails = cacheTeamInvitationOperation(async (hexclaveApp, code) => {
|
|
17
17
|
return await hexclaveApp.getTeamInvitationDetails(code);
|
|
18
18
|
});
|
|
19
19
|
function TeamInvitationInner(props) {
|
|
@@ -21,7 +21,7 @@ function TeamInvitationInner(props) {
|
|
|
21
21
|
const hexclaveApp = useStackApp();
|
|
22
22
|
const [success, setSuccess] = React.useState(false);
|
|
23
23
|
const [errorMessage, setErrorMessage] = React.useState(null);
|
|
24
|
-
const details = use(cachedGetInvitationDetails(hexclaveApp, props.searchParams.code || ""));
|
|
24
|
+
const details = use(cachedGetInvitationDetails(hexclaveApp, props.session, props.searchParams.code || ""));
|
|
25
25
|
if (errorMessage || details.status === "error") return /* @__PURE__ */ jsx(PredefinedMessageCard, {
|
|
26
26
|
type: "unknownError",
|
|
27
27
|
fullPage: props.fullPage
|
|
@@ -85,7 +85,7 @@ function TeamInvitation({ fullPage = false, searchParams }) {
|
|
|
85
85
|
secondaryAction: () => hexclaveApp.redirectToHome(),
|
|
86
86
|
children: /* @__PURE__ */ jsx(Typography, { children: t("Please complete your account setup before joining teams.") })
|
|
87
87
|
});
|
|
88
|
-
const verificationResult = use(cachedVerifyInvitation(hexclaveApp, searchParams.code || ""));
|
|
88
|
+
const verificationResult = use(cachedVerifyInvitation(hexclaveApp, user._internalSession, searchParams.code || ""));
|
|
89
89
|
if (verificationResult.status === "error") {
|
|
90
90
|
const error = verificationResult.error;
|
|
91
91
|
if (KnownErrors.VerificationCodeNotFound.isInstance(error)) return invalidJsx;
|
|
@@ -95,8 +95,9 @@ function TeamInvitation({ fullPage = false, searchParams }) {
|
|
|
95
95
|
}
|
|
96
96
|
return /* @__PURE__ */ jsx(TeamInvitationInner, {
|
|
97
97
|
fullPage,
|
|
98
|
-
searchParams
|
|
99
|
-
|
|
98
|
+
searchParams,
|
|
99
|
+
session: user._internalSession
|
|
100
|
+
}, user.id);
|
|
100
101
|
}
|
|
101
102
|
//#endregion
|
|
102
103
|
export { TeamInvitation };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-invitation.js","names":[],"sources":["../../../src/components-page/team-invitation.tsx"],"sourcesContent":["'use client';\n\n\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 { KnownErrors } from \"@hexclave/shared\";\nimport {
|
|
1
|
+
{"version":3,"file":"team-invitation.js","names":[],"sources":["../../../src/components-page/team-invitation.tsx"],"sourcesContent":["'use client';\n\n\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 { KnownErrors } from \"@hexclave/shared\";\nimport { runAsynchronouslyWithAlert } from \"@hexclave/shared/dist/utils/promises\";\nimport { use } from \"@hexclave/shared/dist/utils/react\";\nimport { Typography } from \"@hexclave/ui\";\nimport React from \"react\";\nimport { MessageCard, StackClientApp, useStackApp, useUser } from \"..\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\nimport { useTranslation } from \"../lib/translations\";\nimport { cacheTeamInvitationOperation } from \"./team-invitation-cache\";\n\n// Both endpoints inspect the current account, so the session must participate in\n// the key even though the SDK app object and invitation code are otherwise stable.\nconst cachedVerifyInvitation = cacheTeamInvitationOperation(async (hexclaveApp: StackClientApp<true>, code: string) => {\n return await hexclaveApp.verifyTeamInvitationCode(code);\n});\n\nconst cachedGetInvitationDetails = cacheTeamInvitationOperation(async (hexclaveApp: StackClientApp<true>, code: string) => {\n return await hexclaveApp.getTeamInvitationDetails(code);\n});\n\nfunction TeamInvitationInner(props: { fullPage?: boolean, searchParams: Record<string, string>, session: object }) {\n const { t } = useTranslation();\n const hexclaveApp = useStackApp();\n const [success, setSuccess] = React.useState(false);\n const [errorMessage, setErrorMessage] = React.useState<string | null>(null);\n const details = use(cachedGetInvitationDetails(hexclaveApp, props.session, props.searchParams.code || ''));\n\n if (errorMessage || details.status === 'error') {\n return (\n <PredefinedMessageCard type=\"unknownError\" fullPage={props.fullPage} />\n );\n }\n\n if (success) {\n return (\n <MessageCard\n title={t('Team invitation')}\n fullPage={props.fullPage}\n primaryButtonText=\"Go home\"\n primaryAction={() => hexclaveApp.redirectToHome()}\n >\n <Typography>You have successfully joined {details.data.teamDisplayName}</Typography>\n </MessageCard>\n );\n }\n\n\n return (\n <MessageCard\n title={t('Team invitation')}\n fullPage={props.fullPage}\n primaryButtonText={t('Join')}\n primaryAction={() => runAsynchronouslyWithAlert(async () => {\n const result = await hexclaveApp.acceptTeamInvitation(props.searchParams.code || '');\n if (result.status === 'error') {\n setErrorMessage(result.error.message);\n } else {\n setSuccess(true);\n }\n })}\n secondaryButtonText={t('Ignore')}\n secondaryAction={() => hexclaveApp.redirectToHome()}\n >\n <Typography>You are invited to join {details.data.teamDisplayName}</Typography>\n </MessageCard>\n );\n}\n\nexport function TeamInvitation({ fullPage=false, searchParams }: { fullPage?: boolean, searchParams: Record<string, string> }) {\n const { t } = useTranslation();\n // Include restricted users to detect if user needs to complete onboarding\n const user = useUser({ includeRestricted: true });\n const hexclaveApp = useStackApp();\n\n const invalidJsx = (\n <MessageCard title={t('Invalid Team Invitation Link')} fullPage={fullPage}>\n <Typography>{t('Please double check if you have the correct team invitation link.')}</Typography>\n </MessageCard>\n );\n\n const expiredJsx = (\n <MessageCard title={t('Expired Team Invitation Link')} fullPage={fullPage}>\n <Typography>{t('Your team invitation link has expired. Please request a new team invitation link ')}</Typography>\n </MessageCard>\n );\n\n const usedJsx = (\n <MessageCard title={t('Used Team Invitation Link')} fullPage={fullPage}>\n <Typography>{t('This team invitation link has already been used.')}</Typography>\n </MessageCard>\n );\n\n const code = searchParams.code;\n if (!code) {\n return invalidJsx;\n }\n\n if (!user) {\n return (\n <MessageCard\n title={t('Team invitation')}\n fullPage={fullPage}\n primaryButtonText={t('Sign in')}\n primaryAction={() => hexclaveApp.redirectToSignIn()}\n secondaryButtonText={t('Cancel')}\n secondaryAction={() => hexclaveApp.redirectToHome()}\n >\n <Typography>{t('Sign in or create an account to join the team.')}</Typography>\n </MessageCard>\n );\n }\n\n // User is restricted (needs to complete onboarding) - redirect to onboarding\n if (user.isRestricted) {\n return (\n <MessageCard\n title={t('Complete your account setup')}\n fullPage={fullPage}\n primaryButtonText={t('Complete setup')}\n primaryAction={() => hexclaveApp.redirectToOnboarding()}\n secondaryButtonText={t('Cancel')}\n secondaryAction={() => hexclaveApp.redirectToHome()}\n >\n <Typography>{t('Please complete your account setup before joining teams.')}</Typography>\n </MessageCard>\n );\n }\n\n const verificationResult = use(cachedVerifyInvitation(hexclaveApp, user._internalSession, searchParams.code || ''));\n\n if (verificationResult.status === 'error') {\n const error = verificationResult.error;\n if (KnownErrors.VerificationCodeNotFound.isInstance(error)) {\n return invalidJsx;\n } else if (KnownErrors.VerificationCodeExpired.isInstance(error)) {\n return expiredJsx;\n } else if (KnownErrors.VerificationCodeAlreadyUsed.isInstance(error)) {\n return usedJsx;\n } else {\n throw error;\n }\n }\n\n return (\n <TeamInvitationInner\n key={user.id}\n fullPage={fullPage}\n searchParams={searchParams}\n session={user._internalSession}\n />\n );\n};\n"],"mappings":"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"}
|