UNPKG

@kilpi/react-client

Version:

Kilpi React Client Components · Kilpi is the authorization framework for full-stack TypeScript applications, designed for flexible, powerful, agnostic, intuitive and developer friendly authorization.

181 lines (170 loc) 5.78 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { ReactClientComponentPlugin: () => ReactClientComponentPlugin }); module.exports = __toCommonJS(index_exports); // src/plugins/ReactClientComponentPlugin.ts var import_client = require("@kilpi/client"); var import_core = require("@kilpi/core"); // src/hooks/useIsAuthorized.ts var import_react3 = require("react"); // src/hooks/useCacheClearSignal.ts var import_react2 = require("react"); // src/hooks/useWrapRef.ts var import_react = require("react"); function useWrapRef(t) { const ref = (0, import_react.useRef)(t); (0, import_react.useEffect)(() => { ref.current = t; }, [t]); return ref; } // src/hooks/useCacheClearSignal.ts function useCacheClearSignal(client, onCacheCleared) { const [signal, setSignal] = (0, import_react2.useState)(0); const onCacheClearedRef = useWrapRef(onCacheCleared); (0, import_react2.useEffect)(() => { return client.onCacheClear(() => { setSignal(signal + 1); onCacheClearedRef.current?.(); }); }, [client, setSignal, onCacheClearedRef]); return signal; } // src/hooks/useIsAuthorized.ts function createUseIsAuthorized(KilpiClient) { return function useIsAuthorized(key, ...inputs) { const [value, setValue] = (0, import_react3.useState)({ status: "idle", isAuthorized: null, error: null }); const cacheSignal = useCacheClearSignal(KilpiClient, () => { setValue({ status: "idle", isAuthorized: null, error: null }); }); (0, import_react3.useEffect)(() => { let isMounted = true; const abortController = new AbortController(); async function fetchIsAuthorized() { if (isMounted) setValue({ status: "loading", error: null, isAuthorized: null }); try { const isAuthorized = await KilpiClient.fetchIsAuthorized({ key, resource: inputs[0], queryOptions: { signal: abortController.signal } }); if (isMounted) setValue({ status: "success", error: null, isAuthorized }); } catch (error) { if (isMounted) setValue({ status: "error", error, isAuthorized: null }); } } fetchIsAuthorized(); return () => { isMounted = false; abortController.abort(); }; }, [setValue, cacheSignal]); return Object.assign(value, { isLoading: value.status === "loading", isError: value.status === "error", isSuccess: value.status === "success", isIdle: value.status === "idle" }); }; } // src/components/ClientAccess.tsx function createClientAccess(KilpiClient) { const useIsAuthorized = createUseIsAuthorized(KilpiClient); function ClientAccess(props) { const query = useIsAuthorized(props.to, ...[props.to, props.on]); switch (query.status) { case "error": return props.Error ?? null; case "loading": case "idle": return props.Loading ?? null; case "success": return props.children; } } return ClientAccess; } // src/hooks/useSubject.ts var import_react4 = require("react"); function createUseSubject(KilpiClient) { return function useSubject() { const [value, setValue] = (0, import_react4.useState)({ status: "idle", subject: null, error: null }); const cacheSignal = useCacheClearSignal(KilpiClient, () => { setValue({ status: "idle", subject: null, error: null }); }); (0, import_react4.useEffect)(() => { let isMounted = true; const abortController = new AbortController(); async function fetchSubject() { if (isMounted) setValue({ status: "loading", subject: null, error: null }); try { const subject = await KilpiClient.fetchSubject({ queryOptions: { signal: abortController.signal } }); if (isMounted) setValue({ status: "success", subject, error: null }); } catch (error) { if (isMounted) setValue({ status: "error", subject: null, error }); } } fetchSubject(); return () => { isMounted = false; abortController.abort(); }; }, [setValue, cacheSignal]); return Object.assign(value, { isLoading: value.status === "loading", isError: value.status === "error", isSuccess: value.status === "success", isIdle: value.status === "idle" }); }; } // src/plugins/ReactClientComponentPlugin.ts function ReactClientComponentPlugin() { return (0, import_client.createKilpiClientPlugin)((Client) => { return { ReactClient: { createComponents() { return { useSubject: createUseSubject(Client), useIsAuthorized: createUseIsAuthorized(Client), ClientAccess: createClientAccess(Client) }; } } }; }); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ReactClientComponentPlugin });