@zxiaosi/sdk 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import { AxiosInstance, AxiosRequestConfig, CreateAxiosDefaults } from "axios";
2
- import { ConfigProviderProps } from "antd";
1
+ import * as zustand from "zustand";
3
2
  import { ComponentType, ReactElement } from "react";
4
3
  import { Location, NavigateFunction, RouteObject, UIMatch } from "react-router-dom";
4
+ import { AxiosInstance, AxiosRequestConfig, CreateAxiosDefaults } from "axios";
5
+ import { ConfigProviderProps } from "antd";
6
+ import * as react_intl_universal0 from "react-intl-universal";
5
7
  import intl from "react-intl-universal";
6
- import * as zustand from "zustand";
7
8
  import { MenuDataItem, ProLayoutProps } from "@ant-design/pro-layout";
8
9
  import { MicroApp, ObjectType, RegistrableApp } from "qiankun";
9
10
 
@@ -296,6 +297,8 @@ interface InitStateStoreProps {
296
297
  initState: UserInfo;
297
298
  /** 设置初始状态 */
298
299
  setInitState(initState: UserInfo): void;
300
+ /** 重置状态 */
301
+ resetInitState(): void;
299
302
  }
300
303
  /** 创建初始状态切片 */
301
304
  //#endregion
@@ -484,4 +487,48 @@ declare class Sdk implements SdkResult {
484
487
  */
485
488
  declare const sdk: Sdk;
486
489
  //#endregion
487
- export { type ApiOptions, type ApiResults, type AppOptions, type AppResults, type ClientOptions, type ClientResults, type ConfigOptions, type ConfigResults, type I18nOptions, type I18nResults, SdkApiPlugin, SdkAppPlugin, SdkClientPlugin, SdkConfigPlugin, SdkI18nPlugin, SdkStoragePlugin, SdkStorePlugin, SdkUIPlugin, type StorageOptions, type StorageResults, type StoreOptions, type StoreResults, type UIOptions, type UIResults, sdk };
490
+ //#region src/hooks/useInitState.d.ts
491
+ /** 初始化变量 */
492
+ declare const useInitState: () => {
493
+ initState: UserInfo;
494
+ setInitState: (initState: UserInfo) => void;
495
+ resetInitState: () => void;
496
+ };
497
+ //#endregion
498
+ //#region src/hooks/useIntl.d.ts
499
+ /**
500
+ * React Intl Universal
501
+ * - 如果项目不使用 React Compiler, 可以直接使用 sdk.i18n.intl
502
+ * - 不要解构使用, const { get } = useIntl() 会报错
503
+ * @example const intl = useIntl(); intl.get(key).d(defaultValue)
504
+ */
505
+ declare const useIntl: () => {
506
+ determineLocale: typeof react_intl_universal0.determineLocale;
507
+ formatHTMLMessage: typeof react_intl_universal0.formatHTMLMessage;
508
+ formatMessage: typeof react_intl_universal0.formatMessage;
509
+ get: typeof react_intl_universal0.get;
510
+ getHTML: typeof react_intl_universal0.getHTML;
511
+ getInitOptions: typeof react_intl_universal0.getInitOptions;
512
+ init: typeof react_intl_universal0.init;
513
+ load: typeof react_intl_universal0.load;
514
+ formatList: typeof react_intl_universal0.formatList;
515
+ formatParentheses: typeof react_intl_universal0.formatParentheses;
516
+ getColon: typeof react_intl_universal0.getColon;
517
+ formatNumber: typeof react_intl_universal0.formatNumber;
518
+ };
519
+ //#endregion
520
+ //#region src/hooks/useCrumb.d.ts
521
+ /**
522
+ * 获取面包屑
523
+ * @see https://reactrouter.com/6.30.3/hooks/use-matches
524
+ */
525
+ declare const useCrumb: () => any[];
526
+ //#endregion
527
+ //#region src/hooks/usePermission.d.ts
528
+ /**
529
+ * 判断是否有权限
530
+ * @param code 权限code (默认为当前路由)
531
+ */
532
+ declare const usePermission: (code?: string) => boolean;
533
+ //#endregion
534
+ export { type ApiOptions, type ApiResults, type AppOptions, type AppResults, type ClientOptions, type ClientResults, type ConfigOptions, type ConfigResults, type I18nOptions, type I18nResults, SdkApiPlugin, SdkAppPlugin, SdkClientPlugin, SdkConfigPlugin, SdkI18nPlugin, SdkStoragePlugin, SdkStorePlugin, SdkUIPlugin, type StorageOptions, type StorageResults, type StoreOptions, type StoreResults, type UIOptions, type UIResults, sdk, useCrumb, useInitState, useIntl, usePermission };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import e from"axios";import{Button as t,ConfigProvider as n,Flex as r,Form as i,Input as a,message as o,theme as s}from"antd";import{Suspense as c,createElement as l,memo as u,useEffect as d,useMemo as ee,useState as f}from"react";import{Navigate as p,Outlet as m,RouterProvider as te,createBrowserRouter as h,useLocation as g,useMatches as _,useNavigate as v}from"react-router-dom";import{Fragment as y,jsx as b,jsxs as x}from"react/jsx-runtime";import S from"react-intl-universal";import{createStore as C,useStore as w}from"zustand";import{subscribeWithSelector as T}from"zustand/middleware";import E from"@ant-design/pro-layout";import{loadMicroApp as ne,registerMicroApps as D,start as O}from"qiankun";import{useShallow as k}from"zustand/shallow";const A=new class{name;_plugins;api;app;client;config;i18n;storage;store;ui;constructor(){this.name=``,this._plugins=new Map}mount(e){if(window[e])throw Error(`The SDK already exists - ${e}`);console.log(`%c SDK mounted:`,`color: pink; font-weight: bold;`,e,A),this.name=e;let t=new Proxy(this,{get:(e,t,n)=>e?Reflect.get(e,t,n):null,set:()=>(console.error(`The SDK cannot be modified.`),!1),deleteProperty:()=>(console.error(`The SDK cannot be deleted.`),!1)});window[this.name]=t}extend(e){if(!window[e])throw Error(`The SDK not found - ${e}`);console.log(`%c SDK extended:`,`color: pink; font-weight: bold;`,e),Object.assign(this,window[e])}use(e,t){let{name:n,install:r}=e;if(!n)throw Error(`${n} plugin has no name`);if(typeof r!=`function`)throw Error(`${n} plugin is not a function`);return r(this,t),this._plugins.set(n,{...e,options:t}),this}};function j(e){return e==null||typeof e!=`object`&&typeof e!=`function`}function M(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function re(e){return Object.getOwnPropertySymbols(e).filter(t=>Object.prototype.propertyIsEnumerable.call(e,t))}function ie(e){return e==null?e===void 0?`[object Undefined]`:`[object Null]`:Object.prototype.toString.call(e)}function N(e,t,n,r=new Map,i=void 0){let a=i?.(e,t,n,r);if(a!==void 0)return a;if(j(e))return e;if(r.has(e))return r.get(e);if(Array.isArray(e)){let t=Array(e.length);r.set(e,t);for(let a=0;a<e.length;a++)t[a]=N(e[a],a,n,r,i);return Object.hasOwn(e,`index`)&&(t.index=e.index),Object.hasOwn(e,`input`)&&(t.input=e.input),t}if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp){let t=new RegExp(e.source,e.flags);return t.lastIndex=e.lastIndex,t}if(e instanceof Map){let t=new Map;r.set(e,t);for(let[a,o]of e)t.set(a,N(o,a,n,r,i));return t}if(e instanceof Set){let t=new Set;r.set(e,t);for(let a of e)t.add(N(a,void 0,n,r,i));return t}if(typeof Buffer<`u`&&Buffer.isBuffer(e))return e.subarray();if(M(e)){let t=new(Object.getPrototypeOf(e)).constructor(e.length);r.set(e,t);for(let a=0;a<e.length;a++)t[a]=N(e[a],a,n,r,i);return t}if(e instanceof ArrayBuffer||typeof SharedArrayBuffer<`u`&&e instanceof SharedArrayBuffer)return e.slice(0);if(e instanceof DataView){let t=new DataView(e.buffer.slice(0),e.byteOffset,e.byteLength);return r.set(e,t),P(t,e,n,r,i),t}if(typeof File<`u`&&e instanceof File){let t=new File([e],e.name,{type:e.type});return r.set(e,t),P(t,e,n,r,i),t}if(typeof Blob<`u`&&e instanceof Blob){let t=new Blob([e],{type:e.type});return r.set(e,t),P(t,e,n,r,i),t}if(e instanceof Error){let t=new e.constructor;return r.set(e,t),t.message=e.message,t.name=e.name,t.stack=e.stack,t.cause=e.cause,P(t,e,n,r,i),t}if(e instanceof Boolean){let t=new Boolean(e.valueOf());return r.set(e,t),P(t,e,n,r,i),t}if(e instanceof Number){let t=new Number(e.valueOf());return r.set(e,t),P(t,e,n,r,i),t}if(e instanceof String){let t=new String(e.valueOf());return r.set(e,t),P(t,e,n,r,i),t}if(typeof e==`object`&&ae(e)){let t=Object.create(Object.getPrototypeOf(e));return r.set(e,t),P(t,e,n,r,i),t}return e}function P(e,t,n=e,r,i){let a=[...Object.keys(t),...re(t)];for(let o=0;o<a.length;o++){let s=a[o],c=Object.getOwnPropertyDescriptor(e,s);(c==null||c.writable)&&(e[s]=N(t[s],s,n,r,i))}}function ae(e){switch(ie(e)){case`[object Arguments]`:case`[object Array]`:case`[object ArrayBuffer]`:case`[object DataView]`:case`[object Boolean]`:case`[object Date]`:case`[object Float32Array]`:case`[object Float64Array]`:case`[object Int8Array]`:case`[object Int16Array]`:case`[object Int32Array]`:case`[object Map]`:case`[object Number]`:case`[object Object]`:case`[object RegExp]`:case`[object Set]`:case`[object String]`:case`[object Symbol]`:case`[object Uint8Array]`:case`[object Uint8ClampedArray]`:case`[object Uint16Array]`:case`[object Uint32Array]`:return!0;default:return!1}}function oe(e){return N(e,void 0,e,new Map,void 0)}function F(e){if(!e||typeof e!=`object`)return!1;let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype||Object.getPrototypeOf(t)===null?Object.prototype.toString.call(e)===`[object Object]`:!1}function se(e){return e===`__proto__`}function I(e,t){let n=Object.keys(t);for(let r=0;r<n.length;r++){let i=n[r];if(se(i))continue;let a=t[i],o=e[i];L(a)&&L(o)?e[i]=I(o,a):Array.isArray(a)?e[i]=I([],a):F(a)?e[i]=I({},a):(o===void 0||a!==void 0)&&(e[i]=a)}return e}function L(e){return F(e)||Array.isArray(e)}const R=e=>{let{requestId:t,url:n,method:r,params:i,data:a}=e;return t||`${r}:${n}?${JSON.stringify(i)}&${JSON.stringify(a)}`},z=e=>{let t=R(e),n=A.api.controllers.get(t);n&&(n.abort(),A.api.controllers.delete(t))},B={beforeLoad:[async e=>{console.log(`[LifeCycle] before load %c%s`,`color: green;`,e.name)}],beforeMount:[async e=>{console.log(`[LifeCycle] before mount %c%s`,`color: green;`,e.name)}],afterUnmount:[async e=>{console.log(`[LifeCycle] after unmount %c%s`,`color: green;`,e.name)}]},V=e=>{let t=e.storage.getTheme();if(t)return t;let n=e.config?.theme;if(n)return n;let r=window.matchMedia(`(prefers-color-scheme: dark)`);return r.matches&&r.matches?`dark`:`light`},H=e=>e.storage.getLocale()||e.config?.locale||navigator.language||`zh-CN`,U=e=>{let t=new Map,n=W(e,t);return{microApps:[...t.values()],menuData:n}},W=(e,t)=>!e||e?.length===0?[]:e.map(e=>{let n=null,{locale:r,path:i,icon:a,component:o,routeAttr:s,children:c}=e;if(s){let e={};try{e=JSON.parse(s)}catch(e){console.error(`Sdk: initData - Subapp routeAttr error: `,e)}let{name:r,rootId:i,...a}=e,o={...a,name:r,container:`#${i}`,props:{sdk:A},loader:e=>A.store.getState().setMicroAppLoading(e)};t.set(r,o),n=A.ui.renderComponent(`Microapp`,{name:r,rootId:i})}else n=o===`Outlet`?b(m,{}):A.ui.renderComponent(o);return{...e,key:`${i}_${a}_${r}`,element:n,children:W(c,t),handle:{crumb:(t={})=>({...e,...t})}}}),G=e=>{let t=`/`;return!e||e.length===0?t:(t=e?.[0]?.path,e?.[0]?.children&&e?.[0]?.children.length>0&&(t=G(e?.[0]?.children)),t)};var K=class{instance;constructor(t={}){this.instance=e.create(t),this.defaultRequestInterceptor(),this.defaultResponseInterceptor()}defaultRequestInterceptor(){this.instance.interceptors.request.use(function(e){if(e?.isCancelRequest){let t=R(e);z(e);let n=new AbortController;A.api.controllers.set(t,n),e.requestId=t,e.signal=n.signal}let t=A.storage.getToken();return e.headers.lang=A.config.locale,e.headers.Authorization=t,I(e.headers,A.api.config.headers||{}),e},function(e){return console.error(`Sdk: defaultRequestInterceptor - 请求错误`),Promise.reject(e)})}defaultResponseInterceptor(){this.instance.interceptors.response.use(function(e){let{data:t,config:n}=e,{isOriginalData:r,isShowFailMsg:i,isCancelRequest:a}=n,{code:s,msg:c}=t;return s!==0&&(i&&o.error(c),console.error(`Sdk: defaultResponseInterceptor - Response error: `,n.url,c),s==20041&&A.app.pageToLogin()),a&&A.api.controllers.delete(n.requestId),r?e:e.data},function(t){let{response:n,config:r}=t,{isShowFailMsg:i}=r;if(e.isCancel(t))return Promise.reject(t);if(n){let{status:e,data:t,statusText:r}=n;i&&o.error(t.msg||r),e==401&&A.app.pageToLogin()}else i&&o.error(`请求超时或服务器异常,请检查网络或联系管理员`),console.error(`Sdk: defaultResponseInterceptor - Request error:`,r.url,t);return Promise.reject(t)})}getInstance(){return this.instance}};const ce={name:`api`,install(e,t={}){let n={baseURL:`/`,timeout:0,...t.config},r=t?.instance||new K(n).getInstance();e.api=I({config:n,controllers:new Map,instance:null,request:(e,t={})=>r.request({url:e,isOriginalData:!1,isShowFailMsg:!0,isCancelRequest:!0,...t}),getUserInfoApi:()=>e.api.request(`/getUserInfo`,{method:`GET`}),getRoutesApi:()=>e.api.request(`/routes`,{method:`GET`}),loginApi:()=>e.api.request(`/login`,{method:`POST`})},t)}},le={name:`app`,install(e,t={}){e.app=I({menuData:[],allRoutes:[],microApps:[],microAppsInstance:new Map,user:null,permissions:[],roles:[],settings:{},initData:null,clearData:()=>{e.app.menuData=[],e.app.allRoutes=e.app.allRoutes.filter(e=>e.path!==`/`),e.app.microApps=[],e.app.microAppsInstance.forEach(e=>e.unmount()),e.app.microAppsInstance.clear(),e.app.user=null,e.app.permissions=[],e.app.roles=[],e.app.settings={}},pageToLogin:()=>{e.storage.clearToken();let t=window.location.pathname||`/`,n=e.config.loginPath,r=t===n?n:`${n}?redirect=${encodeURIComponent(t)}`;e.config.qiankunMode===`router`?window.location.replace(r):(e.app.clearData(),e.client.navigate(r,{replace:!0}))},getRedirectPath:()=>{let t=e.config.defaultPath;if(t)return t;let n=new URLSearchParams(window.location.search);return decodeURIComponent(n.get(`redirect`)||``)||`/`}},t)}},q=`client`,ue={name:q,install(e,t={}){e[q]=I({location:null,navigate:null,matches:null},t)}},J=`config`,de={name:J,install(e,t={}){e[J]=I({env:{},qiankunMode:`router`,theme:null,locale:null,loginPath:`/login`,defaultPath:``,customRoutes:[],antdConfig:{},proLayoutConfig:{title:`Demo`}},t)}},Y=`i18n`,fe={name:Y,install(e,t={}){e[Y]=I({intl:S,intlConfig:{},loadLocale:e=>void 0},t)}},X=`storage`,pe={name:X,install(e,t={}){e[X]=I({localeKey:`locale`,themeKey:`theme`,tokenKey:`token`,getLocale:()=>localStorage.getItem(e.storage.localeKey),setLocale:t=>{localStorage.setItem(e.storage.localeKey,t)},clearLocale:()=>{localStorage.removeItem(e.storage.localeKey)},getTheme:()=>localStorage.getItem(e.storage.themeKey),setTheme:t=>{localStorage.setItem(e.storage.themeKey,t)},clearTheme:()=>{localStorage.removeItem(e.storage.themeKey)},getToken:()=>localStorage.getItem(e.storage.tokenKey),setToken:t=>{localStorage.setItem(e.storage.tokenKey,t)},clearToken:()=>{localStorage.removeItem(e.storage.tokenKey)}},t)}},me=(e,t)=>({initState:{},setInitState:t=>{e(()=>({initState:t})),A.app={...A.app,...t}}}),he=(e,t)=>({locale:null,setLocale:t=>{e(()=>({locale:t})),A.config.locale=t,A.storage.setLocale(t),document.documentElement.setAttribute(`lang`,t);let n=A.i18n.intlConfig;S.init({currentLocale:t,locales:n});try{let e=A.i18n.loadLocale?.(t)||void 0;A.config.antdConfig.locale=e}catch(e){console.error(`Sdk: createLocaleSlice - sdk.i18n.loadLocale error:`,e)}}}),ge=(e,t)=>({microAppLoading:!1,setMicroAppLoading:t=>e(()=>({microAppLoading:t}))}),{defaultAlgorithm:_e,darkAlgorithm:ve}=s,ye=(e,t)=>({theme:null,setTheme:t=>{e(()=>({theme:t})),A.config.theme=t,A.storage.setTheme(t),document.documentElement.setAttribute(`theme`,t);let n=t===`light`?_e:ve;I(A.config.antdConfig,{theme:{algorithm:n}})}}),be=C()(T((...e)=>({...me(...e),...he(...e),...ge(...e),...ye(...e)}))),Z=`store`,xe={name:Z,install(e,t={}){e[Z]=be}},Q=()=>{let e=v(),t=g(),n=_(),r=w(A.store,e=>e.locale),i=n[n.length-1]?.handle?.crumb()||{},a=JSON.parse(i?.routeAttr||`{}`)?.noLayout,o=t=>{e(t.path)};return b(E,{locale:r,formatMessage:({id:e,defaultMessage:t})=>A.i18n.intl.get(e).d(t),location:t,menuItemRender:(e,t)=>b(`div`,{onClick:()=>o(e),children:t}),onMenuHeaderClick:()=>{e(`/`)},onPageChange:e=>{if(!A.app.user||Object.keys(A.app.user).length===0)return A.app.pageToLogin()},...a&&{headerRender:!1,footerRender:!1,menuRender:!1},menu:{request:async()=>A.app.menuData||[],...A.config.proLayoutConfig.menu},...A.config.proLayoutConfig,children:b(c,{fallback:A.ui.renderComponent(`Loading`,{isSuspense:!0}),children:b(m,{})})})},{useToken:Se}=s,Ce=({isInitData:e=!1,isSuspense:t=!1,isMicroApp:n=!1})=>{let{token:r}=Se();return b(`div`,{style:e?{width:`100%`,height:`100%`,display:`flex`,alignItems:`center`,justifyContent:`center`,background:r.colorBgContainer,color:r.colorText}:{},children:`Loading...`})},{useToken:we}=s,Te=()=>{let{token:e}=we(),[n,o]=f(!1);return b(r,{style:{width:`100%`,height:`100%`,background:e.colorBgContainer},justify:`center`,align:`center`,children:x(i,{labelCol:{span:8},labelAlign:`left`,wrapperCol:{span:16},style:{maxWidth:600},initialValues:{username:`admin`,password:`admin`},onFinish:async e=>{try{o(()=>!0);let t=await A.api.loginApi(e);o(()=>!1);let n=t?.data?.token||``;if(!n)return;A.storage.setToken(n);let r=A.app.getRedirectPath();A.config.qiankunMode===`load`?(A.client.navigate(r,{replace:!0}),A.app.initData?.()):window.location.replace(r)}catch(e){console.log(`Sdk: Login - handleFinish: `,e),o(()=>!1)}},autoComplete:`off`,children:[b(i.Item,{label:`用户名`,name:`username`,rules:[{required:!0,message:`请输入用户名!`}],children:b(a,{})}),b(i.Item,{label:`密码`,name:`password`,rules:[{required:!0,message:`请输入密码!`}],children:b(a.Password,{})}),b(i.Item,{noStyle:!0,children:b(t,{block:!0,type:`primary`,htmlType:`submit`,loading:n,children:`登录`})})]})})},$=({children:e})=>{let t=g(),n=_(),r=v();return A.client.location=t,A.client.matches=n,A.client.navigate=r,e},Ee=()=>{let e=A.config.loginPath,t=A.config.customRoutes,r=A.config.qiankunMode===`router`,i=e=>A.ui.renderComponent(`Loading`,e),a=A.ui.renderComponent(`Layout`),o=A.ui.renderComponent(`Login`),s=A.ui.renderComponent(`NotFound`),l=[{path:e,element:o},{path:`*`,element:s},...t].map(e=>({...e,element:b($,{children:e.element})})),[u,m]=f(!1),[g,_]=f(l),[v,y,x,S]=w(A.store,k(e=>[e.locale,e.setLocale,e.theme,e.setTheme])),C=ee(()=>oe(A.config.antdConfig),[v,x]),T=(e,t)=>{S(e||V(A)),y(t||H(A))},E=async()=>{try{m(()=>!0);let[{data:e={}},{data:t=[]}]=await Promise.all([A.api.getUserInfoApi(),A.api.getRoutesApi()]);m(()=>!1);let{theme:n,locale:i}=e?.settings||{};T(n,i);let{microApps:o=[],menuData:c=[]}=U(t);r&&(D(o,B),O());let u=G(c),d=[...l,{path:`/`,element:b(p,{to:u,replace:!0})},{path:`/`,element:b($,{children:a}),children:c,errorElement:s}];_(d),A.app={...A.app,...e,allRoutes:d,microApps:o,menuData:c}}catch(e){console.error(e),m(()=>!1)}};return d(()=>{A.app.initData=E,A.app.allRoutes=l;let t=A.config.customRoutes?.map(e=>e.path),n=window.location.pathname;[e,...t]?.includes(n)?T():E()},[]),b(n,{...C,children:b(c,{fallback:i({isSuspense:!0}),children:u?i({isInitData:!0}):b(te,{router:h(g,{basename:`/`}),future:{v7_startTransition:!1}})})})};var De=u(({name:e,rootId:t})=>{let[n,r]=w(A.store,k(e=>[e.microAppLoading,e.setMicroAppLoading]));return d(()=>{if(!e||A.config.qiankunMode!==`load`)return;let t=A.app.microAppsInstance.get(e);if(t)t?.mount();else{let n=A.app.microApps.find(t=>t.name===e);if(!n)return;r(!0),t=ne(n,{},B),t?.mountPromise?.finally(()=>{r(!1)}),A.app.microAppsInstance.set(e,t)}return()=>{t?.unmount()}},[e]),x(y,{children:[n&&A.ui.renderComponent(`Loading`,{isMicroApp:!0}),b(`main`,{id:t})]})});const Oe=()=>b(`div`,{children:`无权限`}),{useToken:ke}=s,Ae=()=>{let{token:e}=ke();return b(`div`,{style:{width:`100%`,height:`100%`,display:`flex`,alignItems:`center`,justifyContent:`center`,background:e.colorBgContainer},children:`找不到页面`})},je={name:`ui`,install(e,t={}){e.ui=I({Layout:Q,Loading:Ce,Login:Te,Mainapp:Ee,Microapp:De,NotFound:Ae,NoPermission:Oe,setComponent:(t,n)=>{if(!t){console.error(`Sdk: SdkUIPlugin - component cannot be empty`);return}let r=n||t.displayName||t.name;if(!r){console.error(`Sdk: SdkUIPlugin - Component name cannot be empty`);return}e.ui[r]=t},getComponent:t=>t?e.ui[t]:(console.error(`Sdk: SdkUIPlugin - Component name cannot be empty`),null),renderComponent:(t,n={})=>{let r=e.ui.getComponent(t);return r?l(r,n):(console.error(`Sdk: SdkUIPlugin - Component ${t} not found`),null)}},t)}};export{ce as SdkApiPlugin,le as SdkAppPlugin,ue as SdkClientPlugin,de as SdkConfigPlugin,fe as SdkI18nPlugin,pe as SdkStoragePlugin,xe as SdkStorePlugin,je as SdkUIPlugin,A as sdk};
1
+ import{createStore as e,useStore as t}from"zustand";import{useShallow as n}from"zustand/shallow";import{Suspense as r,createElement as i,memo as a,useEffect as o,useMemo as s,useState as c}from"react";import{Navigate as ee,Outlet as l,RouterProvider as te,createBrowserRouter as ne,useLocation as u,useMatches as d,useNavigate as f}from"react-router-dom";import{Fragment as p,jsx as m,jsxs as h}from"react/jsx-runtime";import g from"axios";import{Button as _,ConfigProvider as re,Flex as v,Form as y,Input as b,message as x,theme as S}from"antd";import C from"react-intl-universal";import{subscribeWithSelector as w}from"zustand/middleware";import T from"@ant-design/pro-layout";import{loadMicroApp as E,registerMicroApps as ie,start as ae}from"qiankun";const D=new class{name;_plugins;api;app;client;config;i18n;storage;store;ui;constructor(){this.name=``,this._plugins=new Map}mount(e){if(window[e])throw Error(`The SDK already exists - ${e}`);console.log(`%c SDK mounted:`,`color: pink; font-weight: bold;`,e,D),this.name=e;let t=new Proxy(this,{get:(e,t,n)=>e?Reflect.get(e,t,n):null,set:()=>(console.error(`The SDK cannot be modified.`),!1),deleteProperty:()=>(console.error(`The SDK cannot be deleted.`),!1)});window[this.name]=t}extend(e){if(!window[e])throw Error(`The SDK not found - ${e}`);console.log(`%c SDK extended:`,`color: pink; font-weight: bold;`,e),Object.assign(this,window[e])}use(e,t){let{name:n,install:r}=e;if(!n)throw Error(`${n} plugin has no name`);if(typeof r!=`function`)throw Error(`${n} plugin is not a function`);return r(this,t),this._plugins.set(n,{...e,options:t}),this}},O=()=>{let[e,r,i]=t(D.store,n(e=>[e.initState,e.setInitState,e.resetInitState]));return{initState:e,setInitState:r,resetInitState:i}};function k(e){return e==null||typeof e!=`object`&&typeof e!=`function`}function A(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function oe(e){return Object.getOwnPropertySymbols(e).filter(t=>Object.prototype.propertyIsEnumerable.call(e,t))}function se(e){return e==null?e===void 0?`[object Undefined]`:`[object Null]`:Object.prototype.toString.call(e)}function j(e,t,n,r=new Map,i=void 0){let a=i?.(e,t,n,r);if(a!==void 0)return a;if(k(e))return e;if(r.has(e))return r.get(e);if(Array.isArray(e)){let t=Array(e.length);r.set(e,t);for(let a=0;a<e.length;a++)t[a]=j(e[a],a,n,r,i);return Object.hasOwn(e,`index`)&&(t.index=e.index),Object.hasOwn(e,`input`)&&(t.input=e.input),t}if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp){let t=new RegExp(e.source,e.flags);return t.lastIndex=e.lastIndex,t}if(e instanceof Map){let t=new Map;r.set(e,t);for(let[a,o]of e)t.set(a,j(o,a,n,r,i));return t}if(e instanceof Set){let t=new Set;r.set(e,t);for(let a of e)t.add(j(a,void 0,n,r,i));return t}if(typeof Buffer<`u`&&Buffer.isBuffer(e))return e.subarray();if(A(e)){let t=new(Object.getPrototypeOf(e)).constructor(e.length);r.set(e,t);for(let a=0;a<e.length;a++)t[a]=j(e[a],a,n,r,i);return t}if(e instanceof ArrayBuffer||typeof SharedArrayBuffer<`u`&&e instanceof SharedArrayBuffer)return e.slice(0);if(e instanceof DataView){let t=new DataView(e.buffer.slice(0),e.byteOffset,e.byteLength);return r.set(e,t),M(t,e,n,r,i),t}if(typeof File<`u`&&e instanceof File){let t=new File([e],e.name,{type:e.type});return r.set(e,t),M(t,e,n,r,i),t}if(typeof Blob<`u`&&e instanceof Blob){let t=new Blob([e],{type:e.type});return r.set(e,t),M(t,e,n,r,i),t}if(e instanceof Error){let t=structuredClone(e);return r.set(e,t),t.message=e.message,t.name=e.name,t.stack=e.stack,t.cause=e.cause,t.constructor=e.constructor,M(t,e,n,r,i),t}if(e instanceof Boolean){let t=new Boolean(e.valueOf());return r.set(e,t),M(t,e,n,r,i),t}if(e instanceof Number){let t=new Number(e.valueOf());return r.set(e,t),M(t,e,n,r,i),t}if(e instanceof String){let t=new String(e.valueOf());return r.set(e,t),M(t,e,n,r,i),t}if(typeof e==`object`&&ce(e)){let t=Object.create(Object.getPrototypeOf(e));return r.set(e,t),M(t,e,n,r,i),t}return e}function M(e,t,n=e,r,i){let a=[...Object.keys(t),...oe(t)];for(let o=0;o<a.length;o++){let s=a[o],c=Object.getOwnPropertyDescriptor(e,s);(c==null||c.writable)&&(e[s]=j(t[s],s,n,r,i))}}function ce(e){switch(se(e)){case`[object Arguments]`:case`[object Array]`:case`[object ArrayBuffer]`:case`[object DataView]`:case`[object Boolean]`:case`[object Date]`:case`[object Float32Array]`:case`[object Float64Array]`:case`[object Int8Array]`:case`[object Int16Array]`:case`[object Int32Array]`:case`[object Map]`:case`[object Number]`:case`[object Object]`:case`[object RegExp]`:case`[object Set]`:case`[object String]`:case`[object Symbol]`:case`[object Uint8Array]`:case`[object Uint8ClampedArray]`:case`[object Uint16Array]`:case`[object Uint32Array]`:return!0;default:return!1}}function N(e){return j(e,void 0,e,new Map,void 0)}function P(e){if(!e||typeof e!=`object`)return!1;let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype||Object.getPrototypeOf(t)===null?Object.prototype.toString.call(e)===`[object Object]`:!1}function le(e){return e===`__proto__`}function F(e,t){let n=Object.keys(t);for(let r=0;r<n.length;r++){let i=n[r];if(le(i))continue;let a=t[i],o=e[i];I(a)&&I(o)?e[i]=F(o,a):Array.isArray(a)?e[i]=F([],a):P(a)?e[i]=F({},a):(o===void 0||a!==void 0)&&(e[i]=a)}return e}function I(e){return P(e)||Array.isArray(e)}const ue=()=>s(()=>N(D.i18n.intl),[t(D.store,e=>e.locale)]),L=()=>s(()=>D.client.matches,[u()]).filter(e=>!!e.handle?.crumb).map(e=>e.handle.crumb(e.data)),R=e=>{let{requestId:t,url:n,method:r,params:i,data:a}=e;return t||`${r}:${n}?${JSON.stringify(i)}&${JSON.stringify(a)}`},z=e=>{let t=R(e),n=D.api.controllers.get(t);n&&(n.abort(),D.api.controllers.delete(t))},B={beforeLoad:[async e=>{console.log(`[LifeCycle] before load %c%s`,`color: green;`,e.name)}],beforeMount:[async e=>{console.log(`[LifeCycle] before mount %c%s`,`color: green;`,e.name)}],afterUnmount:[async e=>{console.log(`[LifeCycle] after unmount %c%s`,`color: green;`,e.name)}]},V=e=>{let t=e.storage.getTheme();if(t)return t;let n=e.config?.theme;if(n)return n;let r=window.matchMedia(`(prefers-color-scheme: dark)`);return r.matches&&r.matches?`dark`:`light`},H=e=>e.storage.getLocale()||e.config?.locale||navigator.language||`zh-CN`,U=e=>D.app.permissions?.includes?.(e),de=e=>{let t=new Map,n=W(e,t);return{microApps:[...t.values()],menuData:n}},W=(e,t)=>!e||e?.length===0?[]:e.map(e=>{let n=null,{locale:r,path:i,icon:a,component:o,routeAttr:s,children:c}=e;if(s){let e={};try{e=JSON.parse(s)}catch(e){console.error(`Sdk: initData - Subapp routeAttr error: `,e)}let{name:r,rootId:i,...a}=e,o={...a,name:r,container:`#${i}`,props:{sdk:D},loader:e=>D.store.getState().setMicroAppLoading(e)};t.set(r,o),n=D.ui.renderComponent(`Microapp`,{name:r,rootId:i})}else if(o===`Microapp`)n=D.ui.renderComponent(`Microapp`);else if(o===`Outlet`)n=m(l,{});else{let e=U(i);n=D.ui.renderComponent(e?o:`NoPermission`)}return{...e,key:`${i}_${a}_${r}`,element:n,children:W(c,t),handle:{crumb:(t={})=>({...e,...t})}}}),G=e=>{let t=`/`;return!e||e.length===0?t:(t=e?.[0]?.path,e?.[0]?.children&&e?.[0]?.children.length>0&&(t=G(e?.[0]?.children)),t)},fe=e=>s(()=>U(e||D.client.location.pathname),[u().pathname,e]);var pe=class{instance;constructor(e={}){this.instance=g.create(e),this.defaultRequestInterceptor(),this.defaultResponseInterceptor()}defaultRequestInterceptor(){this.instance.interceptors.request.use(function(e){if(e?.isCancelRequest){let t=R(e);z(e);let n=new AbortController;D.api.controllers.set(t,n),e.requestId=t,e.signal=n.signal}let t=D.storage.getToken();return e.headers.lang=D.config.locale,e.headers.Authorization=t,F(e.headers,D.api.config.headers||{}),e},function(e){return console.error(`Sdk: defaultRequestInterceptor - 请求错误`),Promise.reject(e)})}defaultResponseInterceptor(){this.instance.interceptors.response.use(function(e){let{data:t,config:n}=e,{isOriginalData:r,isShowFailMsg:i,isCancelRequest:a}=n,{code:o,msg:s}=t;return o!==0&&(i&&x.error(s),console.error(`Sdk: defaultResponseInterceptor - Response error: `,n.url,s),o==20041&&D.app.pageToLogin()),a&&D.api.controllers.delete(n.requestId),r?e:e.data},function(e){let{response:t,config:n}=e,{isShowFailMsg:r}=n;if(g.isCancel(e))return Promise.reject(e);if(t){let{status:e,data:n,statusText:i}=t;r&&x.error(n.msg||i),e==401&&D.app.pageToLogin()}else r&&x.error(`请求超时或服务器异常,请检查网络或联系管理员`),console.error(`Sdk: defaultResponseInterceptor - Request error:`,n.url,e);return Promise.reject(e)})}getInstance(){return this.instance}};const me={name:`api`,install(e,t={}){let n={baseURL:`/`,timeout:0,...t.config},r=t?.instance||new pe(n).getInstance();e.api=F({config:n,controllers:new Map,instance:null,request:(e,t={})=>r.request({url:e,isOriginalData:!1,isShowFailMsg:!0,isCancelRequest:!0,...t}),getUserInfoApi:()=>e.api.request(`/getUserInfo`,{method:`GET`}),getRoutesApi:()=>e.api.request(`/routes`,{method:`GET`}),loginApi:()=>e.api.request(`/login`,{method:`POST`})},t)}},he={name:`app`,install(e,t={}){e.app=F({menuData:[],allRoutes:[],microApps:[],microAppsInstance:new Map,user:null,permissions:[],roles:[],settings:{},initData:null,clearData:()=>{e.app.menuData=[],e.app.allRoutes=e.app.allRoutes.filter(e=>e.path!==`/`),e.app.microApps=[],e.app.microAppsInstance.forEach(e=>e.unmount()),e.app.microAppsInstance.clear(),e.store.getState().resetInitState()},pageToLogin:()=>{e.storage.clearToken();let t=window.location.pathname||`/`,n=e.config.loginPath,r=t===n?n:`${n}?redirect=${encodeURIComponent(t)}`;e.config.qiankunMode===`router`?window.location.replace(r):(e.app.clearData(),e.client.navigate(r,{replace:!0}))},getRedirectPath:()=>{let t=e.config.defaultPath;if(t)return t;let n=new URLSearchParams(window.location.search);return decodeURIComponent(n.get(`redirect`)||``)||`/`}},t)}},K=`client`,ge={name:K,install(e,t={}){e[K]=F({location:null,navigate:null,matches:null},t)}},q=`config`,_e={name:q,install(e,t={}){e[q]=F({env:{},qiankunMode:`router`,theme:null,locale:null,loginPath:`/login`,defaultPath:``,customRoutes:[],antdConfig:{},proLayoutConfig:{title:`Demo`}},t)}},J=`i18n`,ve={name:J,install(e,t={}){e[J]=F({intl:C,intlConfig:{},loadLocale:e=>void 0},t)}},Y=`storage`,ye={name:Y,install(e,t={}){e[Y]=F({localeKey:`locale`,themeKey:`theme`,tokenKey:`token`,getLocale:()=>localStorage.getItem(e.storage.localeKey),setLocale:t=>{localStorage.setItem(e.storage.localeKey,t)},clearLocale:()=>{localStorage.removeItem(e.storage.localeKey)},getTheme:()=>localStorage.getItem(e.storage.themeKey),setTheme:t=>{localStorage.setItem(e.storage.themeKey,t)},clearTheme:()=>{localStorage.removeItem(e.storage.themeKey)},getToken:()=>localStorage.getItem(e.storage.tokenKey),setToken:t=>{localStorage.setItem(e.storage.tokenKey,t)},clearToken:()=>{localStorage.removeItem(e.storage.tokenKey)}},t)}},X={user:{},permissions:[],roles:[],settings:{}},be=(e,t)=>({initState:X,setInitState:t=>{e(()=>({initState:t})),D.app={...D.app,...t}},resetInitState:()=>{e(()=>({initState:X}))}}),xe=(e,t)=>({locale:null,setLocale:t=>{e(()=>({locale:t})),D.config.locale=t,D.storage.setLocale(t),document.documentElement.setAttribute(`lang`,t);let n=D.i18n.intlConfig;C.init({currentLocale:t,locales:n});try{let e=D.i18n.loadLocale?.(t)||void 0;F(D.config.antdConfig,{locale:e})}catch(e){console.error(`Sdk: createLocaleSlice - sdk.i18n.loadLocale error:`,e)}}}),Se=(e,t)=>({microAppLoading:!1,setMicroAppLoading:t=>e(()=>({microAppLoading:t}))}),{defaultAlgorithm:Ce,darkAlgorithm:we}=S,Te=(e,t)=>({theme:null,setTheme:t=>{e(()=>({theme:t})),D.config.theme=t,D.storage.setTheme(t),document.documentElement.setAttribute(`theme`,t);let n=t===`light`?Ce:we;F(D.config.antdConfig,{theme:{algorithm:n}})}}),Ee=e()(w((...e)=>({...be(...e),...xe(...e),...Se(...e),...Te(...e)}))),Z=`store`,De={name:Z,install(e,t={}){e[Z]=Ee}},Oe=()=>{let e=f(),n=u(),i=d(),a=t(D.store,e=>e.locale),o=i[i.length-1]?.handle?.crumb()||{},s=JSON.parse(o?.routeAttr||`{}`)?.noLayout,c=t=>{e(t.path)};return m(T,{locale:a,formatMessage:({id:e,defaultMessage:t})=>D.i18n.intl.get(e).d(t),location:n,menuItemRender:(e,t)=>m(`div`,{onClick:()=>c(e),children:t}),onMenuHeaderClick:()=>{e(`/`)},onPageChange:e=>{if(!D.app.user||Object.keys(D.app.user).length===0)return D.app.pageToLogin()},...s&&{headerRender:!1,footerRender:!1,menuRender:!1},menu:{request:async()=>D.app.menuData||[],...D.config.proLayoutConfig.menu},...D.config.proLayoutConfig,children:m(r,{fallback:D.ui.renderComponent(`Loading`,{isSuspense:!0}),children:m(l,{})})})},{useToken:Q}=S,ke=({isInitData:e=!1,isSuspense:t=!1,isMicroApp:n=!1})=>{let{token:r}=Q();return m(`div`,{style:e?{width:`100%`,height:`100%`,display:`flex`,alignItems:`center`,justifyContent:`center`,background:r.colorBgContainer,color:r.colorText}:{},children:`Loading...`})},{useToken:Ae}=S,je=()=>{let{token:e}=Ae(),[t,n]=c(!1);return m(v,{style:{width:`100%`,height:`100%`,background:e.colorBgContainer},justify:`center`,align:`center`,children:h(y,{labelCol:{span:8},labelAlign:`left`,wrapperCol:{span:16},style:{maxWidth:600},initialValues:{username:`admin`,password:`admin`},onFinish:async e=>{try{n(()=>!0);let t=await D.api.loginApi(e);n(()=>!1);let r=t?.data?.token||``;if(!r)return;D.storage.setToken(r);let i=D.app.getRedirectPath();D.config.qiankunMode===`load`?(D.client.navigate(i,{replace:!0}),D.app.initData?.()):window.location.replace(i)}catch(e){console.log(`Sdk: Login - handleFinish: `,e),n(()=>!1)}},autoComplete:`off`,children:[m(y.Item,{label:`用户名`,name:`username`,rules:[{required:!0,message:`请输入用户名!`}],children:m(b,{})}),m(y.Item,{label:`密码`,name:`password`,rules:[{required:!0,message:`请输入密码!`}],children:m(b.Password,{})}),m(y.Item,{noStyle:!0,children:m(_,{block:!0,type:`primary`,htmlType:`submit`,loading:t,children:`登录`})})]})})},$=({children:e})=>{let t=u(),n=d(),r=f();return D.client.location=t,D.client.matches=n,D.client.navigate=r,e},Me=()=>{let e=D.config.loginPath,i=D.config.customRoutes,a=D.config.qiankunMode===`router`,l=e=>D.ui.renderComponent(`Loading`,e),u=D.ui.renderComponent(`Layout`),d=D.ui.renderComponent(`Login`),f=D.ui.renderComponent(`NotFound`),p=[{path:e,element:d},{path:`*`,element:f},...i].map(e=>({...e,element:m($,{children:e.element})})),[h,g]=c(!1),[_,v]=c(p),[y,b,x,S,C]=t(D.store,n(e=>[e.locale,e.setLocale,e.theme,e.setTheme,e.setInitState])),w=s(()=>N(D.config.antdConfig),[y,x]),T=(e,t)=>{S(e||V(D)),b(t||H(D))},E=async()=>{try{g(()=>!0);let[{data:e={}},{data:t=[]}]=await Promise.all([D.api.getUserInfoApi(),D.api.getRoutesApi()]);g(()=>!1),C(e);let{theme:n,locale:r}=e?.settings||{};T(n,r);let{microApps:i=[],menuData:o=[]}=de(t);a&&(ie(i,B),ae());let s=G(o),c=[...p,{path:`/`,element:m(ee,{to:s,replace:!0})},{path:`/`,element:m($,{children:u}),children:o,errorElement:f}];v(c),D.app={...D.app,allRoutes:c,microApps:i,menuData:o}}catch(e){console.error(e),g(()=>!1)}};return o(()=>{D.app.initData=E,D.app.allRoutes=p;let t=D.config.customRoutes?.map(e=>e.path),n=window.location.pathname;[e,...t]?.includes(n)?T():E()},[]),m(re,{...w,children:m(r,{fallback:l({isSuspense:!0}),children:h?l({isInitData:!0}):m(te,{router:ne(_,{basename:`/`}),future:{v7_startTransition:!1}})})})};var Ne=a(({name:e,rootId:r})=>{let[i,a]=t(D.store,n(e=>[e.microAppLoading,e.setMicroAppLoading]));return o(()=>{if(!e||D.config.qiankunMode!==`load`)return;let t=D.app.microAppsInstance.get(e);if(t)t?.mount();else{let n=D.app.microApps.find(t=>t.name===e);if(!n)return;a(!0),t=E(n,{},B),t?.mountPromise?.finally(()=>{a(!1)}),D.app.microAppsInstance.set(e,t)}return()=>{t?.unmount()}},[e]),h(p,{children:[i&&D.ui.renderComponent(`Loading`,{isMicroApp:!0}),m(`main`,{id:r})]})});const Pe=()=>m(`div`,{children:`无权限`}),{useToken:Fe}=S,Ie=()=>{let{token:e}=Fe();return m(`div`,{style:{width:`100%`,height:`100%`,display:`flex`,alignItems:`center`,justifyContent:`center`,background:e.colorBgContainer},children:`找不到页面`})},Le={name:`ui`,install(e,t={}){e.ui=F({Layout:Oe,Loading:ke,Login:je,Mainapp:Me,Microapp:Ne,NotFound:Ie,NoPermission:Pe,setComponent:(t,n)=>{if(!t){console.error(`Sdk: SdkUIPlugin - component cannot be empty`);return}let r=n||t.displayName||t.name;if(!r){console.error(`Sdk: SdkUIPlugin - Component name cannot be empty`);return}e.ui[r]=t},getComponent:t=>t?e.ui[t]:(console.error(`Sdk: SdkUIPlugin - Component name cannot be empty`),null),renderComponent:(t,n={})=>{let r=e.ui.getComponent(t);return r?i(r,n):(console.error(`Sdk: SdkUIPlugin - Component ${t} not found`),null)}},t)}};export{me as SdkApiPlugin,he as SdkAppPlugin,ge as SdkClientPlugin,_e as SdkConfigPlugin,ve as SdkI18nPlugin,ye as SdkStoragePlugin,De as SdkStorePlugin,Le as SdkUIPlugin,D as sdk,L as useCrumb,O as useInitState,ue as useIntl,fe as usePermission};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zxiaosi/sdk",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "A micro frontend kit",
5
5
  "keywords": [
6
6
  "micro frontend",
@@ -30,22 +30,22 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@ant-design/pro-layout": "^7.22.7",
33
- "axios": "^1.13.2",
33
+ "axios": "^1.13.6",
34
34
  "qiankun": "^2.10.16",
35
35
  "react-intl-universal": "^2.13.4"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/react": "^18.3.12",
39
39
  "@types/react-dom": "^18.3.1",
40
- "es-toolkit": "^1.43.0",
41
- "tsdown": "^0.21.2",
40
+ "es-toolkit": "^1.45.1",
41
+ "tsdown": "^0.21.4",
42
42
  "typescript": "^5.9.3"
43
43
  },
44
44
  "peerDependencies": {
45
- "antd": "^5.29.1 || ^6.0.0",
45
+ "antd": "^5.29.0 || ^6.0.0",
46
46
  "react": "^18.3.1 || >=19.0.0",
47
47
  "react-dom": "^18.3.1 || >=19.0.0",
48
- "react-router-dom": "^6.30.2",
49
- "zustand": "^5.0.9"
48
+ "react-router-dom": "^6.30.0",
49
+ "zustand": "^5.0.0"
50
50
  }
51
51
  }