@burdenoff/fe-libs 2026.813.4 → 2026.814.1

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.
@@ -103,6 +103,41 @@ export declare const SUPER_ADMIN_ACTOR_TYPE: "super_admin";
103
103
  * matchPermission("project:read", "project:*") // true (user has wildcard)
104
104
  * matchPermission("*", "project:read") // true
105
105
  */
106
+ /**
107
+ * Tracks when the current scope first came back with no access at all, so the
108
+ * catch-up poll can be bounded. `null` means "not currently empty".
109
+ */
110
+ export type EmptyPermissionsTracker = {
111
+ scopeId: string | null;
112
+ at: number;
113
+ } | null;
114
+ export interface PermissionsRefetchIntervalInput {
115
+ data: EffectivePermissions | undefined;
116
+ scopeId: string | null;
117
+ tracker: EmptyPermissionsTracker;
118
+ now: number;
119
+ refetchInterval: number;
120
+ emptyPermissionsRefetchInterval: number;
121
+ emptyPermissionsCatchupWindow: number;
122
+ }
123
+ /**
124
+ * Decide how soon to re-fetch permissions, and carry the empty-since tracker.
125
+ *
126
+ * An authenticated actor resolving to zero roles AND zero permissions in their
127
+ * own scope is a transient state, not a steady one: workspace provisioning is
128
+ * asynchronous (the RBAC layer clones the role catalog off `workspace.created`,
129
+ * ~90-130s after signup in production). On the normal interval the UI would sit
130
+ * with no product nav and blocked pages for up to five minutes after the
131
+ * backend had already caught up. Poll quickly until access appears, then revert.
132
+ *
133
+ * The window is bounded so an actor who genuinely has no access in this scope —
134
+ * an invited member of someone else's workspace, say — settles back onto the
135
+ * normal cadence instead of polling forever.
136
+ */
137
+ export declare function resolvePermissionsRefetchInterval(input: PermissionsRefetchIntervalInput): {
138
+ interval: number;
139
+ tracker: EmptyPermissionsTracker;
140
+ };
106
141
  export declare function matchPermission(userPermission: string, requiredPermission: string): boolean;
107
142
  /**
108
143
  * Check if any user permission matches the required permission
@@ -144,6 +179,31 @@ export interface PermissionProviderProps {
144
179
  * @default 120000 (2 minutes)
145
180
  */
146
181
  refetchOnFocusStaleTime?: number;
182
+ /**
183
+ * How often to re-poll while the actor resolves to NO roles at all (ms).
184
+ *
185
+ * A brand-new workspace is provisioned asynchronously: the tenant layer
186
+ * creates it, publishes `workspace.created`, and the RBAC layer clones the
187
+ * role catalog and assigns the owner off that event. Measured in production
188
+ * that lands ~90-130s after signup. A user who lands on the app inside that
189
+ * window fetches an empty permission set, and on the normal `refetchInterval`
190
+ * would keep a stripped-down UI (no product nav, blocked pages) for up to
191
+ * five minutes with nothing prompting a retry — the backend catches up but
192
+ * the UI never notices until a manual reload.
193
+ *
194
+ * Empty is only ever a transient state for an authenticated actor in their
195
+ * own scope, so poll quickly until roles appear, then fall back to the normal
196
+ * interval. Bounded by `emptyPermissionsCatchupWindow` so a genuinely
197
+ * permissionless actor does not poll forever.
198
+ * @default 5000 (5 seconds)
199
+ */
200
+ emptyPermissionsRefetchInterval?: number;
201
+ /**
202
+ * How long to keep fast-polling an empty permission set before giving up and
203
+ * reverting to `refetchInterval` (ms).
204
+ * @default 180000 (3 minutes)
205
+ */
206
+ emptyPermissionsCatchupWindow?: number;
147
207
  /**
148
208
  * Enable debug logging
149
209
  * @default false
@@ -189,6 +249,8 @@ export interface PermissionProviderProps {
189
249
  export declare function PermissionProvider({ children, scopeId, gateway, staleTime, // 5 minutes
190
250
  refetchInterval, // 5 minutes
191
251
  refetchOnFocusStaleTime, // 2 minutes
252
+ emptyPermissionsRefetchInterval, // 5 seconds
253
+ emptyPermissionsCatchupWindow, // 3 minutes
192
254
  debug, }: PermissionProviderProps): import("react/jsx-runtime").JSX.Element;
193
255
  /**
194
256
  * Hook to access permission context
@@ -1 +1 @@
1
- {"version":3,"file":"PermissionProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/shell/PermissionProvider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PermissionProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/shell/PermissionProvider.tsx"],"names":[],"mappings":"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"}
@@ -1,11 +1,11 @@
1
1
  import { graphqlFetch as e } from "../../graphql/fetch.js";
2
2
  import { useAuth as t } from "./AuthProvider.js";
3
- import { createContext as n, use as r, useCallback as i, useEffect as a, useMemo as o } from "react";
4
- import { jsx as s } from "react/jsx-runtime";
5
- import { useQuery as c, useQueryClient as l } from "@tanstack/react-query";
3
+ import { createContext as n, use as r, useCallback as i, useEffect as a, useMemo as o, useRef as s } from "react";
4
+ import { jsx as c } from "react/jsx-runtime";
5
+ import { useQuery as l, useQueryClient as u } from "@tanstack/react-query";
6
6
  //#region src/shared/providers/shell/PermissionProvider.tsx
7
- var u = n(null), d = "SUPER_ADMIN", f = "super_admin", p = "\n query MyPermissions($scopeId: String!) {\n myPermissions(scopeId: $scopeId) {\n actorId\n scopeId\n roles\n permissions {\n resourceType\n level\n allowedActions\n }\n }\n }\n";
8
- function m(e) {
7
+ var d = n(null), f = "SUPER_ADMIN", p = "super_admin", m = "\n query MyPermissions($scopeId: String!) {\n myPermissions(scopeId: $scopeId) {\n actorId\n scopeId\n roles\n permissions {\n resourceType\n level\n allowedActions\n }\n }\n }\n";
8
+ function h(e) {
9
9
  let t = e.permissionStrings ?? e.permissions.flatMap((e) => {
10
10
  let t = [];
11
11
  return e.level === "ADMIN" && t.push(`${e.resourceType}:*`), t.push(...e.allowedActions.map((t) => `${e.resourceType}:${t}`)), t;
@@ -25,153 +25,186 @@ function m(e) {
25
25
  cacheKey: e.cacheKey
26
26
  };
27
27
  }
28
- function h(e, t) {
28
+ function g(e) {
29
+ let { data: t, scopeId: n, tracker: r, now: i, refetchInterval: a, emptyPermissionsRefetchInterval: o, emptyPermissionsCatchupWindow: s } = e;
30
+ return t ? t.roles.length > 0 || t.permissions.length > 0 ? {
31
+ interval: a,
32
+ tracker: null
33
+ } : !r || r.scopeId !== n ? {
34
+ interval: o,
35
+ tracker: {
36
+ scopeId: n,
37
+ at: i
38
+ }
39
+ } : i - r.at >= s ? {
40
+ interval: a,
41
+ tracker: r
42
+ } : {
43
+ interval: o,
44
+ tracker: r
45
+ } : {
46
+ interval: a,
47
+ tracker: r
48
+ };
49
+ }
50
+ function _(e, t) {
29
51
  if (e === t || e === "*") return !0;
30
52
  let [n, r] = e.split(":"), [i, a] = t.split(":");
31
53
  return n !== i && n !== "*" ? !1 : r === "*" || a === "*" ? !0 : r === a;
32
54
  }
33
- function g(e, t) {
34
- return e.some((e) => h(e, t));
55
+ function v(e, t) {
56
+ return e.some((e) => _(e, t));
35
57
  }
36
- function _(e, t, n) {
58
+ function y(e, t, n) {
37
59
  return e && (t === "SUPER_ADMIN" || n === "super_admin");
38
60
  }
39
- function v(e) {
61
+ function b(e) {
40
62
  if (!e || typeof e != "object") return null;
41
63
  let t = e;
42
64
  return typeof t.actorType == "string" ? t.actorType : typeof t.actor_type == "string" ? t.actor_type : null;
43
65
  }
44
- function y({ children: n, scopeId: r, gateway: d = "workspace", staleTime: f = 300 * 1e3, refetchInterval: h = 300 * 1e3, refetchOnFocusStaleTime: y = 120 * 1e3, debug: b = !1 }) {
45
- let { isAuthenticated: x, tokens: S, workspaceToken: C, user: w } = t(), T = l(), E = _(x, w?.role, v(w)), D = d === "workspace" ? C ? C.slice(-16) : "missing" : "n/a", O = o(() => [
66
+ function x({ children: n, scopeId: r, gateway: f = "workspace", staleTime: p = 300 * 1e3, refetchInterval: _ = 300 * 1e3, refetchOnFocusStaleTime: x = 120 * 1e3, emptyPermissionsRefetchInterval: S = 5 * 1e3, emptyPermissionsCatchupWindow: C = 180 * 1e3, debug: w = !1 }) {
67
+ let { isAuthenticated: T, tokens: E, workspaceToken: D, user: O } = t(), k = u(), A = y(T, O?.role, b(O)), j = f === "workspace" ? D ? D.slice(-16) : "missing" : "n/a", M = o(() => [
46
68
  "permissions",
47
- d,
69
+ f,
48
70
  r,
49
- D
71
+ j
50
72
  ], [
51
- d,
73
+ f,
52
74
  r,
53
- D
54
- ]), k = i(async () => {
75
+ j
76
+ ]), N = i(async () => {
55
77
  if (!r) throw Error("scopeId is required for permission fetching");
56
- b && console.log("[PermissionProvider] Fetching permissions for scope:", r);
78
+ w && console.log("[PermissionProvider] Fetching permissions for scope:", r);
57
79
  let t = await e({
58
- query: p,
80
+ query: m,
59
81
  variables: { scopeId: r },
60
- gateway: d
82
+ gateway: f
61
83
  });
62
84
  if (t.errors?.length) throw Error(t.errors[0].message);
63
85
  if (!t.data?.myPermissions) throw Error("No permissions returned from server");
64
- let n = m(t.data.myPermissions);
65
- return b && console.log("[PermissionProvider] Received permissions:", n), n;
86
+ let n = h(t.data.myPermissions);
87
+ return w && console.log("[PermissionProvider] Received permissions:", n), n;
66
88
  }, [
67
89
  r,
68
- d,
69
- b
70
- ]), A = !E && x && !!r && !!S?.accessToken, j = c({
71
- queryKey: O,
72
- queryFn: k,
73
- enabled: A,
74
- staleTime: f,
75
- refetchInterval: h,
90
+ f,
91
+ w
92
+ ]), P = !A && T && !!r && !!E?.accessToken, F = s(null), I = l({
93
+ queryKey: M,
94
+ queryFn: N,
95
+ enabled: P,
96
+ staleTime: p,
97
+ refetchInterval: (e) => {
98
+ let { interval: t, tracker: n } = g({
99
+ data: e.state.data,
100
+ scopeId: r,
101
+ tracker: F.current,
102
+ now: Date.now(),
103
+ refetchInterval: _,
104
+ emptyPermissionsRefetchInterval: S,
105
+ emptyPermissionsCatchupWindow: C
106
+ });
107
+ return F.current = n, w && t === S && console.log("[PermissionProvider] No roles yet for scope; polling for provisioning to land", { scopeId: r }), t;
108
+ },
76
109
  refetchOnWindowFocus: (e) => {
77
- let t = e.state.dataUpdatedAt, n = Date.now() - t > y;
78
- return b && n && console.log("[PermissionProvider] Refetching on window focus (stale)"), n;
110
+ let t = e.state.dataUpdatedAt, n = Date.now() - t > x;
111
+ return w && n && console.log("[PermissionProvider] Refetching on window focus (stale)"), n;
79
112
  },
80
113
  refetchOnReconnect: !0,
81
114
  retry: 2,
82
115
  retryDelay: (e) => Math.min(1e3 * 2 ** e, 1e4)
83
- }), { data: M, error: N, isLoading: P, refetch: F } = j;
116
+ }), { data: L, error: R, isLoading: z, refetch: B } = I;
84
117
  a(() => {
85
- if (!M?.expiresAt || !A) return;
86
- let e = new Date(M.expiresAt).getTime() - Date.now();
118
+ if (!L?.expiresAt || !P) return;
119
+ let e = new Date(L.expiresAt).getTime() - Date.now();
87
120
  if (e <= 0) {
88
- b && console.log("[PermissionProvider] Permissions expired, refetching"), F();
121
+ w && console.log("[PermissionProvider] Permissions expired, refetching"), B();
89
122
  return;
90
123
  }
91
124
  let t = Math.max(0, e - 3e4), n = setTimeout(() => {
92
- b && console.log("[PermissionProvider] Permissions expiring, refetching"), A && F();
125
+ w && console.log("[PermissionProvider] Permissions expiring, refetching"), P && B();
93
126
  }, t);
94
127
  return () => clearTimeout(n);
95
128
  }, [
96
- M?.expiresAt,
97
- b,
98
- A,
99
- F
129
+ L?.expiresAt,
130
+ w,
131
+ P,
132
+ B
100
133
  ]);
101
- let I = A ? M ?? null : null, L = i((e) => E ? !0 : I?.permissionStrings ? g(I.permissionStrings, e) : !1, [I?.permissionStrings, E]), R = i((e, t) => {
102
- if (E) return !0;
103
- if (!I?.permissionStrings) return !1;
134
+ let V = P ? L ?? null : null, H = i((e) => A ? !0 : V?.permissionStrings ? v(V.permissionStrings, e) : !1, [V?.permissionStrings, A]), U = i((e, t) => {
135
+ if (A) return !0;
136
+ if (!V?.permissionStrings) return !1;
104
137
  let { requireAll: n = !1 } = t ?? {};
105
- return n ? e.every((e) => g(I.permissionStrings, e)) : e.some((e) => g(I.permissionStrings, e));
106
- }, [I?.permissionStrings, E]), z = i((e) => E ? !0 : I?.roles ? I.roles.includes(e) : !1, [I?.roles, E]), B = i((e) => E ? !0 : I?.roles ? e.some((e) => I.roles.includes(e)) : !1, [I?.roles, E]), V = i((e) => E ? !0 : I?.roles ? e.every((e) => I.roles.includes(e)) : !1, [I?.roles, E]), H = i(async () => {
107
- if (!A) {
108
- b && console.log("[PermissionProvider] Skipping manual refresh — workspace token not available");
138
+ return n ? e.every((e) => v(V.permissionStrings, e)) : e.some((e) => v(V.permissionStrings, e));
139
+ }, [V?.permissionStrings, A]), W = i((e) => A ? !0 : V?.roles ? V.roles.includes(e) : !1, [V?.roles, A]), G = i((e) => A ? !0 : V?.roles ? e.some((e) => V.roles.includes(e)) : !1, [V?.roles, A]), K = i((e) => A ? !0 : V?.roles ? e.every((e) => V.roles.includes(e)) : !1, [V?.roles, A]), q = i(async () => {
140
+ if (!P) {
141
+ w && console.log("[PermissionProvider] Skipping manual refresh — workspace token not available");
109
142
  return;
110
143
  }
111
- b && console.log("[PermissionProvider] Manual refresh requested"), await F();
144
+ w && console.log("[PermissionProvider] Manual refresh requested"), await B();
112
145
  }, [
113
- F,
114
- b,
115
- A
116
- ]), U = i(async () => {
117
- b && console.log("[PermissionProvider] Invalidating permissions cache"), await T.invalidateQueries({ queryKey: O });
146
+ B,
147
+ w,
148
+ P
149
+ ]), J = i(async () => {
150
+ w && console.log("[PermissionProvider] Invalidating permissions cache"), await k.invalidateQueries({ queryKey: M });
118
151
  }, [
119
- T,
120
- O,
121
- b
122
- ]), W = o(() => ({
123
- permissions: I,
124
- isLoading: !E && P,
125
- error: E ? null : N,
126
- hasPermission: L,
127
- hasPermissions: R,
128
- hasRole: z,
129
- hasAnyRole: B,
130
- hasAllRoles: V,
131
- refreshPermissions: H,
132
- invalidatePermissions: U,
152
+ k,
153
+ M,
154
+ w
155
+ ]), Y = o(() => ({
156
+ permissions: V,
157
+ isLoading: !A && z,
158
+ error: A ? null : R,
159
+ hasPermission: H,
160
+ hasPermissions: U,
161
+ hasRole: W,
162
+ hasAnyRole: G,
163
+ hasAllRoles: K,
164
+ refreshPermissions: q,
165
+ invalidatePermissions: J,
133
166
  scopeId: r,
134
- isSuperAdmin: E,
135
- query: j
167
+ isSuperAdmin: A,
168
+ query: I
136
169
  }), [
170
+ V,
171
+ A,
137
172
  I,
138
- E,
139
- j,
140
- N,
141
- P,
142
- L,
143
173
  R,
144
174
  z,
145
- B,
146
- V,
147
175
  H,
148
176
  U,
177
+ W,
178
+ G,
179
+ K,
180
+ q,
181
+ J,
149
182
  r
150
183
  ]);
151
- return /* @__PURE__ */ s(u.Provider, {
152
- value: W,
184
+ return /* @__PURE__ */ c(d.Provider, {
185
+ value: Y,
153
186
  children: n
154
187
  });
155
188
  }
156
- function b() {
157
- let e = r(u);
189
+ function S() {
190
+ let e = r(d);
158
191
  if (!e) throw Error("usePermissions must be used within a PermissionProvider");
159
192
  return e;
160
193
  }
161
- function x() {
162
- return r(u);
194
+ function C() {
195
+ return r(d);
163
196
  }
164
- function S(e) {
165
- let { hasPermission: t, isLoading: n } = b();
197
+ function w(e) {
198
+ let { hasPermission: t, isLoading: n } = S();
166
199
  return n ? !1 : t(e);
167
200
  }
168
- function C(e) {
169
- let { hasRole: t, isLoading: n } = b();
201
+ function T(e) {
202
+ let { hasRole: t, isLoading: n } = S();
170
203
  return n ? !1 : t(e);
171
204
  }
172
- function w() {
173
- let { isLoading: e } = b();
205
+ function E() {
206
+ let { isLoading: e } = S();
174
207
  return e;
175
208
  }
176
209
  //#endregion
177
- export { y as PermissionProvider, f as SUPER_ADMIN_ACTOR_TYPE, d as SUPER_ADMIN_ROLE, g as hasMatchingPermission, _ as isSuperAdminBypass, h as matchPermission, S as usePermission, w as usePermissionLoading, b as usePermissions, C as useRole, x as useSafePermissions };
210
+ export { x as PermissionProvider, p as SUPER_ADMIN_ACTOR_TYPE, f as SUPER_ADMIN_ROLE, v as hasMatchingPermission, y as isSuperAdminBypass, _ as matchPermission, w as usePermission, E as usePermissionLoading, S as usePermissions, T as useRole, C as useSafePermissions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fe-libs",
3
- "version": "2026.813.4",
3
+ "version": "2026.814.1",
4
4
  "description": "Burdenoff frontend primitives and domain libraries",
5
5
  "type": "module",
6
6
  "bin": {