@enterprisestandard/react 0.0.20-beta.20260522.2 → 0.0.20-beta.20260601.4

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.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "@enterprisestandard/core";
2
+ import { generateULID } from "@enterprisestandard/core";
2
3
  import { PropsWithChildren } from "react";
3
4
  declare function SignInLoading({ complete, children }: {
4
5
  complete?: boolean;
@@ -59,4 +60,4 @@ declare function useTenantDirectory<TTenant extends TenantResponse = TenantRespo
59
60
  error: Error | null;
60
61
  refresh: () => Promise<void>;
61
62
  };
62
- export { useTenantDirectory, useTenant, logout, getUser, createTenantUrls, UseTenantDirectoryOptions, TenantProvider, SignedOut, SignedIn, SignInLoading, SSOProvider };
63
+ export { useTenantDirectory, useTenant, logout, getUser, generateULID, createTenantUrls, UseTenantDirectoryOptions, TenantProvider, SignedOut, SignedIn, SignInLoading, SSOProvider };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export*from"@enterprisestandard/core";import{silentLogger as A}from"@enterprisestandard/core";import{createContext as D,useCallback as l,useContext as H,useEffect as $,useState as w}from"react";import{jsx as S}from"react/jsx-runtime";var O=D(void 0),J=/^[a-zA-Z0-9._-]{1,1024}$/;function Q(n){if(!n.trim())throw Error("SSOProvider storageKey must be a non-empty string.");if(!J.test(n))throw Error("SSOProvider storageKey must be 1-1024 characters and contain only letters, numbers, dots, underscores, and hyphens.")}var W=(n)=>{if(n===void 0||n==="")return"es.sso.user";return Q(n),n};function e(n,i,t=A){if(typeof window>"u")return null;try{let T=(n==="local"?localStorage:sessionStorage).getItem(i);if(!T)return null;let p=JSON.parse(T);if(p.sso?.expires)p.sso.expires=new Date(p.sso.expires);return p}catch(c){return t.error("Error loading user from storage:",c),null}}async function _(n,i=A){try{let t=await fetch(n);if(t.status===401)return null;if(!t.ok)throw Error(`Failed to fetch user: ${t.status} ${t.statusText}`);let c=await t.json();if(c.sso?.expires&&typeof c.sso.expires==="string")c.sso.expires=new Date(c.sso.expires);return c}catch(t){return i.error("Error fetching user from URL:",t),null}}function Z({storageKey:n,userUrl:i,storage:t="memory",disableListener:c=!1,log:T=A,children:p}){let[h,r]=w(null),[N,o]=w(!!i),m=W(n),x=l(()=>{if(t==="memory")return null;return e(t,m,T)},[t,m,T]),d=l((f)=>{if(t==="memory"||typeof window>"u")return;try{let a=t==="local"?localStorage:sessionStorage;if(f===null)a.removeItem(m);else a.setItem(m,JSON.stringify(f))}catch(a){T.error("Error saving user to storage:",a)}},[t,m,T]),u=l((f)=>{r(f),d(f)},[d]),E=l(async()=>{if(!i)return;o(!0);try{let f=await _(i,T);r(f),d(f)}finally{o(!1)}},[i,d,T]);$(()=>{let f=x();if(f)r(f);if(i)E();else o(!1)},[x,i,E]),$(()=>{if(c||t==="memory")return;let f=(C)=>{if(C.key!==m)return;if(C.newValue===null)r(null);else try{let P=JSON.parse(C.newValue);if(P.sso?.expires)P.sso.expires=new Date(P.sso.expires);r(P)}catch(P){T.error("Error parsing user from storage event:",P)}},a=()=>{r(null)};return window.addEventListener("storage",f),window.addEventListener("es-sso-logout",a),()=>{window.removeEventListener("storage",f),window.removeEventListener("es-sso-logout",a)}},[c,t,m,T]);let V={user:h,setUser:u,isLoading:N};return S(O.Provider,{value:V,children:p})}function R(){let n=H(O);if(n===void 0)throw Error("useSSOContext must be used within a SSOProvider");return n}async function G(n,i){let t=W(i),c=e("local",t);if(c)return c;let T=e("session",t);if(T)return T;if(n){let p=await _(n);if(p)return p}return}async function Y(n){try{let i=await fetch(n,{headers:{Accept:"application/json"}});if(!i.ok)return{success:!1,error:`HTTP ${i.status}`};let t=await i.json();if(!t.success)return{success:!1,error:t.message||"Logout failed"};if(typeof window<"u")localStorage.removeItem("es.sso.user"),sessionStorage.removeItem("es.sso.user"),window.dispatchEvent(new CustomEvent("es-sso-logout"));return{success:!0}}catch(i){return{success:!1,error:i instanceof Error?i.message:"Network error"}}}import{jsx as v,Fragment as b}from"react/jsx-runtime";function X({complete:n=!1,children:i}){let{isLoading:t}=R();if(t&&!n)return v(b,{children:i});return null}import{jsx as j,Fragment as k}from"react/jsx-runtime";function L({children:n}){let{user:i}=R();if(i)return j(k,{children:n});return null}import{jsx as s,Fragment as K}from"react/jsx-runtime";function F({children:n}){let{user:i,isLoading:t}=R();if(i||t)return null;return s(K,{children:n})}import{buildTenantPath as y,DEFAULT_TENANT_API_NAMESPACE as U,DEFAULT_TENANT_UI_NAMESPACE as g,normalizeTenantRoutingStrategy as B}from"@enterprisestandard/core";import{createContext as nn,useContext as tn,useMemo as cn}from"react";import{jsx as un}from"react/jsx-runtime";var I=nn(null);function q(n,i){let t=B(i);if(t.type==="jwt"){let p=t.ui?.segments??[],h=t.api?.segments??["api"];return{ui:(r="/")=>z(p,r),api:(r="/")=>z(h,r)}}let c=t.ui??g,T=t.api??U;return{ui:(p="/")=>y(n,p,c),api:(p="/")=>y(n,p,T)}}function z(n,i="/"){let t=n.join("/"),c=i.trim().replace(/^\/+/,"");if(!t&&!c)return"/";if(!t)return`/${c}`;if(!c)return`/${t}`;return`/${t}/${c}`}function Tn({id:n,strategy:i,children:t}){let c=cn(()=>{let T=B(i);return{id:n,strategy:T,urls:q(n,T)}},[i,n]);return un(I.Provider,{value:c,children:t})}function pn(){let n=tn(I);if(!n)throw Error("useTenant() must be used within a TenantProvider");return n}import{useCallback as rn,useEffect as fn,useMemo as mn,useState as M}from"react";function on(n={}){let i=n.tenantManagerBaseUrl??"/api/tenants/mine",[t,c]=M(null),[T,p]=M(!0),[h,r]=M(null),N=mn(()=>{let u=new URL(i,"http://localhost");if(n.start!=null)u.searchParams.set("start",String(n.start));if(n.limit!=null)u.searchParams.set("limit",String(n.limit));if(n.order)u.searchParams.set("order",n.order);return`${u.pathname}${u.search}`},[n.limit,n.order,n.start,i]),o=rn(async()=>{p(!0),r(null);try{let u=await fetch(N);if(!u.ok){c(null),r(Error(`Tenant directory request failed with status ${u.status}`));return}let E=await u.json();c(E)}catch(u){c(null),r(u instanceof Error?u:Error("Failed to load tenant directory"))}finally{p(!1)}},[N]);fn(()=>{o()},[o]);let m=t?.tenants??{},x=t?.ids??[],d=x.map((u)=>m[u]).filter((u)=>!!u);return{directory:t,tenants:m,ids:x,items:d,isLoading:T,error:h,refresh:o}}export{on as useTenantDirectory,pn as useTenant,Y as logout,G as getUser,q as createTenantUrls,Tn as TenantProvider,F as SignedOut,L as SignedIn,X as SignInLoading,Z as SSOProvider};
1
+ export*from"@enterprisestandard/core";import{generateULID as qn}from"@enterprisestandard/core";import{silentLogger as A}from"@enterprisestandard/core";import{createContext as V,useCallback as e,useContext as H,useEffect as $,useState as w}from"react";import{jsx as S}from"react/jsx-runtime";var O=V(void 0),J=/^[a-zA-Z0-9._-]{1,1024}$/;function Q(n){if(!n.trim())throw Error("SSOProvider storageKey must be a non-empty string.");if(!J.test(n))throw Error("SSOProvider storageKey must be 1-1024 characters and contain only letters, numbers, dots, underscores, and hyphens.")}var W=(n)=>{if(n===void 0||n==="")return"es.sso.user";return Q(n),n};function C(n,i,t=A){if(typeof window>"u")return null;try{let T=(n==="local"?localStorage:sessionStorage).getItem(i);if(!T)return null;let p=JSON.parse(T);if(p.sso?.expires)p.sso.expires=new Date(p.sso.expires);return p}catch(c){return t.error("Error loading user from storage:",c),null}}async function I(n,i=A){try{let t=await fetch(n);if(t.status===401)return null;if(!t.ok)throw Error(`Failed to fetch user: ${t.status} ${t.statusText}`);let c=await t.json();if(c.sso?.expires&&typeof c.sso.expires==="string")c.sso.expires=new Date(c.sso.expires);return c}catch(t){return i.error("Error fetching user from URL:",t),null}}function Z({storageKey:n,userUrl:i,storage:t="memory",disableListener:c=!1,log:T=A,children:p}){let[h,r]=w(null),[N,o]=w(!!i),m=W(n),x=e(()=>{if(t==="memory")return null;return C(t,m,T)},[t,m,T]),d=e((f)=>{if(t==="memory"||typeof window>"u")return;try{let a=t==="local"?localStorage:sessionStorage;if(f===null)a.removeItem(m);else a.setItem(m,JSON.stringify(f))}catch(a){T.error("Error saving user to storage:",a)}},[t,m,T]),u=e((f)=>{r(f),d(f)},[d]),E=e(async()=>{if(!i)return;o(!0);try{let f=await I(i,T);r(f),d(f)}finally{o(!1)}},[i,d,T]);$(()=>{let f=x();if(f)r(f);if(i)E();else o(!1)},[x,i,E]),$(()=>{if(c||t==="memory")return;let f=(l)=>{if(l.key!==m)return;if(l.newValue===null)r(null);else try{let P=JSON.parse(l.newValue);if(P.sso?.expires)P.sso.expires=new Date(P.sso.expires);r(P)}catch(P){T.error("Error parsing user from storage event:",P)}},a=()=>{r(null)};return window.addEventListener("storage",f),window.addEventListener("es-sso-logout",a),()=>{window.removeEventListener("storage",f),window.removeEventListener("es-sso-logout",a)}},[c,t,m,T]);let D={user:h,setUser:u,isLoading:N};return S(O.Provider,{value:D,children:p})}function R(){let n=H(O);if(n===void 0)throw Error("useSSOContext must be used within a SSOProvider");return n}async function G(n,i){let t=W(i),c=C("local",t);if(c)return c;let T=C("session",t);if(T)return T;if(n){let p=await I(n);if(p)return p}return}async function Y(n){try{let i=await fetch(n,{headers:{Accept:"application/json"}});if(!i.ok)return{success:!1,error:`HTTP ${i.status}`};let t=await i.json();if(!t.success)return{success:!1,error:t.message||"Logout failed"};if(typeof window<"u")localStorage.removeItem("es.sso.user"),sessionStorage.removeItem("es.sso.user"),window.dispatchEvent(new CustomEvent("es-sso-logout"));return{success:!0}}catch(i){return{success:!1,error:i instanceof Error?i.message:"Network error"}}}import{jsx as v,Fragment as b}from"react/jsx-runtime";function X({complete:n=!1,children:i}){let{isLoading:t}=R();if(t&&!n)return v(b,{children:i});return null}import{jsx as j,Fragment as k}from"react/jsx-runtime";function L({children:n}){let{user:i}=R();if(i)return j(k,{children:n});return null}import{jsx as s,Fragment as K}from"react/jsx-runtime";function F({children:n}){let{user:i,isLoading:t}=R();if(i||t)return null;return s(K,{children:n})}import{buildTenantPath as _,DEFAULT_TENANT_API_NAMESPACE as U,DEFAULT_TENANT_UI_NAMESPACE as g,normalizeTenantRoutingStrategy as z}from"@enterprisestandard/core";import{createContext as nn,useContext as tn,useMemo as cn}from"react";import{jsx as un}from"react/jsx-runtime";var B=nn(null);function q(n,i){let t=z(i);if(t.type==="jwt"){let p=t.ui?.segments??[],h=t.api?.segments??["api"];return{ui:(r="/")=>y(p,r),api:(r="/")=>y(h,r)}}let c=t.ui??g,T=t.api??U;return{ui:(p="/")=>_(n,p,c),api:(p="/")=>_(n,p,T)}}function y(n,i="/"){let t=n.join("/"),c=i.trim().replace(/^\/+/,"");if(!t&&!c)return"/";if(!t)return`/${c}`;if(!c)return`/${t}`;return`/${t}/${c}`}function Tn({id:n,strategy:i,children:t}){let c=cn(()=>{let T=z(i);return{id:n,strategy:T,urls:q(n,T)}},[i,n]);return un(B.Provider,{value:c,children:t})}function pn(){let n=tn(B);if(!n)throw Error("useTenant() must be used within a TenantProvider");return n}import{useCallback as rn,useEffect as fn,useMemo as mn,useState as M}from"react";function on(n={}){let i=n.tenantManagerBaseUrl??"/api/tenants/mine",[t,c]=M(null),[T,p]=M(!0),[h,r]=M(null),N=mn(()=>{let u=new URL(i,"http://localhost");if(n.start!=null)u.searchParams.set("start",String(n.start));if(n.limit!=null)u.searchParams.set("limit",String(n.limit));if(n.order)u.searchParams.set("order",n.order);return`${u.pathname}${u.search}`},[n.limit,n.order,n.start,i]),o=rn(async()=>{p(!0),r(null);try{let u=await fetch(N);if(!u.ok){c(null),r(Error(`Tenant directory request failed with status ${u.status}`));return}let E=await u.json();c(E)}catch(u){c(null),r(u instanceof Error?u:Error("Failed to load tenant directory"))}finally{p(!1)}},[N]);fn(()=>{o()},[o]);let m=t?.tenants??{},x=t?.ids??[],d=x.map((u)=>m[u]).filter((u)=>!!u);return{directory:t,tenants:m,ids:x,items:d,isLoading:T,error:h,refresh:o}}export{on as useTenantDirectory,pn as useTenant,Y as logout,G as getUser,qn as generateULID,q as createTenantUrls,Tn as TenantProvider,F as SignedOut,L as SignedIn,X as SignInLoading,Z as SSOProvider};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enterprisestandard/react",
3
- "version": "0.0.20-beta.20260522.2",
3
+ "version": "0.0.20-beta.20260601.4",
4
4
  "description": "Enterprise Standard React Components",
5
5
  "private": false,
6
6
  "author": "enterprisestandard",
@@ -22,7 +22,7 @@
22
22
  "./package.json": "./package.json"
23
23
  },
24
24
  "dependencies": {
25
- "@enterprisestandard/core": "0.0.20-beta.20260522.2"
25
+ "@enterprisestandard/core": "0.0.20-beta.20260601.4"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "react": "^18.0.0 || ^19.0.0",