@the-portland-company/shell 0.76.7 → 0.76.8

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.
@@ -89,6 +89,132 @@ function normalize(s) {
89
89
  return s.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().trim();
90
90
  }
91
91
 
92
+ // src/active-org.ts
93
+ var ACTIVE_ORG_COOKIE = "politogy_active_org";
94
+ var ACTIVE_ORG_QUERY_PARAM = "org";
95
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
96
+ function isOrgId(v) {
97
+ return typeof v === "string" && UUID_RE.test(v.trim());
98
+ }
99
+ function readActiveOrgCookie() {
100
+ if (typeof document === "undefined") return null;
101
+ try {
102
+ const m = document.cookie.match(
103
+ new RegExp(`(?:^|;\\s*)${ACTIVE_ORG_COOKIE}=([^;]+)`)
104
+ );
105
+ const v = m ? decodeURIComponent(m[1]) : null;
106
+ return isOrgId(v) ? v : null;
107
+ } catch {
108
+ return null;
109
+ }
110
+ }
111
+ function writeActiveOrgCookie(orgId) {
112
+ if (typeof document === "undefined" || typeof window === "undefined") return;
113
+ if (!isOrgId(orgId)) return;
114
+ const host = window.location.hostname;
115
+ const domainAttr = /(^|\.)politogyvrm\.com$/i.test(host) ? "; Domain=.politogyvrm.com" : "";
116
+ const secure = window.location.protocol === "https:" ? "; Secure" : "";
117
+ document.cookie = `${ACTIVE_ORG_COOKIE}=${encodeURIComponent(
118
+ orgId
119
+ )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`;
120
+ }
121
+ function readActiveOrgFromUrl(search) {
122
+ if (!search) return null;
123
+ try {
124
+ const qs = search.includes("?") ? search.slice(search.indexOf("?") + 1) : search;
125
+ const v = new URLSearchParams(qs).get(ACTIVE_ORG_QUERY_PARAM);
126
+ return isOrgId(v) ? v : null;
127
+ } catch {
128
+ return null;
129
+ }
130
+ }
131
+ function resolveActiveOrg(search) {
132
+ const fromUrl = readActiveOrgFromUrl(
133
+ (typeof window !== "undefined" ? window.location.search : null)
134
+ );
135
+ if (fromUrl) return fromUrl;
136
+ return readActiveOrgCookie();
137
+ }
138
+ var ORG_ID_QUERY_PARAM = "org_id";
139
+ var ORG_ID_TAIL_LENGTH = 7;
140
+ var LEGACY_ORG_TAIL_LENGTH = 6;
141
+ var TAIL_RE = /^[0-9a-f]{6,7}$/i;
142
+ var AUTH_BASE_URL = "https://auth.politogyvrm.com";
143
+ var AUTH_BASE_URL_STAGING = "https://auth-staging.politogyvrm.com";
144
+ function orgIdTail(orgId) {
145
+ return isOrgId(orgId) ? orgId.trim().toLowerCase().slice(-ORG_ID_TAIL_LENGTH) : null;
146
+ }
147
+ function isOrgSelector(v) {
148
+ return typeof v === "string" && (UUID_RE.test(v.trim()) || TAIL_RE.test(v.trim()));
149
+ }
150
+ function matchOrgSelector(selector, orgs) {
151
+ if (!isOrgSelector(selector)) return null;
152
+ const sel = selector.trim().toLowerCase();
153
+ if (UUID_RE.test(sel)) return orgs.find((o) => o.id.toLowerCase() === sel) ?? null;
154
+ if (sel.length !== ORG_ID_TAIL_LENGTH && sel.length !== LEGACY_ORG_TAIL_LENGTH) return null;
155
+ const hits = orgs.filter((o) => o.id.toLowerCase().endsWith(sel));
156
+ return hits.length === 1 ? hits[0] : null;
157
+ }
158
+ function readOrgSelectorFromUrl(search) {
159
+ if (!search) return null;
160
+ try {
161
+ const qs = search.includes("?") ? search.slice(search.indexOf("?") + 1) : search;
162
+ const params = new URLSearchParams(qs);
163
+ for (const key of [ORG_ID_QUERY_PARAM, ACTIVE_ORG_QUERY_PARAM]) {
164
+ const v = params.get(key);
165
+ if (isOrgSelector(v)) return v.trim().toLowerCase();
166
+ }
167
+ return null;
168
+ } catch {
169
+ return null;
170
+ }
171
+ }
172
+ function orgClaimsFrom(claims) {
173
+ if (!claims || typeof claims !== "object") return null;
174
+ const c = claims;
175
+ if (!isOrgId(c.org_id)) return null;
176
+ return {
177
+ orgId: c.org_id.trim().toLowerCase(),
178
+ orgRole: typeof c.org_role === "string" ? c.org_role : null
179
+ };
180
+ }
181
+ function authBaseUrl() {
182
+ if (typeof window !== "undefined" && window.location.hostname.toLowerCase().includes("staging")) {
183
+ return AUTH_BASE_URL_STAGING;
184
+ }
185
+ return AUTH_BASE_URL;
186
+ }
187
+ var ActiveOrgSwitchError = class extends Error {
188
+ constructor(status, message) {
189
+ super(message);
190
+ this.status = status;
191
+ this.name = "ActiveOrgSwitchError";
192
+ }
193
+ };
194
+ async function switchActiveOrg(orgId, opts = {}) {
195
+ if (!isOrgId(orgId)) throw new ActiveOrgSwitchError(400, "org_id must be a full uuid");
196
+ const doFetch = opts.fetch ?? fetch;
197
+ const res = await doFetch(`${opts.authBaseUrl ?? authBaseUrl()}/api/active-org`, {
198
+ method: "POST",
199
+ credentials: "include",
200
+ headers: { "Content-Type": "application/json" },
201
+ body: JSON.stringify({ org_id: orgId })
202
+ });
203
+ if (!res.ok) {
204
+ let msg = `active-org switch failed (${res.status})`;
205
+ try {
206
+ const body = await res.json();
207
+ if (body?.error) msg = body.error;
208
+ } catch {
209
+ }
210
+ throw new ActiveOrgSwitchError(res.status, msg);
211
+ }
212
+ const claims = orgClaimsFrom(await res.json().catch(() => null));
213
+ if (!claims) throw new ActiveOrgSwitchError(502, "active-org switch returned no org_id");
214
+ writeActiveOrgCookie(claims.orgId);
215
+ return claims;
216
+ }
217
+
92
218
  // src/nav-preference.ts
93
219
  var NAV_DISPLAY_STORAGE_KEY = "politogy_nav_display";
94
220
  var NAV_DISPLAY_COOKIE = "politogy_nav_display";
@@ -2456,6 +2582,11 @@ function useRailCollapse() {
2456
2582
  const collapsible = react.useContext(RailCollapsibleContext);
2457
2583
  return (cls) => collapsible ? cls : "";
2458
2584
  }
2585
+ function orgPillLabel(org) {
2586
+ if (org.name) return org.name;
2587
+ if (org.id) return orgIdTail(org.id) ?? "Organization";
2588
+ return "No organizations";
2589
+ }
2459
2590
  function OrgIconMark({ org, logoSrc }) {
2460
2591
  const rc = useRailCollapse();
2461
2592
  const src = resolveOrgLogoUrl(org.iconUrl) ?? logoSrc;
@@ -2697,7 +2828,7 @@ function NavSidebar({
2697
2828
  {
2698
2829
  title: org.name ?? void 0,
2699
2830
  className: "truncate text-[12px] font-semibold leading-[1.2]",
2700
- children: org.name ?? "No organizations"
2831
+ children: orgPillLabel(org)
2701
2832
  }
2702
2833
  ),
2703
2834
  org.id && !org.loading ? /* @__PURE__ */ jsxRuntime.jsx(OrgIdCopyButton, { id: org.id }) : null
@@ -2799,7 +2930,7 @@ function NavSidebar({
2799
2930
  {
2800
2931
  title: org.name ?? void 0,
2801
2932
  className: "truncate text-[12px] font-semibold leading-[1.2]",
2802
- children: org.name ?? "No organizations"
2933
+ children: orgPillLabel(org)
2803
2934
  }
2804
2935
  ),
2805
2936
  org.id && !org.loading ? /* @__PURE__ */ jsxRuntime.jsx(OrgIdCopyButton, { id: org.id }) : null
@@ -3850,132 +3981,6 @@ function NavAppShell({
3850
3981
  );
3851
3982
  }
3852
3983
 
3853
- // src/active-org.ts
3854
- var ACTIVE_ORG_COOKIE = "politogy_active_org";
3855
- var ACTIVE_ORG_QUERY_PARAM = "org";
3856
- var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
3857
- function isOrgId(v) {
3858
- return typeof v === "string" && UUID_RE.test(v.trim());
3859
- }
3860
- function readActiveOrgCookie() {
3861
- if (typeof document === "undefined") return null;
3862
- try {
3863
- const m = document.cookie.match(
3864
- new RegExp(`(?:^|;\\s*)${ACTIVE_ORG_COOKIE}=([^;]+)`)
3865
- );
3866
- const v = m ? decodeURIComponent(m[1]) : null;
3867
- return isOrgId(v) ? v : null;
3868
- } catch {
3869
- return null;
3870
- }
3871
- }
3872
- function writeActiveOrgCookie(orgId) {
3873
- if (typeof document === "undefined" || typeof window === "undefined") return;
3874
- if (!isOrgId(orgId)) return;
3875
- const host = window.location.hostname;
3876
- const domainAttr = /(^|\.)politogyvrm\.com$/i.test(host) ? "; Domain=.politogyvrm.com" : "";
3877
- const secure = window.location.protocol === "https:" ? "; Secure" : "";
3878
- document.cookie = `${ACTIVE_ORG_COOKIE}=${encodeURIComponent(
3879
- orgId
3880
- )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`;
3881
- }
3882
- function readActiveOrgFromUrl(search) {
3883
- if (!search) return null;
3884
- try {
3885
- const qs = search.includes("?") ? search.slice(search.indexOf("?") + 1) : search;
3886
- const v = new URLSearchParams(qs).get(ACTIVE_ORG_QUERY_PARAM);
3887
- return isOrgId(v) ? v : null;
3888
- } catch {
3889
- return null;
3890
- }
3891
- }
3892
- function resolveActiveOrg(search) {
3893
- const fromUrl = readActiveOrgFromUrl(
3894
- (typeof window !== "undefined" ? window.location.search : null)
3895
- );
3896
- if (fromUrl) return fromUrl;
3897
- return readActiveOrgCookie();
3898
- }
3899
- var ORG_ID_QUERY_PARAM = "org_id";
3900
- var ORG_ID_TAIL_LENGTH = 7;
3901
- var LEGACY_ORG_TAIL_LENGTH = 6;
3902
- var TAIL_RE = /^[0-9a-f]{6,7}$/i;
3903
- var AUTH_BASE_URL = "https://auth.politogyvrm.com";
3904
- var AUTH_BASE_URL_STAGING = "https://auth-staging.politogyvrm.com";
3905
- function orgIdTail(orgId) {
3906
- return isOrgId(orgId) ? orgId.trim().toLowerCase().slice(-ORG_ID_TAIL_LENGTH) : null;
3907
- }
3908
- function isOrgSelector(v) {
3909
- return typeof v === "string" && (UUID_RE.test(v.trim()) || TAIL_RE.test(v.trim()));
3910
- }
3911
- function matchOrgSelector(selector, orgs) {
3912
- if (!isOrgSelector(selector)) return null;
3913
- const sel = selector.trim().toLowerCase();
3914
- if (UUID_RE.test(sel)) return orgs.find((o) => o.id.toLowerCase() === sel) ?? null;
3915
- if (sel.length !== ORG_ID_TAIL_LENGTH && sel.length !== LEGACY_ORG_TAIL_LENGTH) return null;
3916
- const hits = orgs.filter((o) => o.id.toLowerCase().endsWith(sel));
3917
- return hits.length === 1 ? hits[0] : null;
3918
- }
3919
- function readOrgSelectorFromUrl(search) {
3920
- if (!search) return null;
3921
- try {
3922
- const qs = search.includes("?") ? search.slice(search.indexOf("?") + 1) : search;
3923
- const params = new URLSearchParams(qs);
3924
- for (const key of [ORG_ID_QUERY_PARAM, ACTIVE_ORG_QUERY_PARAM]) {
3925
- const v = params.get(key);
3926
- if (isOrgSelector(v)) return v.trim().toLowerCase();
3927
- }
3928
- return null;
3929
- } catch {
3930
- return null;
3931
- }
3932
- }
3933
- function orgClaimsFrom(claims) {
3934
- if (!claims || typeof claims !== "object") return null;
3935
- const c = claims;
3936
- if (!isOrgId(c.org_id)) return null;
3937
- return {
3938
- orgId: c.org_id.trim().toLowerCase(),
3939
- orgRole: typeof c.org_role === "string" ? c.org_role : null
3940
- };
3941
- }
3942
- function authBaseUrl() {
3943
- if (typeof window !== "undefined" && window.location.hostname.toLowerCase().includes("staging")) {
3944
- return AUTH_BASE_URL_STAGING;
3945
- }
3946
- return AUTH_BASE_URL;
3947
- }
3948
- var ActiveOrgSwitchError = class extends Error {
3949
- constructor(status, message) {
3950
- super(message);
3951
- this.status = status;
3952
- this.name = "ActiveOrgSwitchError";
3953
- }
3954
- };
3955
- async function switchActiveOrg(orgId, opts = {}) {
3956
- if (!isOrgId(orgId)) throw new ActiveOrgSwitchError(400, "org_id must be a full uuid");
3957
- const doFetch = opts.fetch ?? fetch;
3958
- const res = await doFetch(`${opts.authBaseUrl ?? authBaseUrl()}/api/active-org`, {
3959
- method: "POST",
3960
- credentials: "include",
3961
- headers: { "Content-Type": "application/json" },
3962
- body: JSON.stringify({ org_id: orgId })
3963
- });
3964
- if (!res.ok) {
3965
- let msg = `active-org switch failed (${res.status})`;
3966
- try {
3967
- const body = await res.json();
3968
- if (body?.error) msg = body.error;
3969
- } catch {
3970
- }
3971
- throw new ActiveOrgSwitchError(res.status, msg);
3972
- }
3973
- const claims = orgClaimsFrom(await res.json().catch(() => null));
3974
- if (!claims) throw new ActiveOrgSwitchError(502, "active-org switch returned no org_id");
3975
- writeActiveOrgCookie(claims.orgId);
3976
- return claims;
3977
- }
3978
-
3979
3984
  // src/lib/breadcrumbs.ts
3980
3985
  function deriveBreadcrumbs(items, pathname, opts) {
3981
3986
  const search = opts?.search ?? (typeof window !== "undefined" ? window.location.search : "");