@stackframe/stack 2.5.1 → 2.5.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @stackframe/stack
2
2
 
3
+ ## 2.5.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Bugfixes
8
+ - Updated dependencies
9
+ - @stackframe/stack-shared@2.5.3
10
+ - @stackframe/stack-sc@2.5.3
11
+ - @stackframe/stack-ui@2.5.3
12
+
13
+ ## 2.5.2
14
+
15
+ ### Patch Changes
16
+
17
+ - Team profile pictures
18
+ - Updated dependencies
19
+ - @stackframe/stack-shared@2.5.2
20
+ - @stackframe/stack-ui@2.5.2
21
+ - @stackframe/stack-sc@2.5.2
22
+
3
23
  ## 2.5.1
4
24
 
5
25
  ### Patch Changes
@@ -25,14 +25,18 @@ __export(selected_team_switcher_exports, {
25
25
  SelectedTeamSwitcher: () => SelectedTeamSwitcher
26
26
  });
27
27
  module.exports = __toCommonJS(selected_team_switcher_exports);
28
- var import__ = require("..");
29
28
  var import_promises = require("@stackframe/stack-shared/dist/utils/promises");
30
- var import_navigation = require("next/navigation");
31
29
  var import_stack_ui = require("@stackframe/stack-ui");
30
+ var import_navigation = require("next/navigation");
32
31
  var import_react = require("react");
32
+ var import__ = require("..");
33
33
  var import_jsx_runtime = require("react/jsx-runtime");
34
34
  function TeamIcon(props) {
35
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-center justify-center w-6 h-6 mr-2 rounded bg-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: props.displayName.slice(0, 1).toUpperCase() }) });
35
+ if (props.team.profileImageUrl) {
36
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-6 h-6 mr-2 rounded bg-gray-200 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: props.team.profileImageUrl, alt: props.team.displayName, className: "w-6 h-6" }) });
37
+ } else {
38
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-center justify-center w-6 h-6 mr-2 rounded bg-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: props.team.displayName.slice(0, 1).toUpperCase() }) });
39
+ }
36
40
  }
37
41
  function SelectedTeamSwitcher(props) {
38
42
  const user = (0, import__.useUser)();
@@ -67,7 +71,7 @@ function SelectedTeamSwitcher(props) {
67
71
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SelectTrigger, { className: "stack-scope", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SelectValue, { placeholder: "Select team" }) }),
68
72
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.SelectContent, { className: "stack-scope", children: [
69
73
  teams && teams.map((team) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SelectItem, { value: team.id, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center", children: [
70
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TeamIcon, { displayName: team.displayName }),
74
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TeamIcon, { team }),
71
75
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: team.displayName })
72
76
  ] }) }, team.id)),
73
77
  teams?.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SelectGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SelectLabel, { children: "No teams" }) })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/selected-team-switcher.tsx"],"sourcesContent":["'use client';\nimport { Team, useUser } from \"..\";\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { useRouter } from \"next/navigation\";\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n Typography,\n} from \"@stackframe/stack-ui\";\nimport { useEffect, useMemo } from \"react\";\n\ntype SelectedTeamSwitcherProps = {\n urlMap?: (team: Team) => string,\n selectedTeam?: Team,\n noUpdateSelectedTeam?: boolean,\n};\n\nfunction TeamIcon(props: { displayName: string }) {\n return (\n <div className=\"flex items-center justify-center w-6 h-6 mr-2 rounded bg-gray-200\">\n <Typography>{props.displayName.slice(0, 1).toUpperCase()}</Typography>\n </div>\n );\n}\n\nexport function SelectedTeamSwitcher(props: SelectedTeamSwitcherProps) {\n const user = useUser();\n const router = useRouter();\n const selectedTeam = user?.selectedTeam || props.selectedTeam;\n const rawTeams = user?.useTeams();\n const teams = useMemo(() => rawTeams?.sort((a, b) => b.id === selectedTeam?.id ? 1 : -1), [rawTeams, selectedTeam]);\n\n useEffect(() => {\n if (!props.noUpdateSelectedTeam && props.selectedTeam) {\n runAsynchronouslyWithAlert(user?.setSelectedTeam(props.selectedTeam));\n }\n }, [props.noUpdateSelectedTeam, props.selectedTeam]);\n\n return (\n <Select \n value={selectedTeam?.id}\n onValueChange={(value) => {\n runAsynchronouslyWithAlert(async () => {\n const team = teams?.find(team => team.id === value);\n if (!team) {\n throw new Error('Team not found, this should not happen');\n }\n\n if (!props.noUpdateSelectedTeam) {\n await user?.setSelectedTeam(team);\n }\n if (props.urlMap) {\n router.push(props.urlMap(team));\n }\n });\n }}\n >\n <SelectTrigger className=\"stack-scope\">\n <SelectValue placeholder=\"Select team\"/>\n </SelectTrigger>\n <SelectContent className=\"stack-scope\">\n {teams && teams.map(team => (\n <SelectItem value={team.id} key={team.id}>\n <div className=\"flex items-center\">\n <TeamIcon displayName={team.displayName} />\n <Typography>{team.displayName}</Typography>\n </div>\n </SelectItem>\n ))}\n\n {teams?.length === 0 && (\n <SelectGroup>\n <SelectLabel>No teams</SelectLabel>\n </SelectGroup>\n )}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,eAA8B;AAC9B,sBAA2C;AAC3C,wBAA0B;AAC1B,sBASO;AACP,mBAAmC;AAW7B;AAHN,SAAS,SAAS,OAAgC;AAChD,SACE,4CAAC,SAAI,WAAU,qEACb,sDAAC,8BAAY,gBAAM,YAAY,MAAM,GAAG,CAAC,EAAE,YAAY,GAAE,GAC3D;AAEJ;AAEO,SAAS,qBAAqB,OAAkC;AACrE,QAAM,WAAO,kBAAQ;AACrB,QAAM,aAAS,6BAAU;AACzB,QAAM,eAAe,MAAM,gBAAgB,MAAM;AACjD,QAAM,WAAW,MAAM,SAAS;AAChC,QAAM,YAAQ,sBAAQ,MAAM,UAAU,KAAK,CAAC,GAAG,MAAM,EAAE,OAAO,cAAc,KAAK,IAAI,EAAE,GAAG,CAAC,UAAU,YAAY,CAAC;AAElH,8BAAU,MAAM;AACd,QAAI,CAAC,MAAM,wBAAwB,MAAM,cAAc;AACrD,sDAA2B,MAAM,gBAAgB,MAAM,YAAY,CAAC;AAAA,IACtE;AAAA,EACF,GAAG,CAAC,MAAM,sBAAsB,MAAM,YAAY,CAAC;AAEnD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,cAAc;AAAA,MACrB,eAAe,CAAC,UAAU;AACxB,wDAA2B,YAAY;AACrC,gBAAM,OAAO,OAAO,KAAK,CAAAA,UAAQA,MAAK,OAAO,KAAK;AAClD,cAAI,CAAC,MAAM;AACT,kBAAM,IAAI,MAAM,wCAAwC;AAAA,UAC1D;AAEA,cAAI,CAAC,MAAM,sBAAsB;AAC/B,kBAAM,MAAM,gBAAgB,IAAI;AAAA,UAClC;AACA,cAAI,MAAM,QAAQ;AAChB,mBAAO,KAAK,MAAM,OAAO,IAAI,CAAC;AAAA,UAChC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA;AAAA,oDAAC,iCAAc,WAAU,eACvB,sDAAC,+BAAY,aAAY,eAAa,GACxC;AAAA,QACA,6CAAC,iCAAc,WAAU,eACtB;AAAA,mBAAS,MAAM,IAAI,UAClB,4CAAC,8BAAW,OAAO,KAAK,IACtB,uDAAC,SAAI,WAAU,qBACb;AAAA,wDAAC,YAAS,aAAa,KAAK,aAAa;AAAA,YACzC,4CAAC,8BAAY,eAAK,aAAY;AAAA,aAChC,KAJ+B,KAAK,EAKtC,CACD;AAAA,UAEA,OAAO,WAAW,KACjB,4CAAC,+BACC,sDAAC,+BAAY,sBAAQ,GACvB;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;","names":["team"]}
1
+ {"version":3,"sources":["../../src/components/selected-team-switcher.tsx"],"sourcesContent":["'use client';\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n Typography\n} from \"@stackframe/stack-ui\";\nimport { useRouter } from \"next/navigation\";\nimport { useEffect, useMemo } from \"react\";\nimport { Team, useUser } from \"..\";\n\ntype SelectedTeamSwitcherProps = {\n urlMap?: (team: Team) => string,\n selectedTeam?: Team,\n noUpdateSelectedTeam?: boolean,\n};\n\nfunction TeamIcon(props: { team: Team }) {\n if (props.team.profileImageUrl) {\n return (\n <div className=\"w-6 h-6 mr-2 rounded bg-gray-200 overflow-hidden\">\n <img src={props.team.profileImageUrl} alt={props.team.displayName} className=\"w-6 h-6\" />\n </div>\n );\n } else {\n return (\n <div className=\"flex items-center justify-center w-6 h-6 mr-2 rounded bg-gray-200\">\n <Typography>{props.team.displayName.slice(0, 1).toUpperCase()}</Typography>\n </div>\n );\n }\n}\n\nexport function SelectedTeamSwitcher(props: SelectedTeamSwitcherProps) {\n const user = useUser();\n const router = useRouter();\n const selectedTeam = user?.selectedTeam || props.selectedTeam;\n const rawTeams = user?.useTeams();\n const teams = useMemo(() => rawTeams?.sort((a, b) => b.id === selectedTeam?.id ? 1 : -1), [rawTeams, selectedTeam]);\n\n useEffect(() => {\n if (!props.noUpdateSelectedTeam && props.selectedTeam) {\n runAsynchronouslyWithAlert(user?.setSelectedTeam(props.selectedTeam));\n }\n }, [props.noUpdateSelectedTeam, props.selectedTeam]);\n\n return (\n <Select \n value={selectedTeam?.id}\n onValueChange={(value) => {\n runAsynchronouslyWithAlert(async () => {\n const team = teams?.find(team => team.id === value);\n if (!team) {\n throw new Error('Team not found, this should not happen');\n }\n\n if (!props.noUpdateSelectedTeam) {\n await user?.setSelectedTeam(team);\n }\n if (props.urlMap) {\n router.push(props.urlMap(team));\n }\n });\n }}\n >\n <SelectTrigger className=\"stack-scope\">\n <SelectValue placeholder=\"Select team\"/>\n </SelectTrigger>\n <SelectContent className=\"stack-scope\">\n {teams && teams.map(team => (\n <SelectItem value={team.id} key={team.id}>\n <div className=\"flex items-center\">\n <TeamIcon team={team} />\n <Typography>{team.displayName}</Typography>\n </div>\n </SelectItem>\n ))}\n\n {teams?.length === 0 && (\n <SelectGroup>\n <SelectLabel>No teams</SelectLabel>\n </SelectGroup>\n )}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,sBAA2C;AAC3C,sBASO;AACP,wBAA0B;AAC1B,mBAAmC;AACnC,eAA8B;AAYtB;AAJR,SAAS,SAAS,OAAuB;AACvC,MAAI,MAAM,KAAK,iBAAiB;AAC9B,WACE,4CAAC,SAAI,WAAU,oDACb,sDAAC,SAAI,KAAK,MAAM,KAAK,iBAAiB,KAAK,MAAM,KAAK,aAAa,WAAU,WAAU,GACzF;AAAA,EAEJ,OAAO;AACL,WACE,4CAAC,SAAI,WAAU,qEACb,sDAAC,8BAAY,gBAAM,KAAK,YAAY,MAAM,GAAG,CAAC,EAAE,YAAY,GAAE,GAChE;AAAA,EAEJ;AACF;AAEO,SAAS,qBAAqB,OAAkC;AACrE,QAAM,WAAO,kBAAQ;AACrB,QAAM,aAAS,6BAAU;AACzB,QAAM,eAAe,MAAM,gBAAgB,MAAM;AACjD,QAAM,WAAW,MAAM,SAAS;AAChC,QAAM,YAAQ,sBAAQ,MAAM,UAAU,KAAK,CAAC,GAAG,MAAM,EAAE,OAAO,cAAc,KAAK,IAAI,EAAE,GAAG,CAAC,UAAU,YAAY,CAAC;AAElH,8BAAU,MAAM;AACd,QAAI,CAAC,MAAM,wBAAwB,MAAM,cAAc;AACrD,sDAA2B,MAAM,gBAAgB,MAAM,YAAY,CAAC;AAAA,IACtE;AAAA,EACF,GAAG,CAAC,MAAM,sBAAsB,MAAM,YAAY,CAAC;AAEnD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,cAAc;AAAA,MACrB,eAAe,CAAC,UAAU;AACxB,wDAA2B,YAAY;AACrC,gBAAM,OAAO,OAAO,KAAK,CAAAA,UAAQA,MAAK,OAAO,KAAK;AAClD,cAAI,CAAC,MAAM;AACT,kBAAM,IAAI,MAAM,wCAAwC;AAAA,UAC1D;AAEA,cAAI,CAAC,MAAM,sBAAsB;AAC/B,kBAAM,MAAM,gBAAgB,IAAI;AAAA,UAClC;AACA,cAAI,MAAM,QAAQ;AAChB,mBAAO,KAAK,MAAM,OAAO,IAAI,CAAC;AAAA,UAChC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA;AAAA,oDAAC,iCAAc,WAAU,eACvB,sDAAC,+BAAY,aAAY,eAAa,GACxC;AAAA,QACA,6CAAC,iCAAc,WAAU,eACtB;AAAA,mBAAS,MAAM,IAAI,UAClB,4CAAC,8BAAW,OAAO,KAAK,IACtB,uDAAC,SAAI,WAAU,qBACb;AAAA,wDAAC,YAAS,MAAY;AAAA,YACtB,4CAAC,8BAAY,eAAK,aAAY;AAAA,aAChC,KAJ+B,KAAK,EAKtC,CACD;AAAA,UAEA,OAAO,WAAW,KACjB,4CAAC,+BACC,sDAAC,+BAAY,sBAAQ,GACvB;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;","names":["team"]}
@@ -2,9 +2,7 @@
2
2
  "use client";
3
3
 
4
4
  // src/components/selected-team-switcher.tsx
5
- import { useUser } from "..";
6
5
  import { runAsynchronouslyWithAlert } from "@stackframe/stack-shared/dist/utils/promises";
7
- import { useRouter } from "next/navigation";
8
6
  import {
9
7
  Select,
10
8
  SelectContent,
@@ -15,10 +13,16 @@ import {
15
13
  SelectValue,
16
14
  Typography
17
15
  } from "@stackframe/stack-ui";
16
+ import { useRouter } from "next/navigation";
18
17
  import { useEffect, useMemo } from "react";
18
+ import { useUser } from "..";
19
19
  import { jsx, jsxs } from "react/jsx-runtime";
20
20
  function TeamIcon(props) {
21
- return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-6 h-6 mr-2 rounded bg-gray-200", children: /* @__PURE__ */ jsx(Typography, { children: props.displayName.slice(0, 1).toUpperCase() }) });
21
+ if (props.team.profileImageUrl) {
22
+ return /* @__PURE__ */ jsx("div", { className: "w-6 h-6 mr-2 rounded bg-gray-200 overflow-hidden", children: /* @__PURE__ */ jsx("img", { src: props.team.profileImageUrl, alt: props.team.displayName, className: "w-6 h-6" }) });
23
+ } else {
24
+ return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-6 h-6 mr-2 rounded bg-gray-200", children: /* @__PURE__ */ jsx(Typography, { children: props.team.displayName.slice(0, 1).toUpperCase() }) });
25
+ }
22
26
  }
23
27
  function SelectedTeamSwitcher(props) {
24
28
  const user = useUser();
@@ -53,7 +57,7 @@ function SelectedTeamSwitcher(props) {
53
57
  /* @__PURE__ */ jsx(SelectTrigger, { className: "stack-scope", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select team" }) }),
54
58
  /* @__PURE__ */ jsxs(SelectContent, { className: "stack-scope", children: [
55
59
  teams && teams.map((team) => /* @__PURE__ */ jsx(SelectItem, { value: team.id, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
56
- /* @__PURE__ */ jsx(TeamIcon, { displayName: team.displayName }),
60
+ /* @__PURE__ */ jsx(TeamIcon, { team }),
57
61
  /* @__PURE__ */ jsx(Typography, { children: team.displayName })
58
62
  ] }) }, team.id)),
59
63
  teams?.length === 0 && /* @__PURE__ */ jsx(SelectGroup, { children: /* @__PURE__ */ jsx(SelectLabel, { children: "No teams" }) })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/selected-team-switcher.tsx"],"sourcesContent":["'use client';\nimport { Team, useUser } from \"..\";\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { useRouter } from \"next/navigation\";\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n Typography,\n} from \"@stackframe/stack-ui\";\nimport { useEffect, useMemo } from \"react\";\n\ntype SelectedTeamSwitcherProps = {\n urlMap?: (team: Team) => string,\n selectedTeam?: Team,\n noUpdateSelectedTeam?: boolean,\n};\n\nfunction TeamIcon(props: { displayName: string }) {\n return (\n <div className=\"flex items-center justify-center w-6 h-6 mr-2 rounded bg-gray-200\">\n <Typography>{props.displayName.slice(0, 1).toUpperCase()}</Typography>\n </div>\n );\n}\n\nexport function SelectedTeamSwitcher(props: SelectedTeamSwitcherProps) {\n const user = useUser();\n const router = useRouter();\n const selectedTeam = user?.selectedTeam || props.selectedTeam;\n const rawTeams = user?.useTeams();\n const teams = useMemo(() => rawTeams?.sort((a, b) => b.id === selectedTeam?.id ? 1 : -1), [rawTeams, selectedTeam]);\n\n useEffect(() => {\n if (!props.noUpdateSelectedTeam && props.selectedTeam) {\n runAsynchronouslyWithAlert(user?.setSelectedTeam(props.selectedTeam));\n }\n }, [props.noUpdateSelectedTeam, props.selectedTeam]);\n\n return (\n <Select \n value={selectedTeam?.id}\n onValueChange={(value) => {\n runAsynchronouslyWithAlert(async () => {\n const team = teams?.find(team => team.id === value);\n if (!team) {\n throw new Error('Team not found, this should not happen');\n }\n\n if (!props.noUpdateSelectedTeam) {\n await user?.setSelectedTeam(team);\n }\n if (props.urlMap) {\n router.push(props.urlMap(team));\n }\n });\n }}\n >\n <SelectTrigger className=\"stack-scope\">\n <SelectValue placeholder=\"Select team\"/>\n </SelectTrigger>\n <SelectContent className=\"stack-scope\">\n {teams && teams.map(team => (\n <SelectItem value={team.id} key={team.id}>\n <div className=\"flex items-center\">\n <TeamIcon displayName={team.displayName} />\n <Typography>{team.displayName}</Typography>\n </div>\n </SelectItem>\n ))}\n\n {teams?.length === 0 && (\n <SelectGroup>\n <SelectLabel>No teams</SelectLabel>\n </SelectGroup>\n )}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":";;;AACA,SAAe,eAAe;AAC9B,SAAS,kCAAkC;AAC3C,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,WAAW,eAAe;AAW7B,cA2CM,YA3CN;AAHN,SAAS,SAAS,OAAgC;AAChD,SACE,oBAAC,SAAI,WAAU,qEACb,8BAAC,cAAY,gBAAM,YAAY,MAAM,GAAG,CAAC,EAAE,YAAY,GAAE,GAC3D;AAEJ;AAEO,SAAS,qBAAqB,OAAkC;AACrE,QAAM,OAAO,QAAQ;AACrB,QAAM,SAAS,UAAU;AACzB,QAAM,eAAe,MAAM,gBAAgB,MAAM;AACjD,QAAM,WAAW,MAAM,SAAS;AAChC,QAAM,QAAQ,QAAQ,MAAM,UAAU,KAAK,CAAC,GAAG,MAAM,EAAE,OAAO,cAAc,KAAK,IAAI,EAAE,GAAG,CAAC,UAAU,YAAY,CAAC;AAElH,YAAU,MAAM;AACd,QAAI,CAAC,MAAM,wBAAwB,MAAM,cAAc;AACrD,iCAA2B,MAAM,gBAAgB,MAAM,YAAY,CAAC;AAAA,IACtE;AAAA,EACF,GAAG,CAAC,MAAM,sBAAsB,MAAM,YAAY,CAAC;AAEnD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,cAAc;AAAA,MACrB,eAAe,CAAC,UAAU;AACxB,mCAA2B,YAAY;AACrC,gBAAM,OAAO,OAAO,KAAK,CAAAA,UAAQA,MAAK,OAAO,KAAK;AAClD,cAAI,CAAC,MAAM;AACT,kBAAM,IAAI,MAAM,wCAAwC;AAAA,UAC1D;AAEA,cAAI,CAAC,MAAM,sBAAsB;AAC/B,kBAAM,MAAM,gBAAgB,IAAI;AAAA,UAClC;AACA,cAAI,MAAM,QAAQ;AAChB,mBAAO,KAAK,MAAM,OAAO,IAAI,CAAC;AAAA,UAChC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA;AAAA,4BAAC,iBAAc,WAAU,eACvB,8BAAC,eAAY,aAAY,eAAa,GACxC;AAAA,QACA,qBAAC,iBAAc,WAAU,eACtB;AAAA,mBAAS,MAAM,IAAI,UAClB,oBAAC,cAAW,OAAO,KAAK,IACtB,+BAAC,SAAI,WAAU,qBACb;AAAA,gCAAC,YAAS,aAAa,KAAK,aAAa;AAAA,YACzC,oBAAC,cAAY,eAAK,aAAY;AAAA,aAChC,KAJ+B,KAAK,EAKtC,CACD;AAAA,UAEA,OAAO,WAAW,KACjB,oBAAC,eACC,8BAAC,eAAY,sBAAQ,GACvB;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;","names":["team"]}
1
+ {"version":3,"sources":["../../../src/components/selected-team-switcher.tsx"],"sourcesContent":["'use client';\nimport { runAsynchronouslyWithAlert } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n Typography\n} from \"@stackframe/stack-ui\";\nimport { useRouter } from \"next/navigation\";\nimport { useEffect, useMemo } from \"react\";\nimport { Team, useUser } from \"..\";\n\ntype SelectedTeamSwitcherProps = {\n urlMap?: (team: Team) => string,\n selectedTeam?: Team,\n noUpdateSelectedTeam?: boolean,\n};\n\nfunction TeamIcon(props: { team: Team }) {\n if (props.team.profileImageUrl) {\n return (\n <div className=\"w-6 h-6 mr-2 rounded bg-gray-200 overflow-hidden\">\n <img src={props.team.profileImageUrl} alt={props.team.displayName} className=\"w-6 h-6\" />\n </div>\n );\n } else {\n return (\n <div className=\"flex items-center justify-center w-6 h-6 mr-2 rounded bg-gray-200\">\n <Typography>{props.team.displayName.slice(0, 1).toUpperCase()}</Typography>\n </div>\n );\n }\n}\n\nexport function SelectedTeamSwitcher(props: SelectedTeamSwitcherProps) {\n const user = useUser();\n const router = useRouter();\n const selectedTeam = user?.selectedTeam || props.selectedTeam;\n const rawTeams = user?.useTeams();\n const teams = useMemo(() => rawTeams?.sort((a, b) => b.id === selectedTeam?.id ? 1 : -1), [rawTeams, selectedTeam]);\n\n useEffect(() => {\n if (!props.noUpdateSelectedTeam && props.selectedTeam) {\n runAsynchronouslyWithAlert(user?.setSelectedTeam(props.selectedTeam));\n }\n }, [props.noUpdateSelectedTeam, props.selectedTeam]);\n\n return (\n <Select \n value={selectedTeam?.id}\n onValueChange={(value) => {\n runAsynchronouslyWithAlert(async () => {\n const team = teams?.find(team => team.id === value);\n if (!team) {\n throw new Error('Team not found, this should not happen');\n }\n\n if (!props.noUpdateSelectedTeam) {\n await user?.setSelectedTeam(team);\n }\n if (props.urlMap) {\n router.push(props.urlMap(team));\n }\n });\n }}\n >\n <SelectTrigger className=\"stack-scope\">\n <SelectValue placeholder=\"Select team\"/>\n </SelectTrigger>\n <SelectContent className=\"stack-scope\">\n {teams && teams.map(team => (\n <SelectItem value={team.id} key={team.id}>\n <div className=\"flex items-center\">\n <TeamIcon team={team} />\n <Typography>{team.displayName}</Typography>\n </div>\n </SelectItem>\n ))}\n\n {teams?.length === 0 && (\n <SelectGroup>\n <SelectLabel>No teams</SelectLabel>\n </SelectGroup>\n )}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":";;;AACA,SAAS,kCAAkC;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB;AAC1B,SAAS,WAAW,eAAe;AACnC,SAAe,eAAe;AAYtB,cAkDI,YAlDJ;AAJR,SAAS,SAAS,OAAuB;AACvC,MAAI,MAAM,KAAK,iBAAiB;AAC9B,WACE,oBAAC,SAAI,WAAU,oDACb,8BAAC,SAAI,KAAK,MAAM,KAAK,iBAAiB,KAAK,MAAM,KAAK,aAAa,WAAU,WAAU,GACzF;AAAA,EAEJ,OAAO;AACL,WACE,oBAAC,SAAI,WAAU,qEACb,8BAAC,cAAY,gBAAM,KAAK,YAAY,MAAM,GAAG,CAAC,EAAE,YAAY,GAAE,GAChE;AAAA,EAEJ;AACF;AAEO,SAAS,qBAAqB,OAAkC;AACrE,QAAM,OAAO,QAAQ;AACrB,QAAM,SAAS,UAAU;AACzB,QAAM,eAAe,MAAM,gBAAgB,MAAM;AACjD,QAAM,WAAW,MAAM,SAAS;AAChC,QAAM,QAAQ,QAAQ,MAAM,UAAU,KAAK,CAAC,GAAG,MAAM,EAAE,OAAO,cAAc,KAAK,IAAI,EAAE,GAAG,CAAC,UAAU,YAAY,CAAC;AAElH,YAAU,MAAM;AACd,QAAI,CAAC,MAAM,wBAAwB,MAAM,cAAc;AACrD,iCAA2B,MAAM,gBAAgB,MAAM,YAAY,CAAC;AAAA,IACtE;AAAA,EACF,GAAG,CAAC,MAAM,sBAAsB,MAAM,YAAY,CAAC;AAEnD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,cAAc;AAAA,MACrB,eAAe,CAAC,UAAU;AACxB,mCAA2B,YAAY;AACrC,gBAAM,OAAO,OAAO,KAAK,CAAAA,UAAQA,MAAK,OAAO,KAAK;AAClD,cAAI,CAAC,MAAM;AACT,kBAAM,IAAI,MAAM,wCAAwC;AAAA,UAC1D;AAEA,cAAI,CAAC,MAAM,sBAAsB;AAC/B,kBAAM,MAAM,gBAAgB,IAAI;AAAA,UAClC;AACA,cAAI,MAAM,QAAQ;AAChB,mBAAO,KAAK,MAAM,OAAO,IAAI,CAAC;AAAA,UAChC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA;AAAA,4BAAC,iBAAc,WAAU,eACvB,8BAAC,eAAY,aAAY,eAAa,GACxC;AAAA,QACA,qBAAC,iBAAc,WAAU,eACtB;AAAA,mBAAS,MAAM,IAAI,UAClB,oBAAC,cAAW,OAAO,KAAK,IACtB,+BAAC,SAAI,WAAU,qBACb;AAAA,gCAAC,YAAS,MAAY;AAAA,YACtB,oBAAC,cAAY,eAAK,aAAY;AAAA,aAChC,KAJ+B,KAAK,EAKtC,CACD;AAAA,UAEA,OAAO,WAAW,KACjB,oBAAC,eACC,8BAAC,eAAY,sBAAQ,GACvB;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;","names":["team"]}
@@ -22,7 +22,7 @@ import * as cookie from "cookie";
22
22
  import { InternalSession } from "@stackframe/stack-shared/dist/sessions";
23
23
  import { mergeScopeStrings } from "@stackframe/stack-shared/dist/utils/strings";
24
24
  var NextNavigation = scrambleDuringCompileTime(NextNavigationUnscrambled);
25
- var clientVersion = "js @stackframe/stack@2.5.1";
25
+ var clientVersion = "js @stackframe/stack@2.5.3";
26
26
  function permissionDefinitionScopeToType(scope) {
27
27
  return { "any-team": "team", "specific-team": "team", "global": "global" }[scope.type];
28
28
  }
@@ -128,6 +128,97 @@ var numberOfAppsCreated = 0;
128
128
  var _StackClientAppImpl = class __StackClientAppImpl {
129
129
  constructor(_options) {
130
130
  this._options = _options;
131
+ this._uniqueIdentifier = void 0;
132
+ this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
133
+ this._currentUserCache = createCacheBySession(async (session) => {
134
+ if (this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY) {
135
+ await wait(2e3);
136
+ }
137
+ const user = await this._interface.getClientUserByToken(session);
138
+ return Result.or(user, null);
139
+ });
140
+ this._currentProjectCache = createCache(async () => {
141
+ return Result.orThrow(await this._interface.getClientProject());
142
+ });
143
+ this._ownedProjectsCache = createCacheBySession(async (session) => {
144
+ return await this._interface.listProjects(session);
145
+ });
146
+ this._currentUserPermissionsCache = createCacheBySession(async (session, [teamId, type, direct]) => {
147
+ return await this._interface.listClientUserTeamPermissions({ teamId, type, direct }, session);
148
+ });
149
+ this._currentUserTeamsCache = createCacheBySession(async (session) => {
150
+ return await this._interface.listClientUserTeams(session);
151
+ });
152
+ this._currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
153
+ async (session, [accountId, scope]) => {
154
+ try {
155
+ return await this._interface.getAccessToken(accountId, scope || "", session);
156
+ } catch (err) {
157
+ if (!(err instanceof KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof KnownErrors.OAuthConnectionNotConnectedToUser)) {
158
+ throw err;
159
+ }
160
+ }
161
+ return null;
162
+ }
163
+ );
164
+ this._currentUserOAuthConnectionCache = createCacheBySession(
165
+ async (session, [connectionId, scope, redirect]) => {
166
+ const user = await this._currentUserCache.getOrWait([session], "write-only");
167
+ let hasConnection = true;
168
+ if (!user || !user.oauthProviders.find((p) => p === connectionId)) {
169
+ hasConnection = false;
170
+ }
171
+ const token = await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
172
+ if (!token) {
173
+ hasConnection = false;
174
+ }
175
+ if (!hasConnection && redirect) {
176
+ await addNewOAuthProviderOrScope(
177
+ this._interface,
178
+ {
179
+ provider: connectionId,
180
+ redirectUrl: this.urls.oauthCallback,
181
+ errorRedirectUrl: this.urls.error,
182
+ providerScope: mergeScopeStrings(scope || "", (this._oauthScopesOnSignIn[connectionId] ?? []).join(" "))
183
+ },
184
+ session
185
+ );
186
+ return await neverResolve();
187
+ } else if (!hasConnection) {
188
+ return null;
189
+ }
190
+ const app = this;
191
+ return {
192
+ id: connectionId,
193
+ async getAccessToken() {
194
+ const result = await app._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
195
+ if (!result) {
196
+ throw new StackAssertionError("No access token available");
197
+ }
198
+ return result;
199
+ },
200
+ useAccessToken() {
201
+ const result = useAsyncCache(app._currentUserOAuthConnectionAccessTokensCache, [session, connectionId, scope || ""], "oauthAccount.useAccessToken()");
202
+ if (!result) {
203
+ throw new StackAssertionError("No access token available");
204
+ }
205
+ return result;
206
+ }
207
+ };
208
+ }
209
+ );
210
+ this._memoryTokenStore = createEmptyTokenStore();
211
+ this._requestTokenStores = /* @__PURE__ */ new WeakMap();
212
+ this._storedCookieTokenStore = null;
213
+ /**
214
+ * A map from token stores and session keys to sessions.
215
+ *
216
+ * This isn't just a map from session keys to sessions for two reasons:
217
+ *
218
+ * - So we can garbage-collect Session objects when the token store is garbage-collected
219
+ * - So different token stores are separated and don't leak information between each other, eg. if the same user sends two requests to the same server they should get a different session object
220
+ */
221
+ this._sessionsByTokenStoreAndSessionKey = /* @__PURE__ */ new WeakMap();
131
222
  if ("interface" in _options) {
132
223
  this._interface = _options.interface;
133
224
  } else {
@@ -150,89 +241,6 @@ var _StackClientAppImpl = class __StackClientAppImpl {
150
241
  (process.env.NODE_ENV === "development" ? console.log : console.warn)(`You have created more than 10 Stack apps (${numberOfAppsCreated}). This is usually a sign of a memory leak, but can sometimes be caused by hot reload of your tech stack. In production, make sure to minimize the number of Stack apps per page (usually, one per project).`);
151
242
  }
152
243
  }
153
- _uniqueIdentifier = void 0;
154
- _interface;
155
- _tokenStoreInit;
156
- _urlOptions;
157
- _oauthScopesOnSignIn;
158
- __DEMO_ENABLE_SLIGHT_FETCH_DELAY = false;
159
- _currentUserCache = createCacheBySession(async (session) => {
160
- if (this.__DEMO_ENABLE_SLIGHT_FETCH_DELAY) {
161
- await wait(2e3);
162
- }
163
- const user = await this._interface.getClientUserByToken(session);
164
- return Result.or(user, null);
165
- });
166
- _currentProjectCache = createCache(async () => {
167
- return Result.orThrow(await this._interface.getClientProject());
168
- });
169
- _ownedProjectsCache = createCacheBySession(async (session) => {
170
- return await this._interface.listProjects(session);
171
- });
172
- _currentUserPermissionsCache = createCacheBySession(async (session, [teamId, type, direct]) => {
173
- return await this._interface.listClientUserTeamPermissions({ teamId, type, direct }, session);
174
- });
175
- _currentUserTeamsCache = createCacheBySession(async (session) => {
176
- return await this._interface.listClientUserTeams(session);
177
- });
178
- _currentUserOAuthConnectionAccessTokensCache = createCacheBySession(
179
- async (session, [accountId, scope]) => {
180
- try {
181
- return await this._interface.getAccessToken(accountId, scope || "", session);
182
- } catch (err) {
183
- if (!(err instanceof KnownErrors.OAuthConnectionDoesNotHaveRequiredScope || err instanceof KnownErrors.OAuthConnectionNotConnectedToUser)) {
184
- throw err;
185
- }
186
- }
187
- return null;
188
- }
189
- );
190
- _currentUserOAuthConnectionCache = createCacheBySession(
191
- async (session, [connectionId, scope, redirect]) => {
192
- const user = await this._currentUserCache.getOrWait([session], "write-only");
193
- let hasConnection = true;
194
- if (!user || !user.oauthProviders.find((p) => p === connectionId)) {
195
- hasConnection = false;
196
- }
197
- const token = await this._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
198
- if (!token) {
199
- hasConnection = false;
200
- }
201
- if (!hasConnection && redirect) {
202
- await addNewOAuthProviderOrScope(
203
- this._interface,
204
- {
205
- provider: connectionId,
206
- redirectUrl: this.urls.oauthCallback,
207
- errorRedirectUrl: this.urls.error,
208
- providerScope: mergeScopeStrings(scope || "", (this._oauthScopesOnSignIn[connectionId] ?? []).join(" "))
209
- },
210
- session
211
- );
212
- return await neverResolve();
213
- } else if (!hasConnection) {
214
- return null;
215
- }
216
- const app = this;
217
- return {
218
- id: connectionId,
219
- async getAccessToken() {
220
- const result = await app._currentUserOAuthConnectionAccessTokensCache.getOrWait([session, connectionId, scope || ""], "write-only");
221
- if (!result) {
222
- throw new StackAssertionError("No access token available");
223
- }
224
- return result;
225
- },
226
- useAccessToken() {
227
- const result = useAsyncCache(app._currentUserOAuthConnectionAccessTokensCache, [session, connectionId, scope || ""], "oauthAccount.useAccessToken()");
228
- if (!result) {
229
- throw new StackAssertionError("No access token available");
230
- }
231
- return result;
232
- }
233
- };
234
- }
235
- );
236
244
  _initUniqueIdentifier() {
237
245
  if (!this._uniqueIdentifier) {
238
246
  throw new StackAssertionError("Unique identifier not initialized");
@@ -260,9 +268,6 @@ var _StackClientAppImpl = class __StackClientAppImpl {
260
268
  runAsynchronously(this._checkFeatureSupport(featureName, options));
261
269
  throw new StackAssertionError(`${featureName} is not currently supported. Please reach out to Stack support for more information.`);
262
270
  }
263
- _memoryTokenStore = createEmptyTokenStore();
264
- _requestTokenStores = /* @__PURE__ */ new WeakMap();
265
- _storedCookieTokenStore = null;
266
271
  get _refreshTokenCookieName() {
267
272
  return `stack-refresh-${this.projectId}`;
268
273
  }
@@ -390,15 +395,6 @@ var _StackClientAppImpl = class __StackClientAppImpl {
390
395
  }
391
396
  }
392
397
  }
393
- /**
394
- * A map from token stores and session keys to sessions.
395
- *
396
- * This isn't just a map from session keys to sessions for two reasons:
397
- *
398
- * - So we can garbage-collect Session objects when the token store is garbage-collected
399
- * - So different token stores are separated and don't leak information between each other, eg. if the same user sends two requests to the same server they should get a different session object
400
- */
401
- _sessionsByTokenStoreAndSessionKey = /* @__PURE__ */ new WeakMap();
402
398
  _getSessionFromTokenStore(tokenStore) {
403
399
  const tokenObj = tokenStore.get();
404
400
  const sessionKey = InternalSession.calculateSessionKey(tokenObj);
@@ -480,6 +476,7 @@ var _StackClientAppImpl = class __StackClientAppImpl {
480
476
  return {
481
477
  id: json.id,
482
478
  displayName: json.displayName,
479
+ profileImageUrl: json.profileImageUrl,
483
480
  createdAt: new Date(json.createdAtMillis),
484
481
  toJson() {
485
482
  return json;
@@ -1002,33 +999,6 @@ var _StackClientAppImpl = class __StackClientAppImpl {
1002
999
  }
1003
1000
  };
1004
1001
  var _StackServerAppImpl = class extends _StackClientAppImpl {
1005
- // TODO override the client user cache to use the server user cache, so we save some requests
1006
- _currentServerUserCache = createCacheBySession(async (session) => {
1007
- const user = await this._interface.getServerUserByToken(session);
1008
- return Result.or(user, null);
1009
- });
1010
- _serverUsersCache = createCache(async () => {
1011
- return await this._interface.listServerUsers();
1012
- });
1013
- _serverUserCache = createCache(async ([userId]) => {
1014
- const user = await this._interface.getServerUserById(userId);
1015
- return Result.or(user, null);
1016
- });
1017
- _serverTeamsCache = createCache(async () => {
1018
- return await this._interface.listServerTeams();
1019
- });
1020
- _serverTeamMembersCache = createCache(async ([teamId]) => {
1021
- return await this._interface.listServerTeamMembers(teamId);
1022
- });
1023
- _serverTeamPermissionDefinitionsCache = createCache(async () => {
1024
- return await this._interface.listPermissionDefinitions();
1025
- });
1026
- _serverTeamUserPermissionsCache = createCache(async ([teamId, userId, type, direct]) => {
1027
- return await this._interface.listServerTeamMemberPermissions({ teamId, userId, type, direct });
1028
- });
1029
- _serverEmailTemplatesCache = createCache(async () => {
1030
- return await this._interface.listEmailTemplates();
1031
- });
1032
1002
  constructor(options) {
1033
1003
  super("interface" in options ? {
1034
1004
  interface: options.interface,
@@ -1047,6 +1017,33 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1047
1017
  urls: options.urls ?? {},
1048
1018
  oauthScopesOnSignIn: options.oauthScopesOnSignIn ?? {}
1049
1019
  });
1020
+ // TODO override the client user cache to use the server user cache, so we save some requests
1021
+ this._currentServerUserCache = createCacheBySession(async (session) => {
1022
+ const user = await this._interface.getServerUserByToken(session);
1023
+ return Result.or(user, null);
1024
+ });
1025
+ this._serverUsersCache = createCache(async () => {
1026
+ return await this._interface.listServerUsers();
1027
+ });
1028
+ this._serverUserCache = createCache(async ([userId]) => {
1029
+ const user = await this._interface.getServerUserById(userId);
1030
+ return Result.or(user, null);
1031
+ });
1032
+ this._serverTeamsCache = createCache(async () => {
1033
+ return await this._interface.listServerTeams();
1034
+ });
1035
+ this._serverTeamMembersCache = createCache(async ([teamId]) => {
1036
+ return await this._interface.listServerTeamMembers(teamId);
1037
+ });
1038
+ this._serverTeamPermissionDefinitionsCache = createCache(async () => {
1039
+ return await this._interface.listPermissionDefinitions();
1040
+ });
1041
+ this._serverTeamUserPermissionsCache = createCache(async ([teamId, userId, type, direct]) => {
1042
+ return await this._interface.listServerTeamMemberPermissions({ teamId, userId, type, direct });
1043
+ });
1044
+ this._serverEmailTemplatesCache = createCache(async () => {
1045
+ return await this._interface.listEmailTemplates();
1046
+ });
1050
1047
  }
1051
1048
  _createBaseUser(json) {
1052
1049
  return {
@@ -1189,6 +1186,7 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1189
1186
  return {
1190
1187
  id: json.id,
1191
1188
  displayName: json.displayName,
1189
+ profileImageUrl: json.profileImageUrl,
1192
1190
  createdAt: new Date(json.createdAtMillis),
1193
1191
  async listMembers() {
1194
1192
  return (await app._interface.listServerTeamMembers(json.id)).map((u) => app._serverTeamMemberFromJson(u));
@@ -1372,12 +1370,6 @@ var _StackServerAppImpl = class extends _StackClientAppImpl {
1372
1370
  }
1373
1371
  };
1374
1372
  var _StackAdminAppImpl = class extends _StackServerAppImpl {
1375
- _adminProjectCache = createCache(async () => {
1376
- return await this._interface.getProject();
1377
- });
1378
- _apiKeySetsCache = createCache(async () => {
1379
- return await this._interface.listApiKeySets();
1380
- });
1381
1373
  constructor(options) {
1382
1374
  super({
1383
1375
  interface: new StackAdminInterface({
@@ -1396,6 +1388,12 @@ var _StackAdminAppImpl = class extends _StackServerAppImpl {
1396
1388
  urls: options.urls,
1397
1389
  oauthScopesOnSignIn: options.oauthScopesOnSignIn
1398
1390
  });
1391
+ this._adminProjectCache = createCache(async () => {
1392
+ return await this._interface.getProject();
1393
+ });
1394
+ this._apiKeySetsCache = createCache(async () => {
1395
+ return await this._interface.listApiKeySets();
1396
+ });
1399
1397
  }
1400
1398
  _createApiKeySetBaseFromJson(data) {
1401
1399
  const app = this;