@the-portland-company/shell 0.7.0 → 0.8.0

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/index.d.cts CHANGED
@@ -78,6 +78,18 @@ interface ShellUser {
78
78
  }
79
79
  /** Status of the auth session lifecycle. */
80
80
  type ShellAuthStatus = 'loading' | 'authenticated' | 'unauthenticated';
81
+ /**
82
+ * Host-app-driven auth for apps that do not authenticate through Supabase
83
+ * (e.g., OIDC apps like Contacts). When passed to ShellProvider it takes
84
+ * precedence over `supabaseClient` session tracking. The host app is
85
+ * responsible for building a Supabase-shaped `user.raw` (id/email/
86
+ * user_metadata.full_name) so chrome components render identically.
87
+ */
88
+ interface ShellInjectedAuth {
89
+ status: ShellAuthStatus;
90
+ user: ShellUser | null;
91
+ signOut: () => void | Promise<void>;
92
+ }
81
93
  /**
82
94
  * One entry in the shell's app-switcher sidebar. The shell uses this list to
83
95
  * render navigation links between sub-apps and to drive Speculation Rules
@@ -261,8 +273,11 @@ interface ShellProviderProps {
261
273
  children: ReactNode;
262
274
  /** Stable ID of the current app, e.g., 'crm'. */
263
275
  currentApp: string;
264
- /** Authenticated Supabase client owned by the host app. */
265
- supabaseClient: SupabaseClient;
276
+ /** Authenticated Supabase client owned by the host app. Optional since
277
+ * 0.8.0 — apps that authenticate elsewhere pass `auth` instead. */
278
+ supabaseClient?: SupabaseClient;
279
+ /** Host-driven auth (takes precedence over supabaseClient). Since 0.8.0. */
280
+ auth?: ShellInjectedAuth;
266
281
  /** App registry for the sidebar. If omitted, uses the default registry shipped with the shell. */
267
282
  appRegistry?: AppRegistryEntry[];
268
283
  /** Optional override for the base path if the app is mounted under a sub-path (e.g., '/contacts'). */
@@ -378,7 +393,7 @@ interface ShellChromeValue {
378
393
  userAvatarUrl?: string;
379
394
  }
380
395
  declare const ShellChromeContext: react.Context<ShellChromeValue | null>;
381
- declare function ShellProvider({ children, supabaseClient, currentApp, appRegistry, basename, organization, linkedAccounts, support, devNotesMenu, myProfileHref, userAvatarUrl, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
396
+ declare function ShellProvider({ children, supabaseClient, auth, currentApp, appRegistry, basename, organization, linkedAccounts, support, devNotesMenu, myProfileHref, userAvatarUrl, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
382
397
 
383
398
  declare function useShellAuth(): ShellAuthValue;
384
399
 
@@ -805,4 +820,4 @@ declare function registerShellPrecache(opts?: RegisterShellPrecacheOptions): Pro
805
820
  */
806
821
  declare function buildSpeculationRules(currentApp: string, registry: AppRegistryEntry[]): string | null;
807
822
 
808
- export { AppLayout, type AppRegistryEntry, BrandIcon, BrandLogo, BreadcrumbBar, Card, CommitCopyButton, type CommitCopyButtonProps, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, ModePill, NavItem, OrgPill, OrgPill as OrgSelector, PageContainer, PageHeader, type ShellActiveRoleConfig, type ShellAuthStatus, type ShellAuthValue, ShellChrome, ShellChromeContext, type ShellChromeProps, type ShellChromeValue, ShellFooterContext, type ShellFooterLink, type ShellFooterValue, type ShellLinkedAccount, ShellLinkedAccountsContext, type ShellLinkedAccountsValue, type ShellModeConfig, ShellModeContext, type ShellModeValue, type ShellNavItem, ShellNavItemsContext, type ShellNavItemsValue, ShellNavigationPreferenceContext, type ShellNavigationPreferenceValue, ShellOrgContext, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, ShellRoleContext, type ShellRoleValue, type ShellSlots, type ShellSupportContext, ShellSupportProviderContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, getOrganizationBadgeLetters, getOrganizationBrandColor, getUserDisplayName, hexToRgba, lightenHexColor, normalizeHexColor, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellFooter, useShellLinkedAccounts, useShellMode, useShellNavItems, useShellNavigationPreference, useShellOrganization, useShellRole, useShellSupport };
823
+ export { AppLayout, type AppRegistryEntry, BrandIcon, BrandLogo, BreadcrumbBar, Card, CommitCopyButton, type CommitCopyButtonProps, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, ModePill, NavItem, OrgPill, OrgPill as OrgSelector, PageContainer, PageHeader, type ShellActiveRoleConfig, type ShellAuthStatus, type ShellAuthValue, ShellChrome, ShellChromeContext, type ShellChromeProps, type ShellChromeValue, ShellFooterContext, type ShellFooterLink, type ShellFooterValue, type ShellInjectedAuth, type ShellLinkedAccount, ShellLinkedAccountsContext, type ShellLinkedAccountsValue, type ShellModeConfig, ShellModeContext, type ShellModeValue, type ShellNavItem, ShellNavItemsContext, type ShellNavItemsValue, ShellNavigationPreferenceContext, type ShellNavigationPreferenceValue, ShellOrgContext, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, ShellRoleContext, type ShellRoleValue, type ShellSlots, type ShellSupportContext, ShellSupportProviderContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, getOrganizationBadgeLetters, getOrganizationBrandColor, getUserDisplayName, hexToRgba, lightenHexColor, normalizeHexColor, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellFooter, useShellLinkedAccounts, useShellMode, useShellNavItems, useShellNavigationPreference, useShellOrganization, useShellRole, useShellSupport };
package/dist/index.d.ts CHANGED
@@ -78,6 +78,18 @@ interface ShellUser {
78
78
  }
79
79
  /** Status of the auth session lifecycle. */
80
80
  type ShellAuthStatus = 'loading' | 'authenticated' | 'unauthenticated';
81
+ /**
82
+ * Host-app-driven auth for apps that do not authenticate through Supabase
83
+ * (e.g., OIDC apps like Contacts). When passed to ShellProvider it takes
84
+ * precedence over `supabaseClient` session tracking. The host app is
85
+ * responsible for building a Supabase-shaped `user.raw` (id/email/
86
+ * user_metadata.full_name) so chrome components render identically.
87
+ */
88
+ interface ShellInjectedAuth {
89
+ status: ShellAuthStatus;
90
+ user: ShellUser | null;
91
+ signOut: () => void | Promise<void>;
92
+ }
81
93
  /**
82
94
  * One entry in the shell's app-switcher sidebar. The shell uses this list to
83
95
  * render navigation links between sub-apps and to drive Speculation Rules
@@ -261,8 +273,11 @@ interface ShellProviderProps {
261
273
  children: ReactNode;
262
274
  /** Stable ID of the current app, e.g., 'crm'. */
263
275
  currentApp: string;
264
- /** Authenticated Supabase client owned by the host app. */
265
- supabaseClient: SupabaseClient;
276
+ /** Authenticated Supabase client owned by the host app. Optional since
277
+ * 0.8.0 — apps that authenticate elsewhere pass `auth` instead. */
278
+ supabaseClient?: SupabaseClient;
279
+ /** Host-driven auth (takes precedence over supabaseClient). Since 0.8.0. */
280
+ auth?: ShellInjectedAuth;
266
281
  /** App registry for the sidebar. If omitted, uses the default registry shipped with the shell. */
267
282
  appRegistry?: AppRegistryEntry[];
268
283
  /** Optional override for the base path if the app is mounted under a sub-path (e.g., '/contacts'). */
@@ -378,7 +393,7 @@ interface ShellChromeValue {
378
393
  userAvatarUrl?: string;
379
394
  }
380
395
  declare const ShellChromeContext: react.Context<ShellChromeValue | null>;
381
- declare function ShellProvider({ children, supabaseClient, currentApp, appRegistry, basename, organization, linkedAccounts, support, devNotesMenu, myProfileHref, userAvatarUrl, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
396
+ declare function ShellProvider({ children, supabaseClient, auth, currentApp, appRegistry, basename, organization, linkedAccounts, support, devNotesMenu, myProfileHref, userAvatarUrl, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
382
397
 
383
398
  declare function useShellAuth(): ShellAuthValue;
384
399
 
@@ -805,4 +820,4 @@ declare function registerShellPrecache(opts?: RegisterShellPrecacheOptions): Pro
805
820
  */
806
821
  declare function buildSpeculationRules(currentApp: string, registry: AppRegistryEntry[]): string | null;
807
822
 
808
- export { AppLayout, type AppRegistryEntry, BrandIcon, BrandLogo, BreadcrumbBar, Card, CommitCopyButton, type CommitCopyButtonProps, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, ModePill, NavItem, OrgPill, OrgPill as OrgSelector, PageContainer, PageHeader, type ShellActiveRoleConfig, type ShellAuthStatus, type ShellAuthValue, ShellChrome, ShellChromeContext, type ShellChromeProps, type ShellChromeValue, ShellFooterContext, type ShellFooterLink, type ShellFooterValue, type ShellLinkedAccount, ShellLinkedAccountsContext, type ShellLinkedAccountsValue, type ShellModeConfig, ShellModeContext, type ShellModeValue, type ShellNavItem, ShellNavItemsContext, type ShellNavItemsValue, ShellNavigationPreferenceContext, type ShellNavigationPreferenceValue, ShellOrgContext, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, ShellRoleContext, type ShellRoleValue, type ShellSlots, type ShellSupportContext, ShellSupportProviderContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, getOrganizationBadgeLetters, getOrganizationBrandColor, getUserDisplayName, hexToRgba, lightenHexColor, normalizeHexColor, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellFooter, useShellLinkedAccounts, useShellMode, useShellNavItems, useShellNavigationPreference, useShellOrganization, useShellRole, useShellSupport };
823
+ export { AppLayout, type AppRegistryEntry, BrandIcon, BrandLogo, BreadcrumbBar, Card, CommitCopyButton, type CommitCopyButtonProps, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, ModePill, NavItem, OrgPill, OrgPill as OrgSelector, PageContainer, PageHeader, type ShellActiveRoleConfig, type ShellAuthStatus, type ShellAuthValue, ShellChrome, ShellChromeContext, type ShellChromeProps, type ShellChromeValue, ShellFooterContext, type ShellFooterLink, type ShellFooterValue, type ShellInjectedAuth, type ShellLinkedAccount, ShellLinkedAccountsContext, type ShellLinkedAccountsValue, type ShellModeConfig, ShellModeContext, type ShellModeValue, type ShellNavItem, ShellNavItemsContext, type ShellNavItemsValue, ShellNavigationPreferenceContext, type ShellNavigationPreferenceValue, ShellOrgContext, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, ShellRoleContext, type ShellRoleValue, type ShellSlots, type ShellSupportContext, ShellSupportProviderContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, getOrganizationBadgeLetters, getOrganizationBrandColor, getUserDisplayName, hexToRgba, lightenHexColor, normalizeHexColor, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellFooter, useShellLinkedAccounts, useShellMode, useShellNavItems, useShellNavigationPreference, useShellOrganization, useShellRole, useShellSupport };
package/dist/index.js CHANGED
@@ -1120,6 +1120,7 @@ function toShellUser(session) {
1120
1120
  function ShellProvider({
1121
1121
  children,
1122
1122
  supabaseClient,
1123
+ auth,
1123
1124
  currentApp,
1124
1125
  appRegistry,
1125
1126
  basename,
@@ -1133,6 +1134,11 @@ function ShellProvider({
1133
1134
  const [status, setStatus] = useState("loading");
1134
1135
  const [session, setSession] = useState(null);
1135
1136
  useEffect(() => {
1137
+ if (auth || !supabaseClient) {
1138
+ setSession(null);
1139
+ if (!auth) setStatus("unauthenticated");
1140
+ return;
1141
+ }
1136
1142
  let cancelled = false;
1137
1143
  supabaseClient.auth.getSession().then(({ data }) => {
1138
1144
  if (cancelled) return;
@@ -1147,18 +1153,27 @@ function ShellProvider({
1147
1153
  cancelled = true;
1148
1154
  sub.data.subscription.unsubscribe();
1149
1155
  };
1150
- }, [supabaseClient]);
1151
- const value = useMemo(
1152
- () => ({
1156
+ }, [supabaseClient, auth]);
1157
+ const value = useMemo(() => {
1158
+ if (auth) {
1159
+ return {
1160
+ status: auth.status,
1161
+ session: null,
1162
+ user: auth.user,
1163
+ signOut: async () => {
1164
+ await auth.signOut();
1165
+ }
1166
+ };
1167
+ }
1168
+ return {
1153
1169
  status,
1154
1170
  session,
1155
1171
  user: toShellUser(session),
1156
1172
  signOut: async () => {
1157
- await supabaseClient.auth.signOut();
1173
+ await supabaseClient?.auth.signOut();
1158
1174
  }
1159
- }),
1160
- [status, session, supabaseClient]
1161
- );
1175
+ };
1176
+ }, [auth, status, session, supabaseClient]);
1162
1177
  const meta = useMemo(
1163
1178
  () => ({
1164
1179
  currentApp,