diff --git a/dist/core.js b/dist/core.js index 10bf5a7..1313f20 100644 --- a/dist/core.js +++ b/dist/core.js @@ -1,31 +1,31 @@ import _ from "axios"; -import { jsx as b, jsxs as M } from "react/jsx-runtime"; +import { jsx as b, jsxs as D } from "react/jsx-runtime"; import $ from "keycloak-js"; -import ee, { createContext as N, useState as X, useRef as R, useCallback as K, useEffect as g, useMemo as f, useContext as te } from "react"; +import ee, { createContext as V, useState as K, useRef as N, useCallback as g, useEffect as f, useMemo as z, useContext as te } from "react"; import { useQueryClient as re, useMutation as ne, useQuery as P, QueryClient as oe, QueryClientProvider as ie } from "@tanstack/react-query"; import { createRoot as se } from "react-dom/client"; -import { extendTheme as ae, withDefaultColorScheme as ue, ChakraProvider as I, Spinner as de, Badge as ce } from "@chakra-ui/react"; -import D from "next-query-params/pages"; -import le from "use-query-params"; +import { extendTheme as ae, withDefaultColorScheme as ue, ChakraProvider as R, Spinner as de, Badge as ce } from "@chakra-ui/react"; +import * as M from "next-query-params/pages"; +import * as le from "use-query-params"; import { Global as he } from "@emotion/react"; -let W = null, o = null, Y = null, O = !1; -const Se = N(null), pe = ({ url: e, realm: r, clientId: t }) => (o || (o = new $({ +let v = null, o = null, Y = null, W = !1; +const pe = V(null), Se = ({ url: e, realm: r, clientId: t }) => (o || (o = new $({ url: e, realm: r, clientId: t -})), o), Fe = (e) => (W = e, W), me = () => O, G = () => !!(o != null && o.authenticated), x = () => (o == null ? void 0 : o.token) ?? null, C = async (e = 30) => o ? o.updateToken(e) : !1, J = (e) => o == null ? void 0 : o.logout(e), tt = (e) => o == null ? void 0 : o.login(e), H = ({ config: e, initOptions: r = {} } = {}) => { - const t = e ?? W; +})), o), me = (e) => (v = e, v), Fe = () => W, I = () => !!(o != null && o.authenticated), x = () => (o == null ? void 0 : o.token) ?? null, C = async (e = 30) => o ? o.updateToken(e) : !1, G = (e) => o == null ? void 0 : o.logout(e), et = (e) => o == null ? void 0 : o.login(e), J = ({ config: e, initOptions: r = {} } = {}) => { + const t = e ?? v; if (!(t != null && t.url) || !(t != null && t.realm) || !(t != null && t.clientId)) throw new Error("Keycloak config is required."); - Fe(t); - const n = pe(t); + me(t); + const n = Se(t); return Y || (Y = n.init({ onLoad: "login-required", checkLoginIframe: !1, flow: "implicit", ...r - }).then((d) => (O = !0, d)).catch((d) => { - throw O = !0, d; + }).then((s) => (W = !0, s)).catch((s) => { + throw W = !0, s; })), Y; }, qe = ({ children: e, @@ -33,78 +33,78 @@ const Se = N(null), pe = ({ url: e, realm: r, clientId: t }) => (o || (o = new $ initOptions: t, loading: n = null }) => { - const [d, h] = X(!1), [u, s] = X(!1), [a, p] = X(null), m = R(!1), i = K(() => { - o && (s(!!o.authenticated), p(o.token ?? null)); + const [s, h] = K(!1), [d, a] = K(!1), [u, S] = K(null), F = N(!1), i = g(() => { + o && (a(!!o.authenticated), S(o.token ?? null)); }, []); - g(() => (m.current = !0, H({ config: r, initOptions: t }).then((l) => { - m.current && (s(!!l), p((o == null ? void 0 : o.token) ?? null), h(!0)); + f(() => (F.current = !0, J({ config: r, initOptions: t }).then((l) => { + F.current && (a(!!l), S((o == null ? void 0 : o.token) ?? null), h(!0)); }).catch(() => { - m.current && (s(!1), p(null), h(!0)); + F.current && (a(!1), S(null), h(!0)); }), () => { - m.current = !1; + F.current = !1; }), [r, t]); - const c = K(() => o == null ? void 0 : o.login(), []), q = K((l) => o == null ? void 0 : o.logout(l), []), S = K( + const c = g(() => o == null ? void 0 : o.login(), []), q = g((l) => o == null ? void 0 : o.logout(l), []), p = g( async (l = 30) => { if (!o) return !1; const Z = await o.updateToken(l); return i(), Z; }, [i] - ), F = f( + ), m = z( () => ({ - initialized: d, - authenticated: u, - token: a, + initialized: s, + authenticated: d, + token: u, login: c, logout: q, - updateToken: S + updateToken: p }), - [d, u, a, c, q, S] + [s, d, u, c, q, p] ); - return d ? /* @__PURE__ */ b(Se.Provider, { value: F, children: e }) : n; + return s ? /* @__PURE__ */ b(pe.Provider, { value: m, children: e }) : n; }; let B = null; const Ee = (e) => { const { api: r } = e, t = _.create({ baseURL: r.baseUrl }), n = async () => { - (!me() || !G()) && await H(); - }, d = !!e.keycloak, h = async (s) => { - if (!d) return s; + (!Fe() || !I()) && await J(); + }, s = !!e.keycloak, h = async (a) => { + if (!s) return a; await n(); - let a = x(); - if (a) { + let u = x(); + if (u) { try { - await C(5), a = x(); + await C(5), u = x(); } catch { } - s.headers = { - ...s.headers, - Authorization: `Bearer ${a}` + a.headers = { + ...a.headers, + Authorization: `Bearer ${u}` }; } - return s; - }, u = async (s) => { - var p; - const a = s.config; - if (((p = s == null ? void 0 : s.response) == null ? void 0 : p.status) === 401 && !(a != null && a._retry)) { - a._retry = !0; + return a; + }, d = async (a) => { + var S; + const u = a.config; + if (((S = a == null ? void 0 : a.response) == null ? void 0 : S.status) === 401 && !(u != null && u._retry)) { + u._retry = !0; try { await C(30); - const m = x(); - return a.headers = { - ...a.headers, - Authorization: `Bearer ${m}` - }, t(a); + const F = x(); + return u.headers = { + ...u.headers, + Authorization: `Bearer ${F}` + }, t(u); } catch { - J({ redirectUri: window.location.origin }); + G({ redirectUri: window.location.origin }); } } - return Promise.reject(s); + return Promise.reject(a); }; return t.interceptors.request.use(h), t.interceptors.response.use( - (s) => s, - u + (a) => a, + d ), { api: t }; @@ -112,79 +112,79 @@ const Ee = (e) => { if (!B) throw new Error("api is not configured. Call configureApi(config) first."); return B.api; -}, k = new Proxy( +}, H = new Proxy( {}, { get(e, r) { return ye()[r]; } } -), be = async (e) => (await k.get(e)).data; -function v(e) { +), be = async (e) => (await H.get(e)).data; +function O(e) { return Array.isArray(e) ? e : [e]; } function Te(e) { - return [...v(e), "list"]; + return [...O(e), "list"]; } function U(e, r) { - return [...v(e), r]; + return [...O(e), r]; } -function Ke(e, r) { +function ge(e, r) { if (!r) return e; const t = new URLSearchParams(); - Object.entries(r).forEach(([d, h]) => { - h != null && h !== "" && t.append(d, h); + Object.entries(r).forEach(([s, h]) => { + h != null && h !== "" && t.append(s, h); }); const n = t.toString(); return n ? `${e}?${n}` : e; } -function Xe(e, r) { +function Ke(e, r) { return typeof e == "function" ? e(r == null ? void 0 : r.id, r) : e; } -function ge(e = {}) { +function fe(e = {}) { const { id: r, ...t } = e; return t; } -function ze(e, r) { +function Xe(e, r) { return `${e.replace(/\/$/, "")}/${r}`; } function xe(e) { return `use${e.charAt(0).toUpperCase()}${e.slice(1)}`; } -function fe(e, r) { +function ze(e, r) { return typeof e == "function" ? e(r) : e; } -function rt({ +function tt({ key: e, url: r, actions: t = {}, - axiosInstance: n = k, - fetcher: d = be + axiosInstance: n = H, + fetcher: s = be }) { - const h = v(e), u = Te(e); - function s(i, c = {}) { + const h = O(e), d = Te(e); + function a(i, c = {}) { return P({ - queryKey: i ? [...u, i] : u, - queryFn: () => d(Ke(r, i)), + queryKey: i ? [...d, i] : d, + queryFn: () => s(ge(r, i)), ...c }); } - function a(i, c = {}) { + function u(i, c = {}) { return P({ queryKey: U(e, i), - queryFn: () => d(ze(r, i)), + queryFn: () => s(Xe(r, i)), enabled: !!i, ...c }); } - function p(i, c = {}) { - const q = re(), S = t[i]; - if (!S) + function S(i, c = {}) { + const q = re(), p = t[i]; + if (!p) throw new Error(`Action "${i}" is not defined.`); return ne({ mutationKey: [...h, i], - mutationFn: async (F = {}) => { - const l = S.method || "post", Z = Xe(S.url || r, F), T = fe(S.requestConfig, F), E = S.body ? S.body(F) : S.sendRawPayload ? F : ge(F); + mutationFn: async (m = {}) => { + const l = p.method || "post", Z = Ke(p.url || r, m), T = ze(p.requestConfig, m), E = p.body ? p.body(m) : p.sendRawPayload ? m : fe(m); let y; if (l === "get") y = await n.get( @@ -195,12 +195,12 @@ function rt({ } : E ); else if (l === "delete") { - const z = E && Object.keys(E).length > 0; + const X = E && Object.keys(E).length > 0; y = await n.delete( Z, - T || z ? { + T || X ? { ...T || {}, - ...z ? { data: E } : {} + ...X ? { data: E } : {} } : void 0 ); } else @@ -211,65 +211,65 @@ function rt({ ); return y.data; }, - onSuccess: (...F) => { + onSuccess: (...m) => { var y; - const [l, Z] = F; + const [l, Z] = m; q.invalidateQueries({ - queryKey: u + queryKey: d }); const T = (Z == null ? void 0 : Z.id) ?? (l == null ? void 0 : l.id); T && q.invalidateQueries({ queryKey: U(e, T) }); - const E = typeof S.invalidateKeys == "function" ? S.invalidateKeys(l, Z) : S.invalidateKeys; - E == null || E.forEach((z) => { - q.invalidateQueries({ queryKey: z }); - }), (y = c.onSuccess) == null || y.call(c, ...F); + const E = typeof p.invalidateKeys == "function" ? p.invalidateKeys(l, Z) : p.invalidateKeys; + E == null || E.forEach((X) => { + q.invalidateQueries({ queryKey: X }); + }), (y = c.onSuccess) == null || y.call(c, ...m); }, ...c }); } - const m = Object.keys(t).reduce((i, c) => (i[xe(c)] = (q = {}) => p(c, q), i), {}); + const F = Object.keys(t).reduce((i, c) => (i[xe(c)] = (q = {}) => S(c, q), i), {}); return { key: h, - listKey: u, - useGet: s, - useItem: a, - useAction: p, - ...m + listKey: d, + useGet: a, + useItem: u, + useAction: S, + ...F }; } -const Q = N(null), w = "permissions", Be = (e) => (e == null ? void 0 : e.storageKey) || w, we = ({ +const k = V(null), w = "permissions", Be = (e) => (e == null ? void 0 : e.storageKey) || w, we = ({ user: e = null, children: r, config: t, loading: n = /* @__PURE__ */ b("div", { children: "Loading permissions..." }), - errorFallback: d = /* @__PURE__ */ b("div", { children: "Error loading permissions" }) + errorFallback: s = /* @__PURE__ */ b("div", { children: "Error loading permissions" }) }) => { - const h = Be(t), [u, s] = X( + const h = Be(t), [d, a] = K( () => Ye(h) - ), { data: a, isLoading: p, error: m } = Ae(t), i = a ?? u; - g(() => { - a && (Pe(h, a), s(a)); - }, [a, h]); - const c = f( - () => We(i), + ), { data: u, isLoading: S, error: F } = Ae(t), i = u ?? d; + f(() => { + u && (Pe(h, u), a(u)); + }, [u, h]); + const c = z( + () => ve(i), [i] - ), q = K( - (l = "") => Oe(c, l), + ), q = g( + (l = "") => We(c, l), [c] - ), S = K((l = "") => !q(l), [q]), F = f( + ), p = g((l = "") => !q(l), [q]), m = z( () => ({ user: e, can: q, - cannot: S, + cannot: p, permissions: i, - isLoading: p, - error: m + isLoading: S, + error: F }), - [e, q, S, i, p, m] + [e, q, p, i, S, F] ); - return m && !i ? d : p && !i ? n : /* @__PURE__ */ b(Q.Provider, { value: F, children: r }); + return F && !i ? s : S && !i ? n : /* @__PURE__ */ b(k.Provider, { value: m, children: r }); }, Ye = (e = w) => { if (!(typeof window > "u")) try { @@ -284,23 +284,23 @@ const Q = N(null), w = "permissions", Be = (e) => (e == null ? void 0 : e.storag localStorage.setItem(e, JSON.stringify(r)); } catch { } -}, nt = (e = w) => { +}, rt = (e = w) => { if (!(typeof window > "u")) try { localStorage.removeItem(e); } catch { } -}, We = (e) => e ? new Set(e.map((r) => r.name)) : /* @__PURE__ */ new Set(), Oe = (e, r = "") => { +}, ve = (e) => e ? new Set(e.map((r) => r.name)) : /* @__PURE__ */ new Set(), We = (e, r = "") => { if (!r) return !1; if (e.has(r) || [...e].some((n) => n.startsWith(r))) return !0; let t = r; for (; t.includes(":"); ) if (t = t.slice(0, t.lastIndexOf(":")), e.has(`${t}:*`)) return !0; return !1; -}, j = { +}, Q = { all: ["permissions"], - list: (e) => [...j.all, e] -}, ve = async (e) => { + list: (e) => [...Q.all, e] +}, Oe = async (e) => { if (!(e != null && e.url) || !(e != null && e.clientId)) throw new Error("Permission config requires url and clientId."); const r = x(), t = new URL(e.url); @@ -315,59 +315,59 @@ const Q = N(null), w = "permissions", Be = (e) => (e == null ? void 0 : e.storag throw new Error("Failed to load permissions"); return n.json(); }, A = () => { - const e = te(Q); + const e = te(k); if (!e) throw new Error("usePermission must be used within PermissionProvider"); return e; }, Ae = (e) => P({ - queryKey: j.list(e == null ? void 0 : e.clientId), - queryFn: () => ve(e), - enabled: !!(e != null && e.url) && !!(e != null && e.clientId) && G(), + queryKey: Q.list(e == null ? void 0 : e.clientId), + queryFn: () => Oe(e), + enabled: !!(e != null && e.url) && !!(e != null && e.clientId) && I(), staleTime: 1 / 0, refetchOnWindowFocus: !1, refetchOnReconnect: !1 -}), ot = ({ +}), nt = ({ perm: e, children: r, fallback: t = /* @__PURE__ */ b("div", { children: "You are not allowed to do this" }) }) => { const { can: n } = A(); return n(e) ? r : t; -}, it = ({ children: e }) => { +}, ot = ({ children: e }) => { const { can: r, permissions: t } = A(); return t && r("admin") ? e : null; -}, st = ({ children: e, forceNoAccess: r = !1 }) => { +}, it = ({ children: e, forceNoAccess: r = !1 }) => { const { can: t, isLoading: n } = A(); - return g(() => { - n || (r || !t("panel_access")) && J(); + return f(() => { + n || (r || !t("panel_access")) && G(); }, [n, t, r]), e; }; -function Me() { - const [e, r] = X(!1), t = R(null); - return g(() => { +function De() { + const [e, r] = K(!1), t = N(null); + return f(() => { if (process.env.NODE_ENV !== "production") return; let n; - const d = async () => { - const u = await fetch(`/version.json?t=${Date.now()}`, { + const s = async () => { + const d = await fetch(`/version.json?t=${Date.now()}`, { cache: "no-store" }); - if (!u.ok) - throw new Error(`Failed to fetch version: ${u.status}`); - const s = await u.json(); - return String(s.version); + if (!d.ok) + throw new Error(`Failed to fetch version: ${d.status}`); + const a = await d.json(); + return String(a.version); }; return (async () => { try { - t.current = await d(), n = setInterval(async () => { + t.current = await s(), n = setInterval(async () => { try { - const u = await d(); - t.current && u !== t.current && (r(!0), clearInterval(n)); - } catch (u) { - console.error("Update check failed:", u); + const d = await s(); + t.current && d !== t.current && (r(!0), clearInterval(n)); + } catch (d) { + console.error("Update check failed:", d); } }, 3e4); - } catch (u) { - console.error("Initial version fetch failed:", u); + } catch (d) { + console.error("Initial version fetch failed:", d); } })(), () => { n && clearInterval(n); @@ -391,7 +391,7 @@ function Me() { } ) : null; } -const De = new oe({ +const Me = new oe({ defaultOptions: { queries: { retry: 1, @@ -435,17 +435,33 @@ const De = new oe({ } ` } -), { QueryParamProvider: Ve } = le; -var V; -const Ne = ((V = D) == null ? void 0 : V.default) ?? D, L = "__UIKIT_REMOTE_DEPS__"; -function Re({ theme: e, chakraProviderProps: r } = {}) { +), j = (e, r) => { + let t = e; + for (let n = 0; n < 4 && t; n += 1) { + const s = Reflect.get(t, r); + if (s !== void 0) return s; + t = Reflect.get(t, "default"); + } +}, Ve = (e) => { + let r = e; + for (let t = 0; t < 4 && r; t += 1) { + const n = Reflect.get(r, "default"); + if (n === void 0) break; + r = n; + } + return r; +}, Ne = j( + le, + "QueryParamProvider" +), Re = j(M, "NextAdapterPages") ?? Ve(M), L = "__UIKIT_REMOTE_DEPS__"; +function Ie({ theme: e, chakraProviderProps: r } = {}) { if (typeof window > "u") return; const t = window[L] || {}; window[L] = { ...t, React: t.React || ee, createRoot: t.createRoot || se, - ChakraProvider: t.ChakraProvider || I, + ChakraProvider: t.ChakraProvider || R, Badge: t.Badge || ce, theme: e ?? t.theme, chakraProviderProps: { @@ -454,35 +470,35 @@ function Re({ theme: e, chakraProviderProps: r } = {}) { } }; } -function at({ +function st({ children: e, apiBaseUrl: r, keycloakClientId: t, permissionClientId: n, - loading: d = /* @__PURE__ */ b(de, {}), + loading: s = /* @__PURE__ */ b(de, {}), updateChecker: h = !1, - updateCheckerProps: u, - keycloakUrl: s = "https://auth.ibagher.ir", - keycloakRealm: a = "bi", - permissionUrl: p = "https://api.d.aiengines.ir/user_api/v1/permissions/list", - keycloakEnabled: m, + updateCheckerProps: d, + keycloakUrl: a = "https://auth.ibagher.ir", + keycloakRealm: u = "bi", + permissionUrl: S = "https://api.d.aiengines.ir/user_api/v1/permissions/list", + keycloakEnabled: F, permissionEnabled: i, theme: c = Ue, remoteUiEnabled: q = !0, - remoteUiChakraProviderProps: S + remoteUiChakraProviderProps: p }) { - const [F, l] = X(!1), Z = m ?? !!t, T = i ?? !!n, E = f( + const [m, l] = K(!1), Z = F ?? !!t, T = i ?? !!n, E = z( () => ({ api: { baseUrl: r || "" }, keycloak: Z ? { - url: s, - realm: a, + url: a, + realm: u, clientId: t } : null, permission: T ? { - url: p, + url: S, clientId: n } : null }), @@ -490,56 +506,56 @@ function at({ r, Z, T, - s, a, + u, t, - p, + S, n ] ); - if (g(() => { + if (f(() => { l(!0); - }, []), g(() => { - F && Ze(E); - }, [F, E]), !F) + }, []), f(() => { + m && Ze(E); + }, [m, E]), !m) return null; - q && Re({ + q && Ie({ theme: c, - chakraProviderProps: S + chakraProviderProps: p }); let y = e; - return T && (y = /* @__PURE__ */ b(we, { config: E.permission, loading: d, children: y })), Z && (y = /* @__PURE__ */ b(qe, { config: E.keycloak, loading: d, children: y })), /* @__PURE__ */ M(I, { theme: c, children: [ + return T && (y = /* @__PURE__ */ b(we, { config: E.permission, loading: s, children: y })), Z && (y = /* @__PURE__ */ b(qe, { config: E.keycloak, loading: s, children: y })), /* @__PURE__ */ D(R, { theme: c, children: [ /* @__PURE__ */ b(Le, {}), - /* @__PURE__ */ M(ie, { client: De, children: [ - h && /* @__PURE__ */ b(Me, { ...u }), - /* @__PURE__ */ b(Ve, { adapter: Ne, children: y }) + /* @__PURE__ */ D(ie, { client: Me, children: [ + h && /* @__PURE__ */ b(De, { ...d }), + /* @__PURE__ */ b(Ne, { adapter: Re, children: y }) ] }) ] }); } export { - it as AdminGuard, - at as BiProvider, - ot as Can, + ot as AdminGuard, + st as BiProvider, + nt as Can, qe as KeycloakProvider, - st as PanelAccessGuard, + it as PanelAccessGuard, we as PermissionProvider, - k as api, - Oe as checkPermission, - nt as clearCachedPermissions, + H as api, + We as checkPermission, + rt as clearCachedPermissions, Ze as configureApi, - rt as createApi, - We as createPermissionSet, + tt as createApi, + ve as createPermissionSet, be as fetcher, ye as getApi, Ye as getCachedPermissions, x as getKeycloakToken, - ve as getPermissions, - H as initKeycloak, - G as isKeycloakAuthenticated, - me as isKeycloakInitialized, - tt as loginKeycloak, - J as logoutKeycloak, - j as permissionKeys, + Oe as getPermissions, + J as initKeycloak, + I as isKeycloakAuthenticated, + Fe as isKeycloakInitialized, + et as loginKeycloak, + G as logoutKeycloak, + Q as permissionKeys, Pe as setCachedPermissions, C as updateKeycloakToken, A as usePermission, diff --git a/src/core/BiProvider.jsx b/src/core/BiProvider.jsx index 22073b6..0f2cee6 100644 --- a/src/core/BiProvider.jsx +++ b/src/core/BiProvider.jsx @@ -2,8 +2,8 @@ import React, { useEffect, useMemo, useState } from "react"; import { createRoot } from "react-dom/client"; import { Badge, ChakraProvider, Spinner } from "@chakra-ui/react"; import { QueryClientProvider } from "@tanstack/react-query"; -import nextAdapterPagesModule from "next-query-params/pages"; -import useQueryParamsModule from "use-query-params"; +import * as nextAdapterPagesModule from "next-query-params/pages"; +import * as useQueryParamsModule from "use-query-params"; import { KeycloakProvider } from "./keycloak.jsx"; import { PermissionProvider } from "./permission.jsx"; import { UpdateChecker } from "./UpdateChecker.jsx"; @@ -11,9 +11,39 @@ import { configureApi } from "./api.js"; import { queryClient } from "./query.js"; import { Fonts, theme as defaultTheme } from "./style.jsx"; -const { QueryParamProvider } = useQueryParamsModule; +const getInteropExport = (module, exportName) => { + let current = module; + + for (let index = 0; index < 4 && current; index += 1) { + const value = Reflect.get(current, exportName); + if (value !== undefined) return value; + + current = Reflect.get(current, "default"); + } + + return undefined; +}; + +const getInteropDefault = (module) => { + let current = module; + + for (let index = 0; index < 4 && current; index += 1) { + const next = Reflect.get(current, "default"); + if (next === undefined) break; + + current = next; + } + + return current; +}; + +const QueryParamProvider = getInteropExport( + useQueryParamsModule, + "QueryParamProvider", +); const NextAdapterPages = - nextAdapterPagesModule?.default ?? nextAdapterPagesModule; + getInteropExport(nextAdapterPagesModule, "NextAdapterPages") ?? + getInteropDefault(nextAdapterPagesModule); const REMOTE_DEPS_KEY = "__UIKIT_REMOTE_DEPS__"; function setupBiRemoteUiDeps({ theme, chakraProviderProps } = {}) {