@mooljs/plugin-access
Advanced tools
+21
| MIT License | ||
| Copyright (c) 2024 merlinhong | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
+2
-3
| { | ||
| "name": "@mooljs/plugin-access", | ||
| "version": "0.1.0", | ||
| "version": "0.1.1", | ||
| "description": "pro layout access for mooljs", | ||
| "main": "dist/access.mjs", | ||
| "main": "index.js", | ||
| "repository": { | ||
@@ -15,3 +15,2 @@ "type": "git", | ||
| "mooljs", | ||
| "element-plus", | ||
| "access" | ||
@@ -18,0 +17,0 @@ ], |
@@ -0,1 +1,2 @@ | ||
| const {readFileSync} = require('node:fs'); | ||
| module.exports = function virtual(api, options) { | ||
@@ -29,3 +30,3 @@ const virtualModuleIds = ['virturl:access']; | ||
| if(id=="\0virturl:access"){ | ||
| return readFileSync('../dist/access.mjs','utf-8'); | ||
| return readFileSync(api.resolve('node_modules/@mooljs/plugin-access/dist/access.mjs'),'utf-8'); | ||
| } | ||
@@ -32,0 +33,0 @@ }, |
| const p = Symbol("access-context"); | ||
| function d(n, o) { | ||
| for (const e of n) { | ||
| if (e.path === o) | ||
| return [null, e]; | ||
| if (e.routes && e.routes.length > 0) { | ||
| const t = d(e.routes, o); | ||
| if (t) | ||
| return [e, t[1]]; | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| function b(n) { | ||
| var a, f; | ||
| const { to: o, routes: e = [], access: t = {}, exclude: u = ["/user"] } = n, l = (s, c) => c && !s[c], i = d(e, o.path); | ||
| if (i) { | ||
| const [s, c] = i; | ||
| return (l(t, (a = s == null ? void 0 : s.meta) == null ? void 0 : a.access) || l(t, (f = c.meta) == null ? void 0 : f.access)) && !u.some((r) => o.path.includes(r)) && o.path !== "/403"; | ||
| } else | ||
| return !1; | ||
| } | ||
| const P = (n, o) => { | ||
| const { router: e, globalConfig: t } = o ?? {}, { access: u = {}, layout: l = {}, menuRoutes: i = [] } = t; | ||
| n.config.globalProperties.$access = u, n.provide(p, u), e == null || e.addRoute({ | ||
| path: "/403", | ||
| component: null, | ||
| children: l.unAccessible ?? (() => import("@mooljs/plugin-layout/layouts/403.vue")) | ||
| }), e == null || e.beforeEach((a, f, s) => { | ||
| var m; | ||
| const c = (m = i.filter((r) => { | ||
| var h; | ||
| return ((h = r.meta) == null ? void 0 : h.layout) === !1; | ||
| })) == null ? void 0 : m.map((r) => r.path); | ||
| b({ to: a, routes: i, access: u, exclude: c }) ? s("/403") : s(); | ||
| }); | ||
| }; | ||
| export { | ||
| p as ACCESS_KEY, | ||
| P as useAccess | ||
| }; |
| export default (initialState) => { | ||
| const { role } = initialState; | ||
| return { | ||
| hasPermision: role == "admin", | ||
| }; | ||
| }; |
| import { CheckPermissionOptions, IMenuRoutes,UseProviderOptions } from './type'; // 假设type.ts和hooks文件在同一目录 | ||
| import { App, inject } from "vue"; | ||
| export const ACCESS_KEY = Symbol('access-context'); | ||
| function findRouteByPath(routes: IMenuRoutes[], targetPath: string): [IMenuRoutes | null, IMenuRoutes] | null { | ||
| for (const route of routes) { | ||
| if (route.path === targetPath) { | ||
| return [null, route]; | ||
| } | ||
| if (route.routes && route.routes.length > 0) { | ||
| const foundRoute = findRouteByPath(route.routes, targetPath); | ||
| if (foundRoute) { | ||
| return [route, foundRoute[1]]; | ||
| } | ||
| } | ||
| } | ||
| return null; | ||
| }; | ||
| function checkPermision(options: CheckPermissionOptions) { | ||
| const { to, routes = [], access = {}, exclude = ['/user'] } = options; | ||
| // 递归函数,用于深度查询路由 | ||
| const hasNoPermision = (access: Record<string, any>, currAccess?: string) => { | ||
| return currAccess && !access[currAccess]; | ||
| } | ||
| const res = findRouteByPath(routes, to.path); | ||
| if (res) { | ||
| const [parentRoutes, route] = res; | ||
| const noPermission = (hasNoPermision(access, parentRoutes?.meta?.access) || hasNoPermision(access, route.meta?.access)) && !exclude.some(_ => to.path.includes(_)); | ||
| return noPermission && to.path !== '/403' | ||
| } else { | ||
| return false | ||
| } | ||
| } | ||
| export const useAccess = (app:App,options:UseProviderOptions)=>{ | ||
| const { router, globalConfig } = options ?? {}; | ||
| const { access = {},layout = {}, menuRoutes = []} = globalConfig; | ||
| app.config.globalProperties.$access = access; | ||
| app.provide(ACCESS_KEY, access); | ||
| router?.addRoute({ | ||
| path: '/403', | ||
| component:null, | ||
| children:layout.unAccessible ?? (() => import('@mooljs/plugin-layout/layouts/403.vue')) | ||
| }); | ||
| router?.beforeEach((to, from, next) => { | ||
| const exclude = menuRoutes.filter(_ => _.meta?.layout === false)?.map(_ => _.path); | ||
| if (checkPermision({ to, routes: menuRoutes, access, exclude })) { | ||
| next('/403'); | ||
| } else { | ||
| next(); | ||
| } | ||
| }); | ||
| } |
-97
| import { RouteLocationNormalizedGeneric, Router } from 'vue-router'; | ||
| import { App, DefineComponent, VNode } from "vue"; | ||
| type GetInitialStateReturnType<T> = T extends () => infer R ? R : never; | ||
| // 定义全局配置接口 | ||
| export interface RuntimeConfig { | ||
| routes?: IMenuRoutes[]; | ||
| layout?: ILayout | ((option: GetInitialStateReturnType<RuntimeConfig['getInitialState']>) => LayoutConfig); | ||
| getInitialState?: () => (Record<string, any> | Promise<Record<string, any>>); | ||
| } | ||
| // 定义路由配置接口 | ||
| export interface IMenuRoutes { | ||
| path: string; | ||
| /** | ||
| * 当前页面渲染的组件,must be a absolute path | ||
| */ | ||
| component?: string; | ||
| meta?: RouteMeta; | ||
| routes?: IMenuRoutes[]; | ||
| } | ||
| // 定义路由元数据接口 | ||
| export interface RouteMeta { | ||
| /** | ||
| * 是否在菜单中隐藏 | ||
| */ | ||
| hideInMenu?: boolean; | ||
| /** | ||
| * 是否在菜单中隐藏其子节点 | ||
| */ | ||
| hideChildrenInMenu?: boolean; | ||
| /** | ||
| * 是否渲染菜单 | ||
| */ | ||
| menuRender?: boolean; | ||
| /** | ||
| * 是否渲染页脚 | ||
| */ | ||
| footerRender?: boolean; | ||
| /** | ||
| * 是否渲染头部 | ||
| */ | ||
| headerRender?: boolean; | ||
| /** | ||
| * 当前路由是否使用内置pro layout | ||
| */ | ||
| layout?: boolean; | ||
| /** | ||
| * 权限相关设置 | ||
| */ | ||
| access?: string; | ||
| /** | ||
| * 是否打平菜单 | ||
| */ | ||
| flatMenu?: boolean; | ||
| /** | ||
| * 当前菜单icon | ||
| */ | ||
| icon?: string; | ||
| /** | ||
| * 菜单或当前页面标题 | ||
| */ | ||
| title: string; | ||
| } | ||
| export interface ILayout { | ||
| headerRender?: DefineComponent<{},{},any> | (() => VNode); | ||
| footerRender?: DefineComponent<{},{},any> | (() => VNode); | ||
| rightRender?: DefineComponent<{},{},any> | (() => VNode); | ||
| unAccessible?: DefineComponent<{},{},any> | (() => VNode); | ||
| noFound?: DefineComponent<{},{},any> | (() => VNode); | ||
| logout?: DefineComponent<{},{},any> | (() => VNode); | ||
| } | ||
| // 定义布局配置接口 | ||
| export interface LayoutConfig extends ILayout { | ||
| menu?: { | ||
| request?: () => Promise<IMenuRoutes[]>; | ||
| }; | ||
| } | ||
| // 定义权限检查函数的参数类型 | ||
| export interface CheckPermissionOptions { | ||
| to: RouteLocationNormalizedGeneric; | ||
| routes: IMenuRoutes[]; | ||
| access?: Record<string, any>; | ||
| exclude?: string[]; | ||
| } | ||
| // 定义useProvider函数的参数类型 | ||
| export interface UseProviderOptions { | ||
| globalConfig: { layout: LayoutConfig,initialState?:Record<string, any>, menuRoutes: IMenuRoutes[], access?: Record<string, any> }; | ||
| router?: Router; | ||
| } |
| // vite.config.js | ||
| import { resolve } from 'path' | ||
| import { defineConfig } from 'vite' | ||
| export default defineConfig({ | ||
| build: { | ||
| lib: { | ||
| entry: resolve(__dirname, 'src/access.ts'), | ||
| name: 'access', | ||
| fileName: 'access', | ||
| formats:['es'] | ||
| }, | ||
| rollupOptions: { | ||
| // 确保外部化处理那些你不想打包进库的依赖 | ||
| external: ['vue','vue-router','@mooljs/plugin-layout/layouts/403.vue'], | ||
| // output: { | ||
| // // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量 | ||
| // globals: { | ||
| // vue: 'Vue', | ||
| // }, | ||
| // }, | ||
| }, | ||
| }, | ||
| }) |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
3259
-64.34%5
-44.44%48
-81.1%1
Infinity%