@fluid-app/portal-sdk 0.1.426 → 0.1.427

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.
@@ -3,6 +3,7 @@ import { type AppShellProps } from "../shell/AppShell";
3
3
  import type { PortalErrorReporter } from "../errors/portal-error-reporter";
4
4
  import type { FluidSDKConfig } from "../types/config";
5
5
  import type { WidgetManifest } from "@fluid-app/portal-core/registries";
6
+ import type { MemberTypeCustomPages } from "@fluid-app/portal-core/member-type-content";
6
7
  import type { WidgetPackageDescriptor } from "../types/widget-package-descriptor";
7
8
  /**
8
9
  * Configuration for `createPortal()`.
@@ -16,6 +17,12 @@ export interface PortalConfig {
16
17
  slug?: string;
17
18
  params?: string;
18
19
  }>>;
20
+ /**
21
+ * Per-member-type page overrides: memberTypeSlug -> (pageSlug -> component).
22
+ * Serves different screens to different member types (e.g. an `affiliate`
23
+ * dashboard) at the same slug. Wins over `customPages` for that member type.
24
+ */
25
+ memberTypeCustomPages?: MemberTypeCustomPages;
19
26
  /** Custom widget manifests (type + component + propertySchema) */
20
27
  customWidgets?: WidgetManifest[];
21
28
  /** Trusted remote widget packages to load at runtime. */
@@ -46,7 +53,7 @@ export interface PortalConfig {
46
53
  /** Root element ID. @default "root" */
47
54
  rootId?: string;
48
55
  /** AppShell props passthrough (basePath, sidebarHeader, etc.) */
49
- shell?: Omit<AppShellProps, "customPages" | "errorReporter">;
56
+ shell?: Omit<AppShellProps, "customPages" | "memberTypeCustomPages" | "errorReporter">;
50
57
  /** Wrap AppShell with additional providers (inserted inside RequireAuth, below FluidProvider) */
51
58
  providers?: ComponentType<{
52
59
  children: ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"create-portal.d.ts","sourceRoot":"","sources":["../../src/entry/create-portal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,aAAa,EAKnB,MAAM,OAAO,CAAC;AAGf,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AA8ZlF;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAClB,MAAM,EACN,aAAa,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAClD,CAAC;IACF,kEAAkE;IAClE,aAAa,CAAC,EAAE,cAAc,EAAE,CAAC;IACjC,yDAAyD;IACzD,cAAc,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACpD;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC;;;;;;;OAOG;IACH,wBAAwB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC1C;;;OAGG;IACH,2BAA2B,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,yDAAyD;IACzD,KAAK,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAChC,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,KAAK,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,aAAa,GAAG,eAAe,CAAC,CAAC;IAC7D,iGAAiG;IACjG,SAAS,CAAC,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IACnD,qGAAqG;IACrG,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,yCAAyC;IACzC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,MAAM,GAAE,YAAiB,GAAG,IAAI,CAqD5D"}
1
+ {"version":3,"file":"create-portal.d.ts","sourceRoot":"","sources":["../../src/entry/create-portal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,aAAa,EAKnB,MAAM,OAAO,CAAC;AAGf,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACxF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AA8ZlF;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAClB,MAAM,EACN,aAAa,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAClD,CAAC;IACF;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAC9C,kEAAkE;IAClE,aAAa,CAAC,EAAE,cAAc,EAAE,CAAC;IACjC,yDAAyD;IACzD,cAAc,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACpD;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC;;;;;;;OAOG;IACH,wBAAwB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC1C;;;OAGG;IACH,2BAA2B,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,yDAAyD;IACzD,KAAK,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAChC,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,KAAK,CAAC,EAAE,IAAI,CACV,aAAa,EACb,aAAa,GAAG,uBAAuB,GAAG,eAAe,CAC1D,CAAC;IACF,iGAAiG;IACjG,SAAS,CAAC,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IACnD,qGAAqG;IACrG,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,yCAAyC;IACzC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,MAAM,GAAE,YAAiB,GAAG,IAAI,CAsD5D"}
package/dist/index.cjs CHANGED
@@ -1826,6 +1826,27 @@ function BuilderScreenViewImpl({ screen, className }) {
1826
1826
  }
1827
1827
  const BuilderScreenView = (0, react.memo)(BuilderScreenViewImpl);
1828
1828
  //#endregion
1829
+ //#region ../core/src/member-type-content.ts
1830
+ /**
1831
+ * Resolve the page component to render for a given member-type slug and
1832
+ * page slug, preferring an exact page match then a base-slug (prefix)
1833
+ * match. Returns undefined when the member type has no override for the
1834
+ * route, so the caller falls back to global content.
1835
+ *
1836
+ * Known limitation: `baseSlug` is the caller's navigation-derived base (see
1837
+ * PageRouter), so a per-type override registered at a detail *prefix* that is
1838
+ * not itself a navigation slug (e.g. `share/product` when the nav only has
1839
+ * `share/products`) is only matched on an exact `currentSlug`. Data-driven,
1840
+ * prefix-aware matching against the registry's own keys is deferred to the
1841
+ * authoring phase; register the exact slug you route to for now.
1842
+ */
1843
+ function resolveMemberTypePage(registry, memberTypeSlug, currentSlug, baseSlug) {
1844
+ if (!registry || !memberTypeSlug) return void 0;
1845
+ const pages = registry[memberTypeSlug];
1846
+ if (!pages) return void 0;
1847
+ return pages[currentSlug] ?? (baseSlug !== currentSlug ? pages[baseSlug] : void 0);
1848
+ }
1849
+ //#endregion
1829
1850
  //#region src/shell/system-screen-map.ts
1830
1851
  const ProfileScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ProfileScreen-Bh_mUdhz.cjs")).then((m) => ({ default: m.ProfileScreen })));
1831
1852
  const OrdersScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./OrdersScreen-DX5fRqYY.cjs")).then((m) => ({ default: m.OrdersScreen })));
@@ -1884,7 +1905,7 @@ function isRouteCoveredByNav(currentSlug, baseSlug, navSlugs) {
1884
1905
  if (navSlugs === void 0) return true;
1885
1906
  return navSlugs.some((navSlug) => navSlug === baseSlug || currentSlug === navSlug || currentSlug.startsWith(navSlug + "/"));
1886
1907
  }
1887
- function PageRouter({ currentSlug, currentNavItem, customPages, screens, baseSlug, restParams, navSlugs }) {
1908
+ function PageRouter({ currentSlug, currentNavItem, customPages, memberTypeCustomPages, screens, baseSlug, restParams, navSlugs }) {
1888
1909
  const { data: account } = require_use_account.useAccount();
1889
1910
  const canRep = !require_member_permissions.deniesRepSurfaces(account);
1890
1911
  const screenById = (0, react.useMemo)(() => {
@@ -1918,6 +1939,12 @@ function PageRouter({ currentSlug, currentNavItem, customPages, screens, baseSlu
1918
1939
  const routeCoveredByNav = currentNavItem !== void 0 || isRouteCoveredByNav(currentSlug, baseSlug, navSlugs);
1919
1940
  const isRepOnlyRoute = require_use_navigation_parent.isRepOnlySlug(currentSlug);
1920
1941
  if (!canRep && isRepOnlyRoute && routeCoveredByNav) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccessDeniedScreen, {});
1942
+ const memberTypeContentSlug = account?.member_type_detail?.slug ?? null;
1943
+ const MemberTypePage = canRep || !isRepOnlyRoute ? resolveMemberTypePage(memberTypeCustomPages, memberTypeContentSlug, currentSlug, baseSlug) : void 0;
1944
+ if (MemberTypePage) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemberTypePage, {
1945
+ slug: currentSlug,
1946
+ params: restParams
1947
+ });
1921
1948
  const ExactCustomPage = customPages?.[currentSlug];
1922
1949
  if (ExactCustomPage) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExactCustomPage, {
1923
1950
  slug: currentSlug,
@@ -2111,7 +2138,7 @@ function findNavItem(items, slug) {
2111
2138
  for (const child of item.children ?? []) if (require_use_navigation_parent.normalizeSlug(child.slug) === normalized) return child;
2112
2139
  }
2113
2140
  }
2114
- function AppShell({ appData: appDataProp, navigation: navigationProp, customPages, basePath = "/", currentSlug: controlledSlug, onNavigate: onNavigateProp, sidebarHeader, sidebarFooter, onLogout, logoutRedirectUrl, errorReporter, children }) {
2141
+ function AppShell({ appData: appDataProp, navigation: navigationProp, customPages, memberTypeCustomPages, basePath = "/", currentSlug: controlledSlug, onNavigate: onNavigateProp, sidebarHeader, sidebarFooter, onLogout, logoutRedirectUrl, errorReporter, children }) {
2115
2142
  const normalizedBasePath = (0, react.useMemo)(() => {
2116
2143
  const stripped = basePath.replace(/^\/|\/$/g, "");
2117
2144
  return stripped ? `/${stripped}` : "/";
@@ -2344,6 +2371,7 @@ function AppShell({ appData: appDataProp, navigation: navigationProp, customPage
2344
2371
  currentSlug: activeSlug,
2345
2372
  currentNavItem,
2346
2373
  customPages,
2374
+ memberTypeCustomPages,
2347
2375
  screens,
2348
2376
  baseSlug,
2349
2377
  restParams,
@@ -2680,6 +2708,7 @@ function createPortal(config = {}) {
2680
2708
  const widgetPackageLoadPromise = createWidgetPackageLoadPromise(config, fluidConfig);
2681
2709
  let app = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AppShell, {
2682
2710
  customPages: config.customPages,
2711
+ memberTypeCustomPages: config.memberTypeCustomPages,
2683
2712
  errorReporter: config.errorReporter,
2684
2713
  ...config.shell
2685
2714
  });