@unifiedsoftware/react-plugin-remote 1.0.1 → 1.0.8
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.cjs +2 -1
- package/dist/index.d.cts +244 -102
- package/dist/index.d.ts +244 -102
- package/dist/index.js +2 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
'use strict';var react=require('react');var w=(i=>(i.INTERNAL="internal",i.MICROFRONTEND="microfrontend",i.IFRAME="iframe",i))(w||{}),O=(e=>e)(O||{});function H(e){return ()=>({manifest:e.manifest,initialize:e.initialize,activate:e.activate,deactivate:e.deactivate,dispose:e.dispose,components:e.components})}function S(e){return e}function U(e){return e}function k(e){return e}function V(e,p){let f=e.id,i=e.apis||{},s={};for(let[t,a]of Object.entries(i)){let g=a.endpoints||a.allowedEndpoints||{};s[t]={};for(let[d,r]of Object.entries(g))s[t][d]=async(c={})=>{let{params:o={},data:l,headers:m}=c,y=r.path,n={},u=/{([^}]+)}/g,h;for(;(h=u.exec(r.path))!==null;){let x=h[1];o[x]&&(n[x]=o[x],y=y.replace(`{${x}}`,o[x]));}let T={...o};for(let x of Object.keys(n))delete T[x];let E=r.method||r.methods&&r.methods[0]||"GET";return p.request({pluginId:f,apiName:t,endpoint:d,method:E,params:Object.keys(T).length>0?T:void 0,data:l,headers:m})};}return s}function q(e,p,f,i,s,t){let[a,g]=react.useState(null),[d,r]=react.useState(false),[c,o]=react.useState(null),l=t?.enabled!==false,m=t?.refetchInterval,y=react.useRef(null),n=react.useCallback(async()=>{if(l){r(true),o(null);try{let u=await e.capabilities.api.request({pluginId:p,apiName:f,endpoint:i,method:"GET",...s});g(u),r(!1),t?.onSuccess&&t.onSuccess(u);}catch(u){let h=u instanceof Error?u:new Error(String(u));o(h),r(false),t?.onError&&t.onError(h);}}},[p,f,i,l,JSON.stringify(s)]);return react.useEffect(()=>{l&&n();},[n,l]),react.useEffect(()=>{if(m&&l)return y.current=setInterval(n,m),()=>{y.current&&clearInterval(y.current);}},[m,n,l]),{data:a,loading:d,error:c,refetch:n,isSuccess:!d&&!c&&a!==null,isError:!d&&c!==null}}function L(e,p,f,i,s="POST",t){let[a,g]=react.useState(null),[d,r]=react.useState(false),[c,o]=react.useState(null),l=react.useCallback(async y=>{r(true),o(null);try{let n=await e.capabilities.api.request({pluginId:p,apiName:f,endpoint:i,method:s,...y});return g(n),r(!1),t?.onSuccess&&t.onSuccess(n,y),n}catch(n){let u=n instanceof Error?n:new Error(String(n));throw o(u),r(false),t?.onError&&t.onError(u,y),u}},[p,f,i,s,t]),m=react.useCallback(()=>{g(null),o(null),r(false);},[]);return {data:a,loading:d,error:c,mutate:l,reset:m,isSuccess:!d&&!c&&a!==null,isError:!d&&c!==null}}function F(e,p,f){let i=f.apis||{},s={};for(let[t,a]of Object.entries(i)){s[t]={};let g=a.endpoints||a.allowedEndpoints||{};for(let[d,r]of Object.entries(g)){let c=r.method||r.methods&&r.methods[0]||"GET",o=`use${d.charAt(0).toUpperCase()}${d.slice(1)}`;c==="GET"?s[t][o]=(l,m)=>q(e,p,t,d,l,m):s[t][o]=l=>L(e,p,t,d,c,l);}}return s}function K(e,p){let f=e.id,i=e.apis||{},s={};for(let[t,a]of Object.entries(i)){if(!a.graphql)continue;let g=a.graphql,d=g.operations||{};s[t]={query:async(r,c)=>{let o=d[r];if(!o)throw new Error(`GraphQL operation '${r}' not found in manifest`);if(o.type!=="query")throw new Error(`Operation '${r}' is not a query`);let l=await p.graphql({pluginId:f,apiName:t,query:o.query,variables:c||o.variables||{},operationName:r,headers:g.headers});if(l.errors&&l.errors.length>0)throw new Error(l.errors[0].message);return l.data},mutate:async(r,c)=>{let o=d[r];if(!o)throw new Error(`GraphQL operation '${r}' not found in manifest`);if(o.type!=="mutation")throw new Error(`Operation '${r}' is not a mutation`);let l=await p.graphql({pluginId:f,apiName:t,query:o.query,variables:c||o.variables||{},operationName:r,headers:g.headers});if(l.errors&&l.errors.length>0)throw new Error(l.errors[0].message);return l.data},subscribe:(r,c,o)=>(console.warn("GraphQL subscriptions not yet implemented"),()=>{})};}return s}function z(e,p,f){return {async query(i,s,t){let a=await f.graphql({pluginId:e,apiName:p,query:i,variables:s||{},operationName:t});if(a.errors&&a.errors.length>0)throw new Error(a.errors[0].message);return a.data},async mutate(i,s,t){let a=await f.graphql({pluginId:e,apiName:p,query:i,variables:s||{},operationName:t});if(a.errors&&a.errors.length>0)throw new Error(a.errors[0].message);return a.data}}}function B(e,p,f={}){let{enabled:i=true,refetchOnMount:s=true,refetchInterval:t,onSuccess:a,onError:g,cacheTime:d=300*1e3}=f,[r,c]=react.useState(void 0),[o,l]=react.useState(i),[m,y]=react.useState(void 0),n=react.useRef(true),u=react.useRef(null),h=react.useCallback(async()=>{if(i){if(u.current&&Date.now()-u.current.timestamp<d){c(u.current.data),l(false);return}l(true),y(void 0);try{let T=await e.graphql(p);if(!n.current)return;if(T.errors&&T.errors.length>0){let E=new Error(T.errors[0].message);y(E),g?.(E);}else T.data&&(c(T.data),u.current={data:T.data,timestamp:Date.now()},a?.(T.data));}catch(T){if(!n.current)return;let E=T instanceof Error?T:new Error(String(T));y(E),g?.(E);}finally{n.current&&l(false);}}},[e,p,i,d,a,g]);return react.useEffect(()=>{s&&h();},[h,s]),react.useEffect(()=>{if(!t||!i)return;let T=setInterval(()=>{h();},t);return ()=>clearInterval(T)},[t,i,h]),react.useEffect(()=>()=>{n.current=false;},[]),{data:r,loading:o,error:m,refetch:h}}function W(e,p,f={}){let{onSuccess:i,onError:s}=f,[t,a]=react.useState(void 0),[g,d]=react.useState(false),[r,c]=react.useState(void 0),o=react.useRef(true);react.useEffect(()=>()=>{o.current=false;},[]);let l=react.useCallback(async y=>{d(true),c(void 0);try{let n=await e.graphql({...p,variables:y});if(!o.current)throw new Error("Component unmounted");if(n.errors&&n.errors.length>0){let u=new Error(n.errors[0].message);throw c(u),s?.(u,y),u}if(n.data)return a(n.data),i?.(n.data,y),n.data;throw new Error("No data returned from mutation")}catch(n){if(!o.current)throw n;let u=n instanceof Error?n:new Error(String(n));throw c(u),s?.(u,y),u}finally{o.current&&d(false);}},[e,p,i,s]),m=react.useCallback(()=>{a(void 0),c(void 0),d(false);},[]);return {mutate:l,data:t,loading:g,error:r,reset:m}}function X(e,p,f={}){return console.warn("GraphQL subscriptions not yet implemented"),{data:void 0,loading:false,error:new Error("Subscriptions not yet implemented"),refetch:async()=>{}}}var v=class{constructor(p,f){this.context=p;this.pluginId=f;}async request(p){let{url:f,method:i,headers:s,body:t,params:a}=p,g=f.split("/").pop()?.split("?")[0]??"";try{return {data:(await this.context.capabilities.api.request({pluginId:this.pluginId,endpoint:g,method:i,data:t,params:a,headers:s})).ObjOptional,status:200,statusText:"OK",headers:{}}}catch(d){throw {message:d.message||"Plugin API Request Failed",status:d.status||500,details:d}}}};function Z(e,p){return new v(e,p)}exports.ExtensionPoint=O;exports.PluginHostAdapter=v;exports.PluginType=w;exports.createGraphQLClient=K;exports.createPluginApi=V;exports.createPluginApiHooks=F;exports.createPluginHostAdapter=Z;exports.createRawGraphQLClient=z;exports.defineApiConfig=k;exports.defineEndpoints=U;exports.defineManifest=S;exports.definePlugin=H;exports.useApiMutation=L;exports.useApiQuery=q;exports.useGraphQLMutation=W;exports.useGraphQLQuery=B;exports.useGraphQLSubscription=X;
|
|
1
|
+
'use strict';var H=require('react'),X=require('@unifiedsoftware/http-client'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var H__default=/*#__PURE__*/_interopDefault(H);var X__namespace=/*#__PURE__*/_interopNamespace(X);var $=Object.defineProperty;var z=(e,t)=>{for(var r in t)$(e,r,{get:t[r],enumerable:true});};var N=(a=>(a.INTERNAL="internal",a.MICROFRONTEND="microfrontend",a.IFRAME="iframe",a))(N||{}),K=(e=>e)(K||{});function Q(e){return ()=>({manifest:e.manifest,initialize:e.initialize,activate:e.activate,deactivate:e.deactivate,dispose:e.dispose,components:e.components})}function re(e){return e}function ae(e){return e}function j(e){return e}function q(e,t){let r=e.id,a=e.apis||{},n={};for(let[i,c]of Object.entries(a)){let h=c.endpoints||c.allowedEndpoints||{};n[i]={};for(let[s,p]of Object.entries(h))n[i][s]=async(f={})=>{let{params:o={},data:u,headers:y}=f,d=p.path,l={},g=/{([^}]+)}/g,m;for(;(m=g.exec(p.path))!==null;){let x=m[1];o[x]&&(l[x]=o[x],d=d.replace(`{${x}}`,o[x]));}let T={...o};for(let x of Object.keys(l))delete T[x];let C=p.method||p.methods&&p.methods[0]||"GET";return t.request({pluginId:r,apiName:i,endpoint:s,method:C,params:Object.keys(T).length>0?T:void 0,data:u,headers:y})};}return n}function J(e,t,r,a,n,i){let[c,h]=H.useState(null),[s,p]=H.useState(false),[f,o]=H.useState(null),u=i?.enabled!==false,y=i?.refetchInterval,d=H.useRef(null),l=H.useCallback(async()=>{if(u){p(true),o(null);try{let g=await e.capabilities.api.request({pluginId:t,apiName:r,endpoint:a,method:"GET",...n});h(g),p(!1),i?.onSuccess&&i.onSuccess(g);}catch(g){let m=g instanceof Error?g:new Error(String(g));o(m),p(false),i?.onError&&i.onError(m);}}},[t,r,a,u,JSON.stringify(n)]);return H.useEffect(()=>{u&&l();},[l,u]),H.useEffect(()=>{if(y&&u)return d.current=setInterval(l,y),()=>{d.current&&clearInterval(d.current);}},[y,l,u]),{data:c,loading:s,error:f,refetch:l,isSuccess:!s&&!f&&c!==null,isError:!s&&f!==null}}function _(e,t,r,a,n="POST",i){let[c,h]=H.useState(null),[s,p]=H.useState(false),[f,o]=H.useState(null),u=H.useCallback(async d=>{p(true),o(null);try{let l=await e.capabilities.api.request({pluginId:t,apiName:r,endpoint:a,method:n,...d});return h(l),p(!1),i?.onSuccess&&i.onSuccess(l,d),l}catch(l){let g=l instanceof Error?l:new Error(String(l));throw o(g),p(false),i?.onError&&i.onError(g,d),g}},[t,r,a,n,i]),y=H.useCallback(()=>{h(null),o(null),p(false);},[]);return {data:c,loading:s,error:f,mutate:u,reset:y,isSuccess:!s&&!f&&c!==null,isError:!s&&f!==null}}function O(e,t,r){let a=r.apis||{},n={};for(let[i,c]of Object.entries(a)){n[i]={};let h=c.endpoints||c.allowedEndpoints||{};for(let[s,p]of Object.entries(h)){let f=p.method||p.methods&&p.methods[0]||"GET",o=`use${s.charAt(0).toUpperCase()}${s.slice(1)}`;f==="GET"?n[i][o]=(u,y)=>J(e,t,i,s,u,y):n[i][o]=u=>_(e,t,i,s,f,u);}}return n}function k(e,t){let r=e.id,a=e.apis||{},n={};for(let[i,c]of Object.entries(a)){if(!c.graphql)continue;let h=c.graphql,s=h.operations||{};n[i]={query:async(p,f)=>{let o=s[p];if(!o)throw new Error(`GraphQL operation '${p}' not found in manifest`);if(o.type!=="query")throw new Error(`Operation '${p}' is not a query`);let u=await t.graphql({pluginId:r,apiName:i,query:o.query,variables:f||o.variables||{},operationName:p,headers:h.headers});if(u.errors&&u.errors.length>0)throw new Error(u.errors[0].message);return u.data},mutate:async(p,f)=>{let o=s[p];if(!o)throw new Error(`GraphQL operation '${p}' not found in manifest`);if(o.type!=="mutation")throw new Error(`Operation '${p}' is not a mutation`);let u=await t.graphql({pluginId:r,apiName:i,query:o.query,variables:f||o.variables||{},operationName:p,headers:h.headers});if(u.errors&&u.errors.length>0)throw new Error(u.errors[0].message);return u.data},subscribe:(p,f,o)=>(console.warn("GraphQL subscriptions not yet implemented"),()=>{})};}return n}function S(e,t,r){return {async query(a,n,i){let c=await r.graphql({pluginId:e,apiName:t,query:a,variables:n||{},operationName:i});if(c.errors&&c.errors.length>0)throw new Error(c.errors[0].message);return c.data},async mutate(a,n,i){let c=await r.graphql({pluginId:e,apiName:t,query:a,variables:n||{},operationName:i});if(c.errors&&c.errors.length>0)throw new Error(c.errors[0].message);return c.data}}}function de(e,t,r={}){let{enabled:a=true,refetchOnMount:n=true,refetchInterval:i,onSuccess:c,onError:h,cacheTime:s=300*1e3}=r,[p,f]=H.useState(void 0),[o,u]=H.useState(a),[y,d]=H.useState(void 0),l=H.useRef(true),g=H.useRef(null),m=H.useCallback(async()=>{if(a){if(g.current&&Date.now()-g.current.timestamp<s){f(g.current.data),u(false);return}u(true),d(void 0);try{let T=await e.graphql(t);if(!l.current)return;if(T.errors&&T.errors.length>0){let C=new Error(T.errors[0].message);d(C),h?.(C);}else T.data&&(f(T.data),g.current={data:T.data,timestamp:Date.now()},c?.(T.data));}catch(T){if(!l.current)return;let C=T instanceof Error?T:new Error(String(T));d(C),h?.(C);}finally{l.current&&u(false);}}},[e,t,a,s,c,h]);return H.useEffect(()=>{n&&m();},[m,n]),H.useEffect(()=>{if(!i||!a)return;let T=setInterval(()=>{m();},i);return ()=>clearInterval(T)},[i,a,m]),H.useEffect(()=>()=>{l.current=false;},[]),{data:p,loading:o,error:y,refetch:m}}function ue(e,t,r={}){let{onSuccess:a,onError:n}=r,[i,c]=H.useState(void 0),[h,s]=H.useState(false),[p,f]=H.useState(void 0),o=H.useRef(true);H.useEffect(()=>()=>{o.current=false;},[]);let u=H.useCallback(async d=>{s(true),f(void 0);try{let l=await e.graphql({...t,variables:d});if(!o.current)throw new Error("Component unmounted");if(l.errors&&l.errors.length>0){let g=new Error(l.errors[0].message);throw f(g),n?.(g,d),g}if(l.data)return c(l.data),a?.(l.data,d),l.data;throw new Error("No data returned from mutation")}catch(l){if(!o.current)throw l;let g=l instanceof Error?l:new Error(String(l));throw f(g),n?.(g,d),g}finally{o.current&&s(false);}},[e,t,a,n]),y=H.useCallback(()=>{c(void 0),f(void 0),s(false);},[]);return {mutate:u,data:i,loading:h,error:p,reset:y}}function fe(e,t,r={}){return console.warn("GraphQL subscriptions not yet implemented"),{data:void 0,loading:false,error:new Error("Subscriptions not yet implemented"),refetch:async()=>{}}}var M=class{constructor(t,r){this.context=t;this.pluginId=r;}async request(t){let{url:r,method:a,headers:n,body:i,params:c}=t,h=r.split("/").pop()?.split("?")[0]??"";try{let s=await this.context.capabilities.api.request({pluginId:this.pluginId,endpoint:h,method:a,data:i,params:c,headers:n});return {data:s&&typeof s=="object"&&"ObjOptional"in s?s.ObjOptional:s,status:200,statusText:"OK",headers:{}}}catch(s){throw {message:s.message||"Plugin API Request Failed",status:s.status||500,details:s}}}};function U(e,t){return new M(e,t)}var L={};z(L,{GraphQLCache:()=>I,GraphQLClient:()=>F,GraphQLError:()=>v,createGraphQLClient:()=>W});var I=class{cache=new Map;defaultTTL;constructor(e=3e5){this.defaultTTL=e;}generateKey(e,t){let r=t?JSON.stringify(t):"";return `${e}:${r}`}isValid(e){return Date.now()-e.timestamp<e.ttl}get(e,t){let r=this.generateKey(e,t),a=this.cache.get(r);return a?this.isValid(a)?a.data:(this.cache.delete(r),null):null}set(e,t,r,a){let n=this.generateKey(e,r);this.cache.set(n,{data:t,timestamp:Date.now(),ttl:a||this.defaultTTL});}clear(e,t){let r=this.generateKey(e,t);this.cache.delete(r);}clearAll(){this.cache.clear();}get size(){return this.cache.size}},v=class extends Error{constructor(e,t,r){super(e),this.errors=t,this.response=r,this.name="GraphQLError";}get firstError(){var e;return ((e=this.errors[0])==null?void 0:e.message)||this.message}get messages(){return this.errors.map(e=>e.message)}},F=class{httpClient;endpoint;defaultHeaders;cache;constructor(e,t){this.httpClient=e,this.endpoint=t.endpoint,this.defaultHeaders={"Content-Type":"application/json",...t.headers},t.cache&&(this.cache=new I(t.cacheTTL));}async query(e,t,r){if(this.cache){let i=this.cache.get(e,t);if(i!==null)return i}let a={query:e,variables:t,operationName:r},n=await this.httpClient.post(this.endpoint,a,{headers:this.defaultHeaders});if(n.errors&&n.errors.length>0)throw new v(n.errors[0].message,n.errors,n);if(!n.data)throw new v("No data returned from GraphQL query",[],n);return this.cache&&this.cache.set(e,n.data,t),n.data}async mutate(e,t,r){let a={query:e,variables:t,operationName:r},n=await this.httpClient.post(this.endpoint,a,{headers:this.defaultHeaders});if(n.errors&&n.errors.length>0)throw new v(n.errors[0].message,n.errors,n);if(!n.data)throw new v("No data returned from GraphQL mutation",[],n);return n.data}async request(e){return await this.httpClient.post(this.endpoint,e,{headers:this.defaultHeaders})}clearCache(e,t){this.cache&&(e?this.cache.clear(e,t):this.cache.clearAll());}getHttpClient(){return this.httpClient}};function W(e,t){return new F(e,t)}var{HttpClient:B}=X__namespace,{createGraphQLClient:xe}=L;function De(e){let t,r,a,n,i={};return {PluginProvider:({children:y})=>{if(!(Object.keys(i).length>0))return null;let l=e.providers.reduceRight((g,m)=>{let{provider:T}=m,C;return "clientKey"in m&&m.clientKey?C=i[m.clientKey]:"value"in m&&(typeof m.value=="function"?C=m.value(i):C=m.value),H__default.default.createElement(T,{value:C},g)},y);return H__default.default.createElement(H__default.default.Fragment,null,l)},initialize:y=>{t=y;let d=y.manifest||e.manifest;console.log(`[${d.id}] Context Injected`),r=q(d,y.capabilities.api),a=O(y,d.id,d),n=k(d,y.capabilities.api);let m={httpClient:new B({adapter:U(y,d.id)}),useGraphQL:C=>S(d.id,C,y.capabilities.api),manifest:d,hostContext:y},T=e.configureServices(m);Object.assign(i,T);},useHostContext:()=>{if(!t)throw new Error("HostContext not initialized");return t},useApi:()=>{if(!r)throw new Error("ApiClient not initialized");return r},usePluginHooks:()=>{if(!a)throw new Error("ApiHooks not initialized");return a},useGraphQL:()=>{if(!n)throw new Error("GraphQLClient not initialized");return n},getClient:y=>{let d=i[y];if(!d)throw new Error(`Client ${String(y)} not initialized`);return d}}}function Me(e){let{integrations:t,extensions:r=[],extraCapabilities:a=[],remote:n,...i}=e,c={},h={},s=new Set(["notification","storage","events",...a]);return t&&(s.add("api_proxy"),Object.entries(t).forEach(([f,o])=>{c[f]={baseUrl:o.baseUrl,graphqlUrl:o.graphql?.url},h[f]={strategy:"proxy",baseUrl:o.baseUrl,auth:"inherit",...o.graphql&&{graphql:{url:o.graphql.url,auth:"inherit",operations:o.graphql.operations,headers:{"Content-Type":"application/json"},cache:{ttl:3e5,enabled:true}}}};})),{manifest:{version:"1.0.0",author:"Unified Software",icon:"extension",...i,remote:e.type==="microfrontend"?{url:n?.url||"https://localhost:4173/assets/remoteEntry.js",scope:n?.scope||"portalWeb",module:n?.module||`./${e.id}`}:void 0,capabilities:Array.from(s),extensionPoints:r,apis:h},endpoints:c}}function Le(e){return Q({manifest:e.manifest,components:e.components,async initialize(t){if(console.log(`[${e.manifest.id}] Initializing (Framework)...`),e.onContextInit&&e.onContextInit(t),e.settings?.defaults)try{let r=`${e.manifest.id}-settings`;await t.capabilities.storage.get(r)||await t.capabilities.storage.set(r,e.settings.defaults);}catch(r){console.error(`[${e.manifest.id}] Failed to init settings:`,r);}e.events&&Object.entries(e.events).forEach(([r,a])=>{t.capabilities.events.on(r,n=>a(t,n));}),e.onInitialize&&await e.onInitialize(t);},async activate(t){console.log(`[${e.manifest.id}] Activating (Framework)...`),t.capabilities.events.emit("plugin:activated",{pluginId:e.manifest.id}),e.onActivate&&await e.onActivate(t);},async deactivate(){e.onDeactivate&&await e.onDeactivate();},async dispose(){e.onDispose&&await e.onDispose();}})}var ee=()=>jsxRuntime.jsx("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",padding:"1rem",width:"100%",color:"#6c757d"},children:"Loading..."});function Ge(e,t=ee){let r=H__default.default.lazy(e);return a=>jsxRuntime.jsx(H.Suspense,{fallback:jsxRuntime.jsx(t,{}),children:jsxRuntime.jsx(r,{...a})})}
|
|
2
|
+
exports.ExtensionPoint=K;exports.LoadingFallback=ee;exports.PluginHostAdapter=M;exports.PluginType=N;exports.createGraphQLClient=k;exports.createLazyComponent=Ge;exports.createManifest=Me;exports.createPlugin=Le;exports.createPluginApi=q;exports.createPluginApiHooks=O;exports.createPluginHostAdapter=U;exports.createRawGraphQLClient=S;exports.createRuntime=De;exports.defineApiConfig=j;exports.defineEndpoints=ae;exports.defineManifest=re;exports.definePlugin=Q;exports.useApiMutation=_;exports.useApiQuery=J;exports.useGraphQLMutation=ue;exports.useGraphQLQuery=de;exports.useGraphQLSubscription=fe;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,13 +1,103 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { HttpAdapter, HttpRequest, HttpResponse } from '@unifiedsoftware/http-client';
|
|
1
|
+
import React, { ComponentType } from 'react';
|
|
2
|
+
import { HttpAdapter, HttpRequest, HttpResponse, HttpClient as HttpClient$1 } from '@unifiedsoftware/http-client';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
* Plugin
|
|
6
|
+
* Plugin Manifest Types
|
|
6
7
|
*
|
|
7
|
-
* Generic
|
|
8
|
-
* These types are project-agnostic and can be reused in any project.
|
|
8
|
+
* Generic manifest structure for plugins
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
declare enum PluginType {
|
|
12
|
+
INTERNAL = "internal",
|
|
13
|
+
MICROFRONTEND = "microfrontend",
|
|
14
|
+
IFRAME = "iframe"
|
|
15
|
+
}
|
|
16
|
+
declare enum ExtensionPoint {
|
|
17
|
+
}
|
|
18
|
+
interface PluginManifest {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly version: string;
|
|
22
|
+
readonly description?: string;
|
|
23
|
+
readonly author?: string;
|
|
24
|
+
readonly homepage?: string;
|
|
25
|
+
readonly icon?: string;
|
|
26
|
+
readonly type: PluginType | 'internal' | 'microfrontend' | 'iframe';
|
|
27
|
+
readonly remote?: {
|
|
28
|
+
readonly url: string;
|
|
29
|
+
readonly scope: string;
|
|
30
|
+
readonly module: string;
|
|
31
|
+
};
|
|
32
|
+
readonly capabilities: readonly string[];
|
|
33
|
+
readonly extensionPoints: readonly string[];
|
|
34
|
+
readonly dependencies?: {
|
|
35
|
+
readonly host?: string;
|
|
36
|
+
readonly plugins?: Record<string, string>;
|
|
37
|
+
};
|
|
38
|
+
readonly config?: Record<string, any>;
|
|
39
|
+
readonly api?: PluginApiConfig;
|
|
40
|
+
readonly apis?: Record<string, PluginApiConfig>;
|
|
41
|
+
}
|
|
42
|
+
interface PluginApiConfig {
|
|
43
|
+
readonly strategy?: 'proxy' | 'direct' | 'bff';
|
|
44
|
+
readonly baseUrl?: string;
|
|
45
|
+
readonly auth?: 'inherit' | 'custom' | 'none';
|
|
46
|
+
readonly allowedEndpoints?: Record<string, EndpointConfig>;
|
|
47
|
+
readonly endpoints?: Record<string, EndpointConfig>;
|
|
48
|
+
readonly corsOrigins?: readonly string[];
|
|
49
|
+
readonly bffUrl?: string;
|
|
50
|
+
readonly graphql?: GraphQLApiConfig;
|
|
51
|
+
}
|
|
52
|
+
interface EndpointConfig {
|
|
53
|
+
readonly path: string;
|
|
54
|
+
readonly method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
55
|
+
readonly methods?: readonly ('GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH')[];
|
|
56
|
+
readonly rateLimit?: number;
|
|
57
|
+
readonly cache?: {
|
|
58
|
+
readonly ttl: number;
|
|
59
|
+
readonly key?: string;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
interface GraphQLApiConfig {
|
|
63
|
+
readonly url: string;
|
|
64
|
+
readonly auth?: 'inherit' | 'custom' | 'none';
|
|
65
|
+
readonly schema?: string;
|
|
66
|
+
readonly operations?: Record<string, GraphQLOperation>;
|
|
67
|
+
readonly subscriptions?: {
|
|
68
|
+
readonly url?: string;
|
|
69
|
+
readonly protocol?: 'ws' | 'graphql-ws';
|
|
70
|
+
};
|
|
71
|
+
readonly headers?: Record<string, string>;
|
|
72
|
+
readonly rateLimit?: number;
|
|
73
|
+
readonly cache?: {
|
|
74
|
+
readonly ttl: number;
|
|
75
|
+
readonly enabled: boolean;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
interface GraphQLOperation {
|
|
79
|
+
readonly query: string;
|
|
80
|
+
readonly type: 'query' | 'mutation' | 'subscription';
|
|
81
|
+
readonly variables?: Record<string, any>;
|
|
82
|
+
readonly cache?: boolean;
|
|
83
|
+
}
|
|
84
|
+
interface Plugin<TContext = any> {
|
|
85
|
+
readonly manifest: PluginManifest;
|
|
86
|
+
initialize?(context: HostContext<TContext>): Promise<void>;
|
|
87
|
+
activate?(context: HostContext<TContext>): Promise<void>;
|
|
88
|
+
deactivate?(): Promise<void>;
|
|
89
|
+
dispose?(): Promise<void>;
|
|
90
|
+
components?: Partial<Record<string, React.ComponentType<any>>>;
|
|
91
|
+
}
|
|
92
|
+
interface PluginDefinition<TContext = any> {
|
|
93
|
+
readonly manifest: PluginManifest;
|
|
94
|
+
initialize?(context: HostContext<TContext>): Promise<void>;
|
|
95
|
+
activate?(context: HostContext<TContext>): Promise<void>;
|
|
96
|
+
deactivate?(): Promise<void>;
|
|
97
|
+
dispose?(): Promise<void>;
|
|
98
|
+
components?: Partial<Record<string, React.ComponentType<any>>>;
|
|
99
|
+
}
|
|
100
|
+
|
|
11
101
|
/**
|
|
12
102
|
* Host Context - Generic interface
|
|
13
103
|
* @template TContext - Project-specific context (e.g., MailingContext, etc.)
|
|
@@ -17,6 +107,7 @@ interface HostContext<TContext = any> {
|
|
|
17
107
|
readonly environment: 'development' | 'production';
|
|
18
108
|
readonly capabilities: HostCapabilities;
|
|
19
109
|
readonly context: TContext;
|
|
110
|
+
readonly manifest?: PluginManifest;
|
|
20
111
|
}
|
|
21
112
|
interface HostCapabilities {
|
|
22
113
|
readonly navigation: NavigationAPI;
|
|
@@ -131,102 +222,6 @@ interface EventAPI {
|
|
|
131
222
|
}
|
|
132
223
|
type EventHandler = (data?: any) => void;
|
|
133
224
|
|
|
134
|
-
/**
|
|
135
|
-
* Plugin Manifest Types
|
|
136
|
-
*
|
|
137
|
-
* Generic manifest structure for plugins
|
|
138
|
-
*/
|
|
139
|
-
|
|
140
|
-
declare enum PluginType {
|
|
141
|
-
INTERNAL = "internal",
|
|
142
|
-
MICROFRONTEND = "microfrontend",
|
|
143
|
-
IFRAME = "iframe"
|
|
144
|
-
}
|
|
145
|
-
declare enum ExtensionPoint {
|
|
146
|
-
}
|
|
147
|
-
interface PluginManifest {
|
|
148
|
-
readonly id: string;
|
|
149
|
-
readonly name: string;
|
|
150
|
-
readonly version: string;
|
|
151
|
-
readonly description?: string;
|
|
152
|
-
readonly author?: string;
|
|
153
|
-
readonly homepage?: string;
|
|
154
|
-
readonly icon?: string;
|
|
155
|
-
readonly type: PluginType | 'internal' | 'microfrontend' | 'iframe';
|
|
156
|
-
readonly remote?: {
|
|
157
|
-
readonly url: string;
|
|
158
|
-
readonly scope: string;
|
|
159
|
-
readonly module: string;
|
|
160
|
-
};
|
|
161
|
-
readonly capabilities: readonly string[];
|
|
162
|
-
readonly extensionPoints: readonly string[];
|
|
163
|
-
readonly dependencies?: {
|
|
164
|
-
readonly host?: string;
|
|
165
|
-
readonly plugins?: Record<string, string>;
|
|
166
|
-
};
|
|
167
|
-
readonly config?: Record<string, any>;
|
|
168
|
-
readonly api?: PluginApiConfig;
|
|
169
|
-
readonly apis?: Record<string, PluginApiConfig>;
|
|
170
|
-
}
|
|
171
|
-
interface PluginApiConfig {
|
|
172
|
-
readonly strategy?: 'proxy' | 'direct' | 'bff';
|
|
173
|
-
readonly baseUrl?: string;
|
|
174
|
-
readonly auth?: 'inherit' | 'custom' | 'none';
|
|
175
|
-
readonly allowedEndpoints?: Record<string, EndpointConfig>;
|
|
176
|
-
readonly endpoints?: Record<string, EndpointConfig>;
|
|
177
|
-
readonly corsOrigins?: readonly string[];
|
|
178
|
-
readonly bffUrl?: string;
|
|
179
|
-
readonly graphql?: GraphQLApiConfig;
|
|
180
|
-
}
|
|
181
|
-
interface EndpointConfig {
|
|
182
|
-
readonly path: string;
|
|
183
|
-
readonly method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
184
|
-
readonly methods?: readonly ('GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH')[];
|
|
185
|
-
readonly rateLimit?: number;
|
|
186
|
-
readonly cache?: {
|
|
187
|
-
readonly ttl: number;
|
|
188
|
-
readonly key?: string;
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
interface GraphQLApiConfig {
|
|
192
|
-
readonly url: string;
|
|
193
|
-
readonly auth?: 'inherit' | 'custom' | 'none';
|
|
194
|
-
readonly schema?: string;
|
|
195
|
-
readonly operations?: Record<string, GraphQLOperation>;
|
|
196
|
-
readonly subscriptions?: {
|
|
197
|
-
readonly url?: string;
|
|
198
|
-
readonly protocol?: 'ws' | 'graphql-ws';
|
|
199
|
-
};
|
|
200
|
-
readonly headers?: Record<string, string>;
|
|
201
|
-
readonly rateLimit?: number;
|
|
202
|
-
readonly cache?: {
|
|
203
|
-
readonly ttl: number;
|
|
204
|
-
readonly enabled: boolean;
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
interface GraphQLOperation {
|
|
208
|
-
readonly query: string;
|
|
209
|
-
readonly type: 'query' | 'mutation' | 'subscription';
|
|
210
|
-
readonly variables?: Record<string, any>;
|
|
211
|
-
readonly cache?: boolean;
|
|
212
|
-
}
|
|
213
|
-
interface Plugin<TContext = any> {
|
|
214
|
-
readonly manifest: PluginManifest;
|
|
215
|
-
initialize?(context: HostContext<TContext>): Promise<void>;
|
|
216
|
-
activate?(context: HostContext<TContext>): Promise<void>;
|
|
217
|
-
deactivate?(): Promise<void>;
|
|
218
|
-
dispose?(): Promise<void>;
|
|
219
|
-
components?: Partial<Record<string, React.ComponentType<any>>>;
|
|
220
|
-
}
|
|
221
|
-
interface PluginDefinition<TContext = any> {
|
|
222
|
-
readonly manifest: PluginManifest;
|
|
223
|
-
initialize?(context: HostContext<TContext>): Promise<void>;
|
|
224
|
-
activate?(context: HostContext<TContext>): Promise<void>;
|
|
225
|
-
deactivate?(): Promise<void>;
|
|
226
|
-
dispose?(): Promise<void>;
|
|
227
|
-
components?: Partial<Record<string, React.ComponentType<any>>>;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
225
|
/**
|
|
231
226
|
* Plugin SDK Helpers
|
|
232
227
|
*
|
|
@@ -584,4 +579,151 @@ declare class PluginHostAdapter implements HttpAdapter {
|
|
|
584
579
|
*/
|
|
585
580
|
declare function createPluginHostAdapter(context: HostContext, pluginId: string): PluginHostAdapter;
|
|
586
581
|
|
|
587
|
-
|
|
582
|
+
declare const HttpClient: typeof HttpClient$1;
|
|
583
|
+
type HttpClient = HttpClient$1;
|
|
584
|
+
|
|
585
|
+
interface ServiceConfigurationContext<TManifest extends PluginManifest = PluginManifest> {
|
|
586
|
+
httpClient: HttpClient;
|
|
587
|
+
useGraphQL: <TData = any>(apiName: string) => {
|
|
588
|
+
query: any;
|
|
589
|
+
mutate: any;
|
|
590
|
+
};
|
|
591
|
+
manifest: TManifest;
|
|
592
|
+
hostContext: HostContext;
|
|
593
|
+
}
|
|
594
|
+
type PluginContextOptions<TManifest extends PluginManifest, TClients extends Record<string, any>> = {
|
|
595
|
+
manifest: TManifest;
|
|
596
|
+
/**
|
|
597
|
+
* Factory function to create/configure services and clients.
|
|
598
|
+
* Receives a context object with initialized base clients and manifest.
|
|
599
|
+
*/
|
|
600
|
+
configureServices: (context: ServiceConfigurationContext<TManifest>) => TClients;
|
|
601
|
+
/**
|
|
602
|
+
* List of Context Providers to wrap the application in.
|
|
603
|
+
* Framework handles rendering them in order.
|
|
604
|
+
*/
|
|
605
|
+
providers: Array<{
|
|
606
|
+
provider: React.Provider<any> | React.ComponentType<any>;
|
|
607
|
+
/**
|
|
608
|
+
* Key of the client to inject directly as the provider value.
|
|
609
|
+
*/
|
|
610
|
+
clientKey?: Extract<keyof TClients, string>;
|
|
611
|
+
/**
|
|
612
|
+
* Explicit value or Factory function to create the value.
|
|
613
|
+
* If a function is provided, it receives the map of all initialized clients.
|
|
614
|
+
*/
|
|
615
|
+
value?: any | ((clients: TClients) => any);
|
|
616
|
+
}>;
|
|
617
|
+
};
|
|
618
|
+
/**
|
|
619
|
+
* Creates the entire Context handling machinery for a plugin.
|
|
620
|
+
* Returns the Provider, Context setters/getters, and Hooks.
|
|
621
|
+
*/
|
|
622
|
+
declare function createRuntime<TManifest extends PluginManifest, TClients extends Record<string, any>>(options: PluginContextOptions<TManifest, TClients>): {
|
|
623
|
+
PluginProvider: React.FC<{
|
|
624
|
+
children: React.ReactNode;
|
|
625
|
+
}>;
|
|
626
|
+
initialize: (context: HostContext) => void;
|
|
627
|
+
useHostContext: () => HostContext<any>;
|
|
628
|
+
useApi: () => PluginApiClient<TManifest>;
|
|
629
|
+
usePluginHooks: () => PluginApiHooks<TManifest>;
|
|
630
|
+
useGraphQL: () => PluginGraphQLClient<TManifest>;
|
|
631
|
+
getClient: <K extends keyof TClients>(key: K) => TClients[K];
|
|
632
|
+
};
|
|
633
|
+
/**
|
|
634
|
+
* Manifest Config for Framework
|
|
635
|
+
*/
|
|
636
|
+
interface FrameworkManifestConfig {
|
|
637
|
+
id: string;
|
|
638
|
+
name: string;
|
|
639
|
+
description?: string;
|
|
640
|
+
version?: string;
|
|
641
|
+
author?: string;
|
|
642
|
+
icon?: string;
|
|
643
|
+
type: 'internal' | 'microfrontend';
|
|
644
|
+
remote?: {
|
|
645
|
+
url?: string;
|
|
646
|
+
scope?: string;
|
|
647
|
+
module?: string;
|
|
648
|
+
};
|
|
649
|
+
/**
|
|
650
|
+
* Define custom integrations/APIs.
|
|
651
|
+
* Key: API Name (e.g., 'payoffDemandApi', 'portalApi')
|
|
652
|
+
* Value: Configuration object
|
|
653
|
+
*/
|
|
654
|
+
integrations?: Record<string, {
|
|
655
|
+
baseUrl: string;
|
|
656
|
+
graphql?: {
|
|
657
|
+
url: string;
|
|
658
|
+
operations: any;
|
|
659
|
+
};
|
|
660
|
+
}>;
|
|
661
|
+
extensions?: string[];
|
|
662
|
+
extraCapabilities?: string[];
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Helper to create a manifest that also exposes its configuration/endpoints
|
|
666
|
+
* allowing for safe destructuring and reuse.
|
|
667
|
+
*/
|
|
668
|
+
declare function createManifest(config: FrameworkManifestConfig): {
|
|
669
|
+
manifest: {
|
|
670
|
+
readonly remote: {
|
|
671
|
+
url: string;
|
|
672
|
+
scope: string;
|
|
673
|
+
module: string;
|
|
674
|
+
} | undefined;
|
|
675
|
+
readonly capabilities: string[];
|
|
676
|
+
readonly extensionPoints: string[];
|
|
677
|
+
readonly apis: any;
|
|
678
|
+
readonly id: string;
|
|
679
|
+
readonly name: string;
|
|
680
|
+
readonly description?: string;
|
|
681
|
+
readonly version: string;
|
|
682
|
+
readonly author: string;
|
|
683
|
+
readonly icon: string;
|
|
684
|
+
readonly type: "internal" | "microfrontend";
|
|
685
|
+
};
|
|
686
|
+
endpoints: Record<string, {
|
|
687
|
+
baseUrl: string;
|
|
688
|
+
graphqlUrl?: string;
|
|
689
|
+
}>;
|
|
690
|
+
};
|
|
691
|
+
interface FrameworkPluginDefinition<TContext extends HostContext = HostContext> {
|
|
692
|
+
manifest: any;
|
|
693
|
+
settings?: {
|
|
694
|
+
defaults?: Record<string, any>;
|
|
695
|
+
};
|
|
696
|
+
events?: {
|
|
697
|
+
[eventName: string]: (context: TContext, payload: any) => void;
|
|
698
|
+
};
|
|
699
|
+
components?: PluginDefinition<TContext>['components'];
|
|
700
|
+
onInitialize?: (context: TContext) => Promise<void> | void;
|
|
701
|
+
onActivate?: (context: TContext) => Promise<void> | void;
|
|
702
|
+
onDeactivate?: () => Promise<void> | void;
|
|
703
|
+
onDispose?: () => Promise<void> | void;
|
|
704
|
+
/**
|
|
705
|
+
* Callback to initialize the context (e.g. saving it to a global variable or provider)
|
|
706
|
+
*/
|
|
707
|
+
onContextInit?: (context: TContext) => void;
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Creates a plugin with a declarative framework.
|
|
711
|
+
* Wraps the standard definePlugin to providing auto-wiring of context, settings, and events.
|
|
712
|
+
*/
|
|
713
|
+
declare function createPlugin<TContext extends HostContext = HostContext>(definition: FrameworkPluginDefinition<TContext>): () => Plugin<any>;
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Standard Loading Fallback for Plugins
|
|
717
|
+
* Kept simple and dependency-free to ensure portability.
|
|
718
|
+
*/
|
|
719
|
+
declare const LoadingFallback: () => react_jsx_runtime.JSX.Element;
|
|
720
|
+
/**
|
|
721
|
+
* Creates a Lazy Loaded component wrapped in Suspense with a standard loader.
|
|
722
|
+
* @param importer The dynamic import function (e.g., () => import('./MyComponent'))
|
|
723
|
+
* @param Fallback Optional custom fallback component. Defaults to standard LoadingFallback.
|
|
724
|
+
*/
|
|
725
|
+
declare function createLazyComponent<T>(importer: () => Promise<{
|
|
726
|
+
default: ComponentType<T> | any;
|
|
727
|
+
}>, Fallback?: ComponentType): (props: T & JSX.IntrinsicAttributes) => react_jsx_runtime.JSX.Element;
|
|
728
|
+
|
|
729
|
+
export { type AlertOptions, type ApiAPI, type ApiRequestConfig, type ConfirmOptions, type EndpointConfig, type EventAPI, type EventHandler, ExtensionPoint, type FrameworkManifestConfig, type FrameworkPluginDefinition, type GraphQLApiConfig, type GraphQLError, type GraphQLOperation, type GraphQLRequestConfig, type GraphQLResponse, type HostCapabilities, type HostContext, LoadingFallback, type ModalAPI, type ModalAction, type ModalConfig, type NavigateOptions, type NavigationAPI, type NotificationAPI, type NotificationOptions, type Plugin, type PluginApiClient, type PluginApiConfig, type PluginApiHooks, type PluginDefinition, type PluginGraphQLClient, PluginHostAdapter, type PluginManifest, PluginType, type ServiceConfigurationContext, type StorageAPI, type UseApiMutationResult, type UseApiQueryOptions, type UseApiQueryResult, type UseMutationOptions, type UseMutationResult, type UseQueryOptions, type UseQueryResult, createGraphQLClient, createLazyComponent, createManifest, createPlugin, createPluginApi, createPluginApiHooks, createPluginHostAdapter, createRawGraphQLClient, createRuntime, defineApiConfig, defineEndpoints, defineManifest, definePlugin, useApiMutation, useApiQuery, useGraphQLMutation, useGraphQLQuery, useGraphQLSubscription };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,103 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { HttpAdapter, HttpRequest, HttpResponse } from '@unifiedsoftware/http-client';
|
|
1
|
+
import React, { ComponentType } from 'react';
|
|
2
|
+
import { HttpAdapter, HttpRequest, HttpResponse, HttpClient as HttpClient$1 } from '@unifiedsoftware/http-client';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
* Plugin
|
|
6
|
+
* Plugin Manifest Types
|
|
6
7
|
*
|
|
7
|
-
* Generic
|
|
8
|
-
* These types are project-agnostic and can be reused in any project.
|
|
8
|
+
* Generic manifest structure for plugins
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
declare enum PluginType {
|
|
12
|
+
INTERNAL = "internal",
|
|
13
|
+
MICROFRONTEND = "microfrontend",
|
|
14
|
+
IFRAME = "iframe"
|
|
15
|
+
}
|
|
16
|
+
declare enum ExtensionPoint {
|
|
17
|
+
}
|
|
18
|
+
interface PluginManifest {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly version: string;
|
|
22
|
+
readonly description?: string;
|
|
23
|
+
readonly author?: string;
|
|
24
|
+
readonly homepage?: string;
|
|
25
|
+
readonly icon?: string;
|
|
26
|
+
readonly type: PluginType | 'internal' | 'microfrontend' | 'iframe';
|
|
27
|
+
readonly remote?: {
|
|
28
|
+
readonly url: string;
|
|
29
|
+
readonly scope: string;
|
|
30
|
+
readonly module: string;
|
|
31
|
+
};
|
|
32
|
+
readonly capabilities: readonly string[];
|
|
33
|
+
readonly extensionPoints: readonly string[];
|
|
34
|
+
readonly dependencies?: {
|
|
35
|
+
readonly host?: string;
|
|
36
|
+
readonly plugins?: Record<string, string>;
|
|
37
|
+
};
|
|
38
|
+
readonly config?: Record<string, any>;
|
|
39
|
+
readonly api?: PluginApiConfig;
|
|
40
|
+
readonly apis?: Record<string, PluginApiConfig>;
|
|
41
|
+
}
|
|
42
|
+
interface PluginApiConfig {
|
|
43
|
+
readonly strategy?: 'proxy' | 'direct' | 'bff';
|
|
44
|
+
readonly baseUrl?: string;
|
|
45
|
+
readonly auth?: 'inherit' | 'custom' | 'none';
|
|
46
|
+
readonly allowedEndpoints?: Record<string, EndpointConfig>;
|
|
47
|
+
readonly endpoints?: Record<string, EndpointConfig>;
|
|
48
|
+
readonly corsOrigins?: readonly string[];
|
|
49
|
+
readonly bffUrl?: string;
|
|
50
|
+
readonly graphql?: GraphQLApiConfig;
|
|
51
|
+
}
|
|
52
|
+
interface EndpointConfig {
|
|
53
|
+
readonly path: string;
|
|
54
|
+
readonly method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
55
|
+
readonly methods?: readonly ('GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH')[];
|
|
56
|
+
readonly rateLimit?: number;
|
|
57
|
+
readonly cache?: {
|
|
58
|
+
readonly ttl: number;
|
|
59
|
+
readonly key?: string;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
interface GraphQLApiConfig {
|
|
63
|
+
readonly url: string;
|
|
64
|
+
readonly auth?: 'inherit' | 'custom' | 'none';
|
|
65
|
+
readonly schema?: string;
|
|
66
|
+
readonly operations?: Record<string, GraphQLOperation>;
|
|
67
|
+
readonly subscriptions?: {
|
|
68
|
+
readonly url?: string;
|
|
69
|
+
readonly protocol?: 'ws' | 'graphql-ws';
|
|
70
|
+
};
|
|
71
|
+
readonly headers?: Record<string, string>;
|
|
72
|
+
readonly rateLimit?: number;
|
|
73
|
+
readonly cache?: {
|
|
74
|
+
readonly ttl: number;
|
|
75
|
+
readonly enabled: boolean;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
interface GraphQLOperation {
|
|
79
|
+
readonly query: string;
|
|
80
|
+
readonly type: 'query' | 'mutation' | 'subscription';
|
|
81
|
+
readonly variables?: Record<string, any>;
|
|
82
|
+
readonly cache?: boolean;
|
|
83
|
+
}
|
|
84
|
+
interface Plugin<TContext = any> {
|
|
85
|
+
readonly manifest: PluginManifest;
|
|
86
|
+
initialize?(context: HostContext<TContext>): Promise<void>;
|
|
87
|
+
activate?(context: HostContext<TContext>): Promise<void>;
|
|
88
|
+
deactivate?(): Promise<void>;
|
|
89
|
+
dispose?(): Promise<void>;
|
|
90
|
+
components?: Partial<Record<string, React.ComponentType<any>>>;
|
|
91
|
+
}
|
|
92
|
+
interface PluginDefinition<TContext = any> {
|
|
93
|
+
readonly manifest: PluginManifest;
|
|
94
|
+
initialize?(context: HostContext<TContext>): Promise<void>;
|
|
95
|
+
activate?(context: HostContext<TContext>): Promise<void>;
|
|
96
|
+
deactivate?(): Promise<void>;
|
|
97
|
+
dispose?(): Promise<void>;
|
|
98
|
+
components?: Partial<Record<string, React.ComponentType<any>>>;
|
|
99
|
+
}
|
|
100
|
+
|
|
11
101
|
/**
|
|
12
102
|
* Host Context - Generic interface
|
|
13
103
|
* @template TContext - Project-specific context (e.g., MailingContext, etc.)
|
|
@@ -17,6 +107,7 @@ interface HostContext<TContext = any> {
|
|
|
17
107
|
readonly environment: 'development' | 'production';
|
|
18
108
|
readonly capabilities: HostCapabilities;
|
|
19
109
|
readonly context: TContext;
|
|
110
|
+
readonly manifest?: PluginManifest;
|
|
20
111
|
}
|
|
21
112
|
interface HostCapabilities {
|
|
22
113
|
readonly navigation: NavigationAPI;
|
|
@@ -131,102 +222,6 @@ interface EventAPI {
|
|
|
131
222
|
}
|
|
132
223
|
type EventHandler = (data?: any) => void;
|
|
133
224
|
|
|
134
|
-
/**
|
|
135
|
-
* Plugin Manifest Types
|
|
136
|
-
*
|
|
137
|
-
* Generic manifest structure for plugins
|
|
138
|
-
*/
|
|
139
|
-
|
|
140
|
-
declare enum PluginType {
|
|
141
|
-
INTERNAL = "internal",
|
|
142
|
-
MICROFRONTEND = "microfrontend",
|
|
143
|
-
IFRAME = "iframe"
|
|
144
|
-
}
|
|
145
|
-
declare enum ExtensionPoint {
|
|
146
|
-
}
|
|
147
|
-
interface PluginManifest {
|
|
148
|
-
readonly id: string;
|
|
149
|
-
readonly name: string;
|
|
150
|
-
readonly version: string;
|
|
151
|
-
readonly description?: string;
|
|
152
|
-
readonly author?: string;
|
|
153
|
-
readonly homepage?: string;
|
|
154
|
-
readonly icon?: string;
|
|
155
|
-
readonly type: PluginType | 'internal' | 'microfrontend' | 'iframe';
|
|
156
|
-
readonly remote?: {
|
|
157
|
-
readonly url: string;
|
|
158
|
-
readonly scope: string;
|
|
159
|
-
readonly module: string;
|
|
160
|
-
};
|
|
161
|
-
readonly capabilities: readonly string[];
|
|
162
|
-
readonly extensionPoints: readonly string[];
|
|
163
|
-
readonly dependencies?: {
|
|
164
|
-
readonly host?: string;
|
|
165
|
-
readonly plugins?: Record<string, string>;
|
|
166
|
-
};
|
|
167
|
-
readonly config?: Record<string, any>;
|
|
168
|
-
readonly api?: PluginApiConfig;
|
|
169
|
-
readonly apis?: Record<string, PluginApiConfig>;
|
|
170
|
-
}
|
|
171
|
-
interface PluginApiConfig {
|
|
172
|
-
readonly strategy?: 'proxy' | 'direct' | 'bff';
|
|
173
|
-
readonly baseUrl?: string;
|
|
174
|
-
readonly auth?: 'inherit' | 'custom' | 'none';
|
|
175
|
-
readonly allowedEndpoints?: Record<string, EndpointConfig>;
|
|
176
|
-
readonly endpoints?: Record<string, EndpointConfig>;
|
|
177
|
-
readonly corsOrigins?: readonly string[];
|
|
178
|
-
readonly bffUrl?: string;
|
|
179
|
-
readonly graphql?: GraphQLApiConfig;
|
|
180
|
-
}
|
|
181
|
-
interface EndpointConfig {
|
|
182
|
-
readonly path: string;
|
|
183
|
-
readonly method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
184
|
-
readonly methods?: readonly ('GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH')[];
|
|
185
|
-
readonly rateLimit?: number;
|
|
186
|
-
readonly cache?: {
|
|
187
|
-
readonly ttl: number;
|
|
188
|
-
readonly key?: string;
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
interface GraphQLApiConfig {
|
|
192
|
-
readonly url: string;
|
|
193
|
-
readonly auth?: 'inherit' | 'custom' | 'none';
|
|
194
|
-
readonly schema?: string;
|
|
195
|
-
readonly operations?: Record<string, GraphQLOperation>;
|
|
196
|
-
readonly subscriptions?: {
|
|
197
|
-
readonly url?: string;
|
|
198
|
-
readonly protocol?: 'ws' | 'graphql-ws';
|
|
199
|
-
};
|
|
200
|
-
readonly headers?: Record<string, string>;
|
|
201
|
-
readonly rateLimit?: number;
|
|
202
|
-
readonly cache?: {
|
|
203
|
-
readonly ttl: number;
|
|
204
|
-
readonly enabled: boolean;
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
interface GraphQLOperation {
|
|
208
|
-
readonly query: string;
|
|
209
|
-
readonly type: 'query' | 'mutation' | 'subscription';
|
|
210
|
-
readonly variables?: Record<string, any>;
|
|
211
|
-
readonly cache?: boolean;
|
|
212
|
-
}
|
|
213
|
-
interface Plugin<TContext = any> {
|
|
214
|
-
readonly manifest: PluginManifest;
|
|
215
|
-
initialize?(context: HostContext<TContext>): Promise<void>;
|
|
216
|
-
activate?(context: HostContext<TContext>): Promise<void>;
|
|
217
|
-
deactivate?(): Promise<void>;
|
|
218
|
-
dispose?(): Promise<void>;
|
|
219
|
-
components?: Partial<Record<string, React.ComponentType<any>>>;
|
|
220
|
-
}
|
|
221
|
-
interface PluginDefinition<TContext = any> {
|
|
222
|
-
readonly manifest: PluginManifest;
|
|
223
|
-
initialize?(context: HostContext<TContext>): Promise<void>;
|
|
224
|
-
activate?(context: HostContext<TContext>): Promise<void>;
|
|
225
|
-
deactivate?(): Promise<void>;
|
|
226
|
-
dispose?(): Promise<void>;
|
|
227
|
-
components?: Partial<Record<string, React.ComponentType<any>>>;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
225
|
/**
|
|
231
226
|
* Plugin SDK Helpers
|
|
232
227
|
*
|
|
@@ -584,4 +579,151 @@ declare class PluginHostAdapter implements HttpAdapter {
|
|
|
584
579
|
*/
|
|
585
580
|
declare function createPluginHostAdapter(context: HostContext, pluginId: string): PluginHostAdapter;
|
|
586
581
|
|
|
587
|
-
|
|
582
|
+
declare const HttpClient: typeof HttpClient$1;
|
|
583
|
+
type HttpClient = HttpClient$1;
|
|
584
|
+
|
|
585
|
+
interface ServiceConfigurationContext<TManifest extends PluginManifest = PluginManifest> {
|
|
586
|
+
httpClient: HttpClient;
|
|
587
|
+
useGraphQL: <TData = any>(apiName: string) => {
|
|
588
|
+
query: any;
|
|
589
|
+
mutate: any;
|
|
590
|
+
};
|
|
591
|
+
manifest: TManifest;
|
|
592
|
+
hostContext: HostContext;
|
|
593
|
+
}
|
|
594
|
+
type PluginContextOptions<TManifest extends PluginManifest, TClients extends Record<string, any>> = {
|
|
595
|
+
manifest: TManifest;
|
|
596
|
+
/**
|
|
597
|
+
* Factory function to create/configure services and clients.
|
|
598
|
+
* Receives a context object with initialized base clients and manifest.
|
|
599
|
+
*/
|
|
600
|
+
configureServices: (context: ServiceConfigurationContext<TManifest>) => TClients;
|
|
601
|
+
/**
|
|
602
|
+
* List of Context Providers to wrap the application in.
|
|
603
|
+
* Framework handles rendering them in order.
|
|
604
|
+
*/
|
|
605
|
+
providers: Array<{
|
|
606
|
+
provider: React.Provider<any> | React.ComponentType<any>;
|
|
607
|
+
/**
|
|
608
|
+
* Key of the client to inject directly as the provider value.
|
|
609
|
+
*/
|
|
610
|
+
clientKey?: Extract<keyof TClients, string>;
|
|
611
|
+
/**
|
|
612
|
+
* Explicit value or Factory function to create the value.
|
|
613
|
+
* If a function is provided, it receives the map of all initialized clients.
|
|
614
|
+
*/
|
|
615
|
+
value?: any | ((clients: TClients) => any);
|
|
616
|
+
}>;
|
|
617
|
+
};
|
|
618
|
+
/**
|
|
619
|
+
* Creates the entire Context handling machinery for a plugin.
|
|
620
|
+
* Returns the Provider, Context setters/getters, and Hooks.
|
|
621
|
+
*/
|
|
622
|
+
declare function createRuntime<TManifest extends PluginManifest, TClients extends Record<string, any>>(options: PluginContextOptions<TManifest, TClients>): {
|
|
623
|
+
PluginProvider: React.FC<{
|
|
624
|
+
children: React.ReactNode;
|
|
625
|
+
}>;
|
|
626
|
+
initialize: (context: HostContext) => void;
|
|
627
|
+
useHostContext: () => HostContext<any>;
|
|
628
|
+
useApi: () => PluginApiClient<TManifest>;
|
|
629
|
+
usePluginHooks: () => PluginApiHooks<TManifest>;
|
|
630
|
+
useGraphQL: () => PluginGraphQLClient<TManifest>;
|
|
631
|
+
getClient: <K extends keyof TClients>(key: K) => TClients[K];
|
|
632
|
+
};
|
|
633
|
+
/**
|
|
634
|
+
* Manifest Config for Framework
|
|
635
|
+
*/
|
|
636
|
+
interface FrameworkManifestConfig {
|
|
637
|
+
id: string;
|
|
638
|
+
name: string;
|
|
639
|
+
description?: string;
|
|
640
|
+
version?: string;
|
|
641
|
+
author?: string;
|
|
642
|
+
icon?: string;
|
|
643
|
+
type: 'internal' | 'microfrontend';
|
|
644
|
+
remote?: {
|
|
645
|
+
url?: string;
|
|
646
|
+
scope?: string;
|
|
647
|
+
module?: string;
|
|
648
|
+
};
|
|
649
|
+
/**
|
|
650
|
+
* Define custom integrations/APIs.
|
|
651
|
+
* Key: API Name (e.g., 'payoffDemandApi', 'portalApi')
|
|
652
|
+
* Value: Configuration object
|
|
653
|
+
*/
|
|
654
|
+
integrations?: Record<string, {
|
|
655
|
+
baseUrl: string;
|
|
656
|
+
graphql?: {
|
|
657
|
+
url: string;
|
|
658
|
+
operations: any;
|
|
659
|
+
};
|
|
660
|
+
}>;
|
|
661
|
+
extensions?: string[];
|
|
662
|
+
extraCapabilities?: string[];
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Helper to create a manifest that also exposes its configuration/endpoints
|
|
666
|
+
* allowing for safe destructuring and reuse.
|
|
667
|
+
*/
|
|
668
|
+
declare function createManifest(config: FrameworkManifestConfig): {
|
|
669
|
+
manifest: {
|
|
670
|
+
readonly remote: {
|
|
671
|
+
url: string;
|
|
672
|
+
scope: string;
|
|
673
|
+
module: string;
|
|
674
|
+
} | undefined;
|
|
675
|
+
readonly capabilities: string[];
|
|
676
|
+
readonly extensionPoints: string[];
|
|
677
|
+
readonly apis: any;
|
|
678
|
+
readonly id: string;
|
|
679
|
+
readonly name: string;
|
|
680
|
+
readonly description?: string;
|
|
681
|
+
readonly version: string;
|
|
682
|
+
readonly author: string;
|
|
683
|
+
readonly icon: string;
|
|
684
|
+
readonly type: "internal" | "microfrontend";
|
|
685
|
+
};
|
|
686
|
+
endpoints: Record<string, {
|
|
687
|
+
baseUrl: string;
|
|
688
|
+
graphqlUrl?: string;
|
|
689
|
+
}>;
|
|
690
|
+
};
|
|
691
|
+
interface FrameworkPluginDefinition<TContext extends HostContext = HostContext> {
|
|
692
|
+
manifest: any;
|
|
693
|
+
settings?: {
|
|
694
|
+
defaults?: Record<string, any>;
|
|
695
|
+
};
|
|
696
|
+
events?: {
|
|
697
|
+
[eventName: string]: (context: TContext, payload: any) => void;
|
|
698
|
+
};
|
|
699
|
+
components?: PluginDefinition<TContext>['components'];
|
|
700
|
+
onInitialize?: (context: TContext) => Promise<void> | void;
|
|
701
|
+
onActivate?: (context: TContext) => Promise<void> | void;
|
|
702
|
+
onDeactivate?: () => Promise<void> | void;
|
|
703
|
+
onDispose?: () => Promise<void> | void;
|
|
704
|
+
/**
|
|
705
|
+
* Callback to initialize the context (e.g. saving it to a global variable or provider)
|
|
706
|
+
*/
|
|
707
|
+
onContextInit?: (context: TContext) => void;
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Creates a plugin with a declarative framework.
|
|
711
|
+
* Wraps the standard definePlugin to providing auto-wiring of context, settings, and events.
|
|
712
|
+
*/
|
|
713
|
+
declare function createPlugin<TContext extends HostContext = HostContext>(definition: FrameworkPluginDefinition<TContext>): () => Plugin<any>;
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Standard Loading Fallback for Plugins
|
|
717
|
+
* Kept simple and dependency-free to ensure portability.
|
|
718
|
+
*/
|
|
719
|
+
declare const LoadingFallback: () => react_jsx_runtime.JSX.Element;
|
|
720
|
+
/**
|
|
721
|
+
* Creates a Lazy Loaded component wrapped in Suspense with a standard loader.
|
|
722
|
+
* @param importer The dynamic import function (e.g., () => import('./MyComponent'))
|
|
723
|
+
* @param Fallback Optional custom fallback component. Defaults to standard LoadingFallback.
|
|
724
|
+
*/
|
|
725
|
+
declare function createLazyComponent<T>(importer: () => Promise<{
|
|
726
|
+
default: ComponentType<T> | any;
|
|
727
|
+
}>, Fallback?: ComponentType): (props: T & JSX.IntrinsicAttributes) => react_jsx_runtime.JSX.Element;
|
|
728
|
+
|
|
729
|
+
export { type AlertOptions, type ApiAPI, type ApiRequestConfig, type ConfirmOptions, type EndpointConfig, type EventAPI, type EventHandler, ExtensionPoint, type FrameworkManifestConfig, type FrameworkPluginDefinition, type GraphQLApiConfig, type GraphQLError, type GraphQLOperation, type GraphQLRequestConfig, type GraphQLResponse, type HostCapabilities, type HostContext, LoadingFallback, type ModalAPI, type ModalAction, type ModalConfig, type NavigateOptions, type NavigationAPI, type NotificationAPI, type NotificationOptions, type Plugin, type PluginApiClient, type PluginApiConfig, type PluginApiHooks, type PluginDefinition, type PluginGraphQLClient, PluginHostAdapter, type PluginManifest, PluginType, type ServiceConfigurationContext, type StorageAPI, type UseApiMutationResult, type UseApiQueryOptions, type UseApiQueryResult, type UseMutationOptions, type UseMutationResult, type UseQueryOptions, type UseQueryResult, createGraphQLClient, createLazyComponent, createManifest, createPlugin, createPluginApi, createPluginApiHooks, createPluginHostAdapter, createRawGraphQLClient, createRuntime, defineApiConfig, defineEndpoints, defineManifest, definePlugin, useApiMutation, useApiQuery, useGraphQLMutation, useGraphQLQuery, useGraphQLSubscription };
|
package/dist/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import {useState,useRef,useCallback,useEffect}from'react';var w=(i=>(i.INTERNAL="internal",i.MICROFRONTEND="microfrontend",i.IFRAME="iframe",i))(w||{}),O=(e=>e)(O||{});function H(e){return ()=>({manifest:e.manifest,initialize:e.initialize,activate:e.activate,deactivate:e.deactivate,dispose:e.dispose,components:e.components})}function S(e){return e}function U(e){return e}function k(e){return e}function V(e,p){let f=e.id,i=e.apis||{},s={};for(let[t,a]of Object.entries(i)){let g=a.endpoints||a.allowedEndpoints||{};s[t]={};for(let[d,r]of Object.entries(g))s[t][d]=async(c={})=>{let{params:o={},data:l,headers:m}=c,y=r.path,n={},u=/{([^}]+)}/g,h;for(;(h=u.exec(r.path))!==null;){let x=h[1];o[x]&&(n[x]=o[x],y=y.replace(`{${x}}`,o[x]));}let T={...o};for(let x of Object.keys(n))delete T[x];let E=r.method||r.methods&&r.methods[0]||"GET";return p.request({pluginId:f,apiName:t,endpoint:d,method:E,params:Object.keys(T).length>0?T:void 0,data:l,headers:m})};}return s}function q(e,p,f,i,s,t){let[a,g]=useState(null),[d,r]=useState(false),[c,o]=useState(null),l=t?.enabled!==false,m=t?.refetchInterval,y=useRef(null),n=useCallback(async()=>{if(l){r(true),o(null);try{let u=await e.capabilities.api.request({pluginId:p,apiName:f,endpoint:i,method:"GET",...s});g(u),r(!1),t?.onSuccess&&t.onSuccess(u);}catch(u){let h=u instanceof Error?u:new Error(String(u));o(h),r(false),t?.onError&&t.onError(h);}}},[p,f,i,l,JSON.stringify(s)]);return useEffect(()=>{l&&n();},[n,l]),useEffect(()=>{if(m&&l)return y.current=setInterval(n,m),()=>{y.current&&clearInterval(y.current);}},[m,n,l]),{data:a,loading:d,error:c,refetch:n,isSuccess:!d&&!c&&a!==null,isError:!d&&c!==null}}function L(e,p,f,i,s="POST",t){let[a,g]=useState(null),[d,r]=useState(false),[c,o]=useState(null),l=useCallback(async y=>{r(true),o(null);try{let n=await e.capabilities.api.request({pluginId:p,apiName:f,endpoint:i,method:s,...y});return g(n),r(!1),t?.onSuccess&&t.onSuccess(n,y),n}catch(n){let u=n instanceof Error?n:new Error(String(n));throw o(u),r(false),t?.onError&&t.onError(u,y),u}},[p,f,i,s,t]),m=useCallback(()=>{g(null),o(null),r(false);},[]);return {data:a,loading:d,error:c,mutate:l,reset:m,isSuccess:!d&&!c&&a!==null,isError:!d&&c!==null}}function F(e,p,f){let i=f.apis||{},s={};for(let[t,a]of Object.entries(i)){s[t]={};let g=a.endpoints||a.allowedEndpoints||{};for(let[d,r]of Object.entries(g)){let c=r.method||r.methods&&r.methods[0]||"GET",o=`use${d.charAt(0).toUpperCase()}${d.slice(1)}`;c==="GET"?s[t][o]=(l,m)=>q(e,p,t,d,l,m):s[t][o]=l=>L(e,p,t,d,c,l);}}return s}function K(e,p){let f=e.id,i=e.apis||{},s={};for(let[t,a]of Object.entries(i)){if(!a.graphql)continue;let g=a.graphql,d=g.operations||{};s[t]={query:async(r,c)=>{let o=d[r];if(!o)throw new Error(`GraphQL operation '${r}' not found in manifest`);if(o.type!=="query")throw new Error(`Operation '${r}' is not a query`);let l=await p.graphql({pluginId:f,apiName:t,query:o.query,variables:c||o.variables||{},operationName:r,headers:g.headers});if(l.errors&&l.errors.length>0)throw new Error(l.errors[0].message);return l.data},mutate:async(r,c)=>{let o=d[r];if(!o)throw new Error(`GraphQL operation '${r}' not found in manifest`);if(o.type!=="mutation")throw new Error(`Operation '${r}' is not a mutation`);let l=await p.graphql({pluginId:f,apiName:t,query:o.query,variables:c||o.variables||{},operationName:r,headers:g.headers});if(l.errors&&l.errors.length>0)throw new Error(l.errors[0].message);return l.data},subscribe:(r,c,o)=>(console.warn("GraphQL subscriptions not yet implemented"),()=>{})};}return s}function z(e,p,f){return {async query(i,s,t){let a=await f.graphql({pluginId:e,apiName:p,query:i,variables:s||{},operationName:t});if(a.errors&&a.errors.length>0)throw new Error(a.errors[0].message);return a.data},async mutate(i,s,t){let a=await f.graphql({pluginId:e,apiName:p,query:i,variables:s||{},operationName:t});if(a.errors&&a.errors.length>0)throw new Error(a.errors[0].message);return a.data}}}function B(e,p,f={}){let{enabled:i=true,refetchOnMount:s=true,refetchInterval:t,onSuccess:a,onError:g,cacheTime:d=300*1e3}=f,[r,c]=useState(void 0),[o,l]=useState(i),[m,y]=useState(void 0),n=useRef(true),u=useRef(null),h=useCallback(async()=>{if(i){if(u.current&&Date.now()-u.current.timestamp<d){c(u.current.data),l(false);return}l(true),y(void 0);try{let T=await e.graphql(p);if(!n.current)return;if(T.errors&&T.errors.length>0){let E=new Error(T.errors[0].message);y(E),g?.(E);}else T.data&&(c(T.data),u.current={data:T.data,timestamp:Date.now()},a?.(T.data));}catch(T){if(!n.current)return;let E=T instanceof Error?T:new Error(String(T));y(E),g?.(E);}finally{n.current&&l(false);}}},[e,p,i,d,a,g]);return useEffect(()=>{s&&h();},[h,s]),useEffect(()=>{if(!t||!i)return;let T=setInterval(()=>{h();},t);return ()=>clearInterval(T)},[t,i,h]),useEffect(()=>()=>{n.current=false;},[]),{data:r,loading:o,error:m,refetch:h}}function W(e,p,f={}){let{onSuccess:i,onError:s}=f,[t,a]=useState(void 0),[g,d]=useState(false),[r,c]=useState(void 0),o=useRef(true);useEffect(()=>()=>{o.current=false;},[]);let l=useCallback(async y=>{d(true),c(void 0);try{let n=await e.graphql({...p,variables:y});if(!o.current)throw new Error("Component unmounted");if(n.errors&&n.errors.length>0){let u=new Error(n.errors[0].message);throw c(u),s?.(u,y),u}if(n.data)return a(n.data),i?.(n.data,y),n.data;throw new Error("No data returned from mutation")}catch(n){if(!o.current)throw n;let u=n instanceof Error?n:new Error(String(n));throw c(u),s?.(u,y),u}finally{o.current&&d(false);}},[e,p,i,s]),m=useCallback(()=>{a(void 0),c(void 0),d(false);},[]);return {mutate:l,data:t,loading:g,error:r,reset:m}}function X(e,p,f={}){return console.warn("GraphQL subscriptions not yet implemented"),{data:void 0,loading:false,error:new Error("Subscriptions not yet implemented"),refetch:async()=>{}}}var v=class{constructor(p,f){this.context=p;this.pluginId=f;}async request(p){let{url:f,method:i,headers:s,body:t,params:a}=p,g=f.split("/").pop()?.split("?")[0]??"";try{return {data:(await this.context.capabilities.api.request({pluginId:this.pluginId,endpoint:g,method:i,data:t,params:a,headers:s})).ObjOptional,status:200,statusText:"OK",headers:{}}}catch(d){throw {message:d.message||"Plugin API Request Failed",status:d.status||500,details:d}}}};function Z(e,p){return new v(e,p)}export{O as ExtensionPoint,v as PluginHostAdapter,w as PluginType,K as createGraphQLClient,V as createPluginApi,F as createPluginApiHooks,Z as createPluginHostAdapter,z as createRawGraphQLClient,k as defineApiConfig,U as defineEndpoints,S as defineManifest,H as definePlugin,L as useApiMutation,q as useApiQuery,W as useGraphQLMutation,B as useGraphQLQuery,X as useGraphQLSubscription};
|
|
1
|
+
import H,{useState,useRef,useCallback,useEffect,Suspense}from'react';import*as X from'@unifiedsoftware/http-client';import {jsx}from'react/jsx-runtime';var $=Object.defineProperty;var z=(e,t)=>{for(var r in t)$(e,r,{get:t[r],enumerable:true});};var N=(a=>(a.INTERNAL="internal",a.MICROFRONTEND="microfrontend",a.IFRAME="iframe",a))(N||{}),K=(e=>e)(K||{});function Q(e){return ()=>({manifest:e.manifest,initialize:e.initialize,activate:e.activate,deactivate:e.deactivate,dispose:e.dispose,components:e.components})}function re(e){return e}function ae(e){return e}function j(e){return e}function q(e,t){let r=e.id,a=e.apis||{},n={};for(let[i,c]of Object.entries(a)){let h=c.endpoints||c.allowedEndpoints||{};n[i]={};for(let[s,p]of Object.entries(h))n[i][s]=async(f={})=>{let{params:o={},data:u,headers:y}=f,d=p.path,l={},g=/{([^}]+)}/g,m;for(;(m=g.exec(p.path))!==null;){let x=m[1];o[x]&&(l[x]=o[x],d=d.replace(`{${x}}`,o[x]));}let T={...o};for(let x of Object.keys(l))delete T[x];let C=p.method||p.methods&&p.methods[0]||"GET";return t.request({pluginId:r,apiName:i,endpoint:s,method:C,params:Object.keys(T).length>0?T:void 0,data:u,headers:y})};}return n}function J(e,t,r,a,n,i){let[c,h]=useState(null),[s,p]=useState(false),[f,o]=useState(null),u=i?.enabled!==false,y=i?.refetchInterval,d=useRef(null),l=useCallback(async()=>{if(u){p(true),o(null);try{let g=await e.capabilities.api.request({pluginId:t,apiName:r,endpoint:a,method:"GET",...n});h(g),p(!1),i?.onSuccess&&i.onSuccess(g);}catch(g){let m=g instanceof Error?g:new Error(String(g));o(m),p(false),i?.onError&&i.onError(m);}}},[t,r,a,u,JSON.stringify(n)]);return useEffect(()=>{u&&l();},[l,u]),useEffect(()=>{if(y&&u)return d.current=setInterval(l,y),()=>{d.current&&clearInterval(d.current);}},[y,l,u]),{data:c,loading:s,error:f,refetch:l,isSuccess:!s&&!f&&c!==null,isError:!s&&f!==null}}function _(e,t,r,a,n="POST",i){let[c,h]=useState(null),[s,p]=useState(false),[f,o]=useState(null),u=useCallback(async d=>{p(true),o(null);try{let l=await e.capabilities.api.request({pluginId:t,apiName:r,endpoint:a,method:n,...d});return h(l),p(!1),i?.onSuccess&&i.onSuccess(l,d),l}catch(l){let g=l instanceof Error?l:new Error(String(l));throw o(g),p(false),i?.onError&&i.onError(g,d),g}},[t,r,a,n,i]),y=useCallback(()=>{h(null),o(null),p(false);},[]);return {data:c,loading:s,error:f,mutate:u,reset:y,isSuccess:!s&&!f&&c!==null,isError:!s&&f!==null}}function O(e,t,r){let a=r.apis||{},n={};for(let[i,c]of Object.entries(a)){n[i]={};let h=c.endpoints||c.allowedEndpoints||{};for(let[s,p]of Object.entries(h)){let f=p.method||p.methods&&p.methods[0]||"GET",o=`use${s.charAt(0).toUpperCase()}${s.slice(1)}`;f==="GET"?n[i][o]=(u,y)=>J(e,t,i,s,u,y):n[i][o]=u=>_(e,t,i,s,f,u);}}return n}function k(e,t){let r=e.id,a=e.apis||{},n={};for(let[i,c]of Object.entries(a)){if(!c.graphql)continue;let h=c.graphql,s=h.operations||{};n[i]={query:async(p,f)=>{let o=s[p];if(!o)throw new Error(`GraphQL operation '${p}' not found in manifest`);if(o.type!=="query")throw new Error(`Operation '${p}' is not a query`);let u=await t.graphql({pluginId:r,apiName:i,query:o.query,variables:f||o.variables||{},operationName:p,headers:h.headers});if(u.errors&&u.errors.length>0)throw new Error(u.errors[0].message);return u.data},mutate:async(p,f)=>{let o=s[p];if(!o)throw new Error(`GraphQL operation '${p}' not found in manifest`);if(o.type!=="mutation")throw new Error(`Operation '${p}' is not a mutation`);let u=await t.graphql({pluginId:r,apiName:i,query:o.query,variables:f||o.variables||{},operationName:p,headers:h.headers});if(u.errors&&u.errors.length>0)throw new Error(u.errors[0].message);return u.data},subscribe:(p,f,o)=>(console.warn("GraphQL subscriptions not yet implemented"),()=>{})};}return n}function S(e,t,r){return {async query(a,n,i){let c=await r.graphql({pluginId:e,apiName:t,query:a,variables:n||{},operationName:i});if(c.errors&&c.errors.length>0)throw new Error(c.errors[0].message);return c.data},async mutate(a,n,i){let c=await r.graphql({pluginId:e,apiName:t,query:a,variables:n||{},operationName:i});if(c.errors&&c.errors.length>0)throw new Error(c.errors[0].message);return c.data}}}function de(e,t,r={}){let{enabled:a=true,refetchOnMount:n=true,refetchInterval:i,onSuccess:c,onError:h,cacheTime:s=300*1e3}=r,[p,f]=useState(void 0),[o,u]=useState(a),[y,d]=useState(void 0),l=useRef(true),g=useRef(null),m=useCallback(async()=>{if(a){if(g.current&&Date.now()-g.current.timestamp<s){f(g.current.data),u(false);return}u(true),d(void 0);try{let T=await e.graphql(t);if(!l.current)return;if(T.errors&&T.errors.length>0){let C=new Error(T.errors[0].message);d(C),h?.(C);}else T.data&&(f(T.data),g.current={data:T.data,timestamp:Date.now()},c?.(T.data));}catch(T){if(!l.current)return;let C=T instanceof Error?T:new Error(String(T));d(C),h?.(C);}finally{l.current&&u(false);}}},[e,t,a,s,c,h]);return useEffect(()=>{n&&m();},[m,n]),useEffect(()=>{if(!i||!a)return;let T=setInterval(()=>{m();},i);return ()=>clearInterval(T)},[i,a,m]),useEffect(()=>()=>{l.current=false;},[]),{data:p,loading:o,error:y,refetch:m}}function ue(e,t,r={}){let{onSuccess:a,onError:n}=r,[i,c]=useState(void 0),[h,s]=useState(false),[p,f]=useState(void 0),o=useRef(true);useEffect(()=>()=>{o.current=false;},[]);let u=useCallback(async d=>{s(true),f(void 0);try{let l=await e.graphql({...t,variables:d});if(!o.current)throw new Error("Component unmounted");if(l.errors&&l.errors.length>0){let g=new Error(l.errors[0].message);throw f(g),n?.(g,d),g}if(l.data)return c(l.data),a?.(l.data,d),l.data;throw new Error("No data returned from mutation")}catch(l){if(!o.current)throw l;let g=l instanceof Error?l:new Error(String(l));throw f(g),n?.(g,d),g}finally{o.current&&s(false);}},[e,t,a,n]),y=useCallback(()=>{c(void 0),f(void 0),s(false);},[]);return {mutate:u,data:i,loading:h,error:p,reset:y}}function fe(e,t,r={}){return console.warn("GraphQL subscriptions not yet implemented"),{data:void 0,loading:false,error:new Error("Subscriptions not yet implemented"),refetch:async()=>{}}}var M=class{constructor(t,r){this.context=t;this.pluginId=r;}async request(t){let{url:r,method:a,headers:n,body:i,params:c}=t,h=r.split("/").pop()?.split("?")[0]??"";try{let s=await this.context.capabilities.api.request({pluginId:this.pluginId,endpoint:h,method:a,data:i,params:c,headers:n});return {data:s&&typeof s=="object"&&"ObjOptional"in s?s.ObjOptional:s,status:200,statusText:"OK",headers:{}}}catch(s){throw {message:s.message||"Plugin API Request Failed",status:s.status||500,details:s}}}};function U(e,t){return new M(e,t)}var L={};z(L,{GraphQLCache:()=>I,GraphQLClient:()=>F,GraphQLError:()=>v,createGraphQLClient:()=>W});var I=class{cache=new Map;defaultTTL;constructor(e=3e5){this.defaultTTL=e;}generateKey(e,t){let r=t?JSON.stringify(t):"";return `${e}:${r}`}isValid(e){return Date.now()-e.timestamp<e.ttl}get(e,t){let r=this.generateKey(e,t),a=this.cache.get(r);return a?this.isValid(a)?a.data:(this.cache.delete(r),null):null}set(e,t,r,a){let n=this.generateKey(e,r);this.cache.set(n,{data:t,timestamp:Date.now(),ttl:a||this.defaultTTL});}clear(e,t){let r=this.generateKey(e,t);this.cache.delete(r);}clearAll(){this.cache.clear();}get size(){return this.cache.size}},v=class extends Error{constructor(e,t,r){super(e),this.errors=t,this.response=r,this.name="GraphQLError";}get firstError(){var e;return ((e=this.errors[0])==null?void 0:e.message)||this.message}get messages(){return this.errors.map(e=>e.message)}},F=class{httpClient;endpoint;defaultHeaders;cache;constructor(e,t){this.httpClient=e,this.endpoint=t.endpoint,this.defaultHeaders={"Content-Type":"application/json",...t.headers},t.cache&&(this.cache=new I(t.cacheTTL));}async query(e,t,r){if(this.cache){let i=this.cache.get(e,t);if(i!==null)return i}let a={query:e,variables:t,operationName:r},n=await this.httpClient.post(this.endpoint,a,{headers:this.defaultHeaders});if(n.errors&&n.errors.length>0)throw new v(n.errors[0].message,n.errors,n);if(!n.data)throw new v("No data returned from GraphQL query",[],n);return this.cache&&this.cache.set(e,n.data,t),n.data}async mutate(e,t,r){let a={query:e,variables:t,operationName:r},n=await this.httpClient.post(this.endpoint,a,{headers:this.defaultHeaders});if(n.errors&&n.errors.length>0)throw new v(n.errors[0].message,n.errors,n);if(!n.data)throw new v("No data returned from GraphQL mutation",[],n);return n.data}async request(e){return await this.httpClient.post(this.endpoint,e,{headers:this.defaultHeaders})}clearCache(e,t){this.cache&&(e?this.cache.clear(e,t):this.cache.clearAll());}getHttpClient(){return this.httpClient}};function W(e,t){return new F(e,t)}var{HttpClient:B}=X,{createGraphQLClient:xe}=L;function De(e){let t,r,a,n,i={};return {PluginProvider:({children:y})=>{if(!(Object.keys(i).length>0))return null;let l=e.providers.reduceRight((g,m)=>{let{provider:T}=m,C;return "clientKey"in m&&m.clientKey?C=i[m.clientKey]:"value"in m&&(typeof m.value=="function"?C=m.value(i):C=m.value),H.createElement(T,{value:C},g)},y);return H.createElement(H.Fragment,null,l)},initialize:y=>{t=y;let d=y.manifest||e.manifest;console.log(`[${d.id}] Context Injected`),r=q(d,y.capabilities.api),a=O(y,d.id,d),n=k(d,y.capabilities.api);let m={httpClient:new B({adapter:U(y,d.id)}),useGraphQL:C=>S(d.id,C,y.capabilities.api),manifest:d,hostContext:y},T=e.configureServices(m);Object.assign(i,T);},useHostContext:()=>{if(!t)throw new Error("HostContext not initialized");return t},useApi:()=>{if(!r)throw new Error("ApiClient not initialized");return r},usePluginHooks:()=>{if(!a)throw new Error("ApiHooks not initialized");return a},useGraphQL:()=>{if(!n)throw new Error("GraphQLClient not initialized");return n},getClient:y=>{let d=i[y];if(!d)throw new Error(`Client ${String(y)} not initialized`);return d}}}function Me(e){let{integrations:t,extensions:r=[],extraCapabilities:a=[],remote:n,...i}=e,c={},h={},s=new Set(["notification","storage","events",...a]);return t&&(s.add("api_proxy"),Object.entries(t).forEach(([f,o])=>{c[f]={baseUrl:o.baseUrl,graphqlUrl:o.graphql?.url},h[f]={strategy:"proxy",baseUrl:o.baseUrl,auth:"inherit",...o.graphql&&{graphql:{url:o.graphql.url,auth:"inherit",operations:o.graphql.operations,headers:{"Content-Type":"application/json"},cache:{ttl:3e5,enabled:true}}}};})),{manifest:{version:"1.0.0",author:"Unified Software",icon:"extension",...i,remote:e.type==="microfrontend"?{url:n?.url||"https://localhost:4173/assets/remoteEntry.js",scope:n?.scope||"portalWeb",module:n?.module||`./${e.id}`}:void 0,capabilities:Array.from(s),extensionPoints:r,apis:h},endpoints:c}}function Le(e){return Q({manifest:e.manifest,components:e.components,async initialize(t){if(console.log(`[${e.manifest.id}] Initializing (Framework)...`),e.onContextInit&&e.onContextInit(t),e.settings?.defaults)try{let r=`${e.manifest.id}-settings`;await t.capabilities.storage.get(r)||await t.capabilities.storage.set(r,e.settings.defaults);}catch(r){console.error(`[${e.manifest.id}] Failed to init settings:`,r);}e.events&&Object.entries(e.events).forEach(([r,a])=>{t.capabilities.events.on(r,n=>a(t,n));}),e.onInitialize&&await e.onInitialize(t);},async activate(t){console.log(`[${e.manifest.id}] Activating (Framework)...`),t.capabilities.events.emit("plugin:activated",{pluginId:e.manifest.id}),e.onActivate&&await e.onActivate(t);},async deactivate(){e.onDeactivate&&await e.onDeactivate();},async dispose(){e.onDispose&&await e.onDispose();}})}var ee=()=>jsx("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",padding:"1rem",width:"100%",color:"#6c757d"},children:"Loading..."});function Ge(e,t=ee){let r=H.lazy(e);return a=>jsx(Suspense,{fallback:jsx(t,{}),children:jsx(r,{...a})})}
|
|
2
|
+
export{K as ExtensionPoint,ee as LoadingFallback,M as PluginHostAdapter,N as PluginType,k as createGraphQLClient,Ge as createLazyComponent,Me as createManifest,Le as createPlugin,q as createPluginApi,O as createPluginApiHooks,U as createPluginHostAdapter,S as createRawGraphQLClient,De as createRuntime,j as defineApiConfig,ae as defineEndpoints,re as defineManifest,Q as definePlugin,_ as useApiMutation,J as useApiQuery,ue as useGraphQLMutation,de as useGraphQLQuery,fe as useGraphQLSubscription};
|