🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@dlymon/utils

Package Overview
Dependencies
Maintainers
2
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@dlymon/utils - npm Package Compare versions

Comparing version
8.0.0
to
9.0.0
+27
dist/helpers/find-menu-by-path.cjs
'use strict';
function findMenuByPath(list, path) {
for (const menu of list) {
if (menu.path === path) {
return menu;
}
const findMenu = menu.children && findMenuByPath(menu.children, path);
if (findMenu) {
return findMenu;
}
}
return null;
}
function findRootMenuByPath(menus, path, level = 0) {
const findMenu = findMenuByPath(menus, path);
const rootMenuPath = findMenu?.parents?.[level];
const rootMenu = rootMenuPath ? menus.find((item) => item.path === rootMenuPath) : void 0;
return {
findMenu,
rootMenu,
rootMenuPath
};
}
exports.findMenuByPath = findMenuByPath;
exports.findRootMenuByPath = findRootMenuByPath;
import { MenuRecordRaw } from '@dlymon-core/typings';
declare function findMenuByPath(list: MenuRecordRaw[], path?: string): MenuRecordRaw | null;
declare function findRootMenuByPath(menus: MenuRecordRaw[], path?: string, level?: number): {
findMenu: MenuRecordRaw | null;
rootMenu: MenuRecordRaw | undefined;
rootMenuPath: string | undefined;
};
export { findMenuByPath, findRootMenuByPath };
import { MenuRecordRaw } from '@dlymon-core/typings';
declare function findMenuByPath(list: MenuRecordRaw[], path?: string): MenuRecordRaw | null;
declare function findRootMenuByPath(menus: MenuRecordRaw[], path?: string, level?: number): {
findMenu: MenuRecordRaw | null;
rootMenu: MenuRecordRaw | undefined;
rootMenuPath: string | undefined;
};
export { findMenuByPath, findRootMenuByPath };
import { MenuRecordRaw } from '@dlymon-core/typings';
declare function findMenuByPath(list: MenuRecordRaw[], path?: string): MenuRecordRaw | null;
declare function findRootMenuByPath(menus: MenuRecordRaw[], path?: string, level?: number): {
findMenu: MenuRecordRaw | null;
rootMenu: MenuRecordRaw | undefined;
rootMenuPath: string | undefined;
};
export { findMenuByPath, findRootMenuByPath };
function findMenuByPath(list, path) {
for (const menu of list) {
if (menu.path === path) {
return menu;
}
const findMenu = menu.children && findMenuByPath(menu.children, path);
if (findMenu) {
return findMenu;
}
}
return null;
}
function findRootMenuByPath(menus, path, level = 0) {
const findMenu = findMenuByPath(menus, path);
const rootMenuPath = findMenu?.parents?.[level];
const rootMenu = rootMenuPath ? menus.find((item) => item.path === rootMenuPath) : void 0;
return {
findMenu,
rootMenu,
rootMenuPath
};
}
export { findMenuByPath, findRootMenuByPath };
'use strict';
const utils = require('@dlymon-core/shared/utils');
function generateMenus(routes, router) {
const finalRoutesMap = Object.fromEntries(
router.getRoutes().map(({ name, path }) => [name, path])
);
let menus = utils.mapTree(routes, (route) => {
const path = finalRoutesMap[route.name] ?? route.path ?? "";
const {
meta = {},
name: routeName,
redirect,
children = []
} = route;
const {
activeIcon,
badge,
badgeType,
badgeVariants,
hideChildrenInMenu = false,
icon,
link,
order,
title = ""
} = meta;
const name = title || routeName || "";
const resultChildren = hideChildrenInMenu ? [] : children ?? [];
if (resultChildren.length > 0) {
resultChildren.forEach((child) => {
child.parents = [...route.parents ?? [], path];
child.parent = path;
});
}
const resultPath = hideChildrenInMenu ? redirect || path : link || path;
return {
activeIcon,
badge,
badgeType,
badgeVariants,
icon,
name,
order,
parent: route.parent,
parents: route.parents,
path: resultPath,
show: !meta.hideInMenu,
children: resultChildren
};
});
menus = menus.sort((a, b) => (a?.order ?? 999) - (b?.order ?? 999));
return utils.filterTree(menus, (menu) => !!menu.show);
}
exports.generateMenus = generateMenus;
import { RouteRecordRaw, Router } from 'vue-router';
import { MenuRecordRaw } from '@dlymon-core/typings';
declare function generateMenus(routes: RouteRecordRaw[], router: Router): MenuRecordRaw[];
export { generateMenus };
import { RouteRecordRaw, Router } from 'vue-router';
import { MenuRecordRaw } from '@dlymon-core/typings';
declare function generateMenus(routes: RouteRecordRaw[], router: Router): MenuRecordRaw[];
export { generateMenus };
import { RouteRecordRaw, Router } from 'vue-router';
import { MenuRecordRaw } from '@dlymon-core/typings';
declare function generateMenus(routes: RouteRecordRaw[], router: Router): MenuRecordRaw[];
export { generateMenus };
import { mapTree, filterTree } from '@dlymon-core/shared/utils';
function generateMenus(routes, router) {
const finalRoutesMap = Object.fromEntries(
router.getRoutes().map(({ name, path }) => [name, path])
);
let menus = mapTree(routes, (route) => {
const path = finalRoutesMap[route.name] ?? route.path ?? "";
const {
meta = {},
name: routeName,
redirect,
children = []
} = route;
const {
activeIcon,
badge,
badgeType,
badgeVariants,
hideChildrenInMenu = false,
icon,
link,
order,
title = ""
} = meta;
const name = title || routeName || "";
const resultChildren = hideChildrenInMenu ? [] : children ?? [];
if (resultChildren.length > 0) {
resultChildren.forEach((child) => {
child.parents = [...route.parents ?? [], path];
child.parent = path;
});
}
const resultPath = hideChildrenInMenu ? redirect || path : link || path;
return {
activeIcon,
badge,
badgeType,
badgeVariants,
icon,
name,
order,
parent: route.parent,
parents: route.parents,
path: resultPath,
show: !meta.hideInMenu,
children: resultChildren
};
});
menus = menus.sort((a, b) => (a?.order ?? 999) - (b?.order ?? 999));
return filterTree(menus, (menu) => !!menu.show);
}
export { generateMenus };
'use strict';
const utils = require('@dlymon-core/shared/utils');
async function generateRoutesByBackend(options) {
const { fetchMenuListAsync, layoutMap = {}, pageMap = {} } = options;
try {
const menuRoutes = await fetchMenuListAsync?.();
if (!menuRoutes) {
return [];
}
const normalizePageMap = {};
for (const [key, value] of Object.entries(pageMap)) {
normalizePageMap[normalizeViewPath(key)] = value;
}
const routes = convertRoutes(menuRoutes, layoutMap, normalizePageMap);
return routes;
} catch (error) {
console.error(error);
throw error;
}
}
function convertRoutes(routes, layoutMap, pageMap) {
return utils.mapTree(routes, (node) => {
const route = node;
const { component, name } = node;
if (!name) {
console.error("route name is required", route);
}
if (component && layoutMap[component]) {
route.component = layoutMap[component];
} else if (component) {
const normalizePath = normalizeViewPath(component);
const pageKey = normalizePath.endsWith(".vue") ? normalizePath : `${normalizePath}.vue`;
if (pageMap[pageKey]) {
route.component = pageMap[pageKey];
} else {
console.error(`route component is invalid: ${pageKey}`, route);
route.component = pageMap["/_core/fallback/not-found.vue"];
}
}
return route;
});
}
function normalizeViewPath(path) {
const normalizedPath = path.replace(/^(\.\/|\.\.\/)+/, "");
const viewPath = normalizedPath.startsWith("/") ? normalizedPath : `/${normalizedPath}`;
return viewPath.replace(/^\/views/, "");
}
exports.generateRoutesByBackend = generateRoutesByBackend;
import { RouteRecordRaw } from 'vue-router';
import { GenerateMenuAndRoutesOptions } from '@dlymon-core/typings';
declare function generateRoutesByBackend(options: GenerateMenuAndRoutesOptions): Promise<RouteRecordRaw[]>;
export { generateRoutesByBackend };
import { RouteRecordRaw } from 'vue-router';
import { GenerateMenuAndRoutesOptions } from '@dlymon-core/typings';
declare function generateRoutesByBackend(options: GenerateMenuAndRoutesOptions): Promise<RouteRecordRaw[]>;
export { generateRoutesByBackend };
import { RouteRecordRaw } from 'vue-router';
import { GenerateMenuAndRoutesOptions } from '@dlymon-core/typings';
declare function generateRoutesByBackend(options: GenerateMenuAndRoutesOptions): Promise<RouteRecordRaw[]>;
export { generateRoutesByBackend };
import { mapTree } from '@dlymon-core/shared/utils';
async function generateRoutesByBackend(options) {
const { fetchMenuListAsync, layoutMap = {}, pageMap = {} } = options;
try {
const menuRoutes = await fetchMenuListAsync?.();
if (!menuRoutes) {
return [];
}
const normalizePageMap = {};
for (const [key, value] of Object.entries(pageMap)) {
normalizePageMap[normalizeViewPath(key)] = value;
}
const routes = convertRoutes(menuRoutes, layoutMap, normalizePageMap);
return routes;
} catch (error) {
console.error(error);
throw error;
}
}
function convertRoutes(routes, layoutMap, pageMap) {
return mapTree(routes, (node) => {
const route = node;
const { component, name } = node;
if (!name) {
console.error("route name is required", route);
}
if (component && layoutMap[component]) {
route.component = layoutMap[component];
} else if (component) {
const normalizePath = normalizeViewPath(component);
const pageKey = normalizePath.endsWith(".vue") ? normalizePath : `${normalizePath}.vue`;
if (pageMap[pageKey]) {
route.component = pageMap[pageKey];
} else {
console.error(`route component is invalid: ${pageKey}`, route);
route.component = pageMap["/_core/fallback/not-found.vue"];
}
}
return route;
});
}
function normalizeViewPath(path) {
const normalizedPath = path.replace(/^(\.\/|\.\.\/)+/, "");
const viewPath = normalizedPath.startsWith("/") ? normalizedPath : `/${normalizedPath}`;
return viewPath.replace(/^\/views/, "");
}
export { generateRoutesByBackend };
'use strict';
const utils = require('@dlymon-core/shared/utils');
async function generateRoutesByFrontend(routes, roles, forbiddenComponent) {
const finalRoutes = utils.filterTree(routes, (route) => {
return hasAuthority(route, roles);
});
if (!forbiddenComponent) {
return finalRoutes;
}
return utils.mapTree(finalRoutes, (route) => {
if (menuHasVisibleWithForbidden(route)) {
route.component = forbiddenComponent;
}
return route;
});
}
function hasAuthority(route, access) {
const authority = route.meta?.authority;
if (!authority) {
return true;
}
const canAccess = access.some((value) => authority.includes(value));
return canAccess || !canAccess && menuHasVisibleWithForbidden(route);
}
function menuHasVisibleWithForbidden(route) {
return !!route.meta?.authority && Reflect.has(route.meta || {}, "menuVisibleWithForbidden") && !!route.meta?.menuVisibleWithForbidden;
}
exports.generateRoutesByFrontend = generateRoutesByFrontend;
exports.hasAuthority = hasAuthority;
import { RouteRecordRaw } from 'vue-router';
declare function generateRoutesByFrontend(routes: RouteRecordRaw[], roles: string[], forbiddenComponent?: RouteRecordRaw['component']): Promise<RouteRecordRaw[]>;
declare function hasAuthority(route: RouteRecordRaw, access: string[]): boolean;
export { generateRoutesByFrontend, hasAuthority };
import { RouteRecordRaw } from 'vue-router';
declare function generateRoutesByFrontend(routes: RouteRecordRaw[], roles: string[], forbiddenComponent?: RouteRecordRaw['component']): Promise<RouteRecordRaw[]>;
declare function hasAuthority(route: RouteRecordRaw, access: string[]): boolean;
export { generateRoutesByFrontend, hasAuthority };
import { RouteRecordRaw } from 'vue-router';
declare function generateRoutesByFrontend(routes: RouteRecordRaw[], roles: string[], forbiddenComponent?: RouteRecordRaw['component']): Promise<RouteRecordRaw[]>;
declare function hasAuthority(route: RouteRecordRaw, access: string[]): boolean;
export { generateRoutesByFrontend, hasAuthority };
import { filterTree, mapTree } from '@dlymon-core/shared/utils';
async function generateRoutesByFrontend(routes, roles, forbiddenComponent) {
const finalRoutes = filterTree(routes, (route) => {
return hasAuthority(route, roles);
});
if (!forbiddenComponent) {
return finalRoutes;
}
return mapTree(finalRoutes, (route) => {
if (menuHasVisibleWithForbidden(route)) {
route.component = forbiddenComponent;
}
return route;
});
}
function hasAuthority(route, access) {
const authority = route.meta?.authority;
if (!authority) {
return true;
}
const canAccess = access.some((value) => authority.includes(value));
return canAccess || !canAccess && menuHasVisibleWithForbidden(route);
}
function menuHasVisibleWithForbidden(route) {
return !!route.meta?.authority && Reflect.has(route.meta || {}, "menuVisibleWithForbidden") && !!route.meta?.menuVisibleWithForbidden;
}
export { generateRoutesByFrontend, hasAuthority };
'use strict';
function getPopupContainer(node) {
return node?.closest("form") ?? node?.parentNode ?? document.body;
}
exports.getPopupContainer = getPopupContainer;
declare function getPopupContainer(node?: HTMLElement): HTMLElement;
export { getPopupContainer };
declare function getPopupContainer(node?: HTMLElement): HTMLElement;
export { getPopupContainer };
declare function getPopupContainer(node?: HTMLElement): HTMLElement;
export { getPopupContainer };
function getPopupContainer(node) {
return node?.closest("form") ?? node?.parentNode ?? document.body;
}
export { getPopupContainer };
'use strict';
const helpers_findMenuByPath = require('./find-menu-by-path.cjs');
const helpers_generateMenus = require('./generate-menus.cjs');
const helpers_generateRoutesBackend = require('./generate-routes-backend.cjs');
const helpers_generateRoutesFrontend = require('./generate-routes-frontend.cjs');
const helpers_getPopupContainer = require('./get-popup-container.cjs');
const helpers_mergeRouteModules = require('./merge-route-modules.cjs');
const helpers_resetRoutes = require('./reset-routes.cjs');
const helpers_unmountGlobalLoading = require('./unmount-global-loading.cjs');
require('@dlymon-core/shared/utils');
exports.findMenuByPath = helpers_findMenuByPath.findMenuByPath;
exports.findRootMenuByPath = helpers_findMenuByPath.findRootMenuByPath;
exports.generateMenus = helpers_generateMenus.generateMenus;
exports.generateRoutesByBackend = helpers_generateRoutesBackend.generateRoutesByBackend;
exports.generateRoutesByFrontend = helpers_generateRoutesFrontend.generateRoutesByFrontend;
exports.hasAuthority = helpers_generateRoutesFrontend.hasAuthority;
exports.getPopupContainer = helpers_getPopupContainer.getPopupContainer;
exports.mergeRouteModules = helpers_mergeRouteModules.mergeRouteModules;
exports.resetStaticRoutes = helpers_resetRoutes.resetStaticRoutes;
exports.unmountGlobalLoading = helpers_unmountGlobalLoading.unmountGlobalLoading;
export { findMenuByPath, findRootMenuByPath } from './find-menu-by-path.cjs';
export { generateMenus } from './generate-menus.cjs';
export { generateRoutesByBackend } from './generate-routes-backend.cjs';
export { generateRoutesByFrontend, hasAuthority } from './generate-routes-frontend.cjs';
export { getPopupContainer } from './get-popup-container.cjs';
export { RouteModuleType, mergeRouteModules } from './merge-route-modules.cjs';
export { resetStaticRoutes } from './reset-routes.cjs';
export { unmountGlobalLoading } from './unmount-global-loading.cjs';
import '@dlymon-core/shared/cache';
import '@dlymon-core/shared/color';
import '@dlymon-core/shared/utils';
import '@dlymon-core/typings';
import 'vue-router';
export { findMenuByPath, findRootMenuByPath } from './find-menu-by-path.mjs';
export { generateMenus } from './generate-menus.mjs';
export { generateRoutesByBackend } from './generate-routes-backend.mjs';
export { generateRoutesByFrontend, hasAuthority } from './generate-routes-frontend.mjs';
export { getPopupContainer } from './get-popup-container.mjs';
export { RouteModuleType, mergeRouteModules } from './merge-route-modules.mjs';
export { resetStaticRoutes } from './reset-routes.mjs';
export { unmountGlobalLoading } from './unmount-global-loading.mjs';
import '@dlymon-core/shared/cache';
import '@dlymon-core/shared/color';
import '@dlymon-core/shared/utils';
import '@dlymon-core/typings';
import 'vue-router';
export { findMenuByPath, findRootMenuByPath } from './find-menu-by-path.js';
export { generateMenus } from './generate-menus.js';
export { generateRoutesByBackend } from './generate-routes-backend.js';
export { generateRoutesByFrontend, hasAuthority } from './generate-routes-frontend.js';
export { getPopupContainer } from './get-popup-container.js';
export { RouteModuleType, mergeRouteModules } from './merge-route-modules.js';
export { resetStaticRoutes } from './reset-routes.js';
export { unmountGlobalLoading } from './unmount-global-loading.js';
import '@dlymon-core/shared/cache';
import '@dlymon-core/shared/color';
import '@dlymon-core/shared/utils';
import '@dlymon-core/typings';
import 'vue-router';
export { findMenuByPath, findRootMenuByPath } from './find-menu-by-path.mjs';
export { generateMenus } from './generate-menus.mjs';
export { generateRoutesByBackend } from './generate-routes-backend.mjs';
export { generateRoutesByFrontend, hasAuthority } from './generate-routes-frontend.mjs';
export { getPopupContainer } from './get-popup-container.mjs';
export { mergeRouteModules } from './merge-route-modules.mjs';
export { resetStaticRoutes } from './reset-routes.mjs';
export { unmountGlobalLoading } from './unmount-global-loading.mjs';
import '@dlymon-core/shared/utils';
'use strict';
function mergeRouteModules(routeModules) {
const mergedRoutes = [];
for (const routeModule of Object.values(routeModules)) {
const moduleRoutes = routeModule?.default ?? [];
mergedRoutes.push(...moduleRoutes);
}
return mergedRoutes;
}
exports.mergeRouteModules = mergeRouteModules;
import { RouteRecordRaw } from 'vue-router';
interface RouteModuleType {
default: RouteRecordRaw[];
}
declare function mergeRouteModules(routeModules: Record<string, unknown>): RouteRecordRaw[];
export { mergeRouteModules };
export type { RouteModuleType };
import { RouteRecordRaw } from 'vue-router';
interface RouteModuleType {
default: RouteRecordRaw[];
}
declare function mergeRouteModules(routeModules: Record<string, unknown>): RouteRecordRaw[];
export { mergeRouteModules };
export type { RouteModuleType };
import { RouteRecordRaw } from 'vue-router';
interface RouteModuleType {
default: RouteRecordRaw[];
}
declare function mergeRouteModules(routeModules: Record<string, unknown>): RouteRecordRaw[];
export { mergeRouteModules };
export type { RouteModuleType };
function mergeRouteModules(routeModules) {
const mergedRoutes = [];
for (const routeModule of Object.values(routeModules)) {
const moduleRoutes = routeModule?.default ?? [];
mergedRoutes.push(...moduleRoutes);
}
return mergedRoutes;
}
export { mergeRouteModules };
'use strict';
const utils = require('@dlymon-core/shared/utils');
function resetStaticRoutes(router, routes) {
const staticRouteNames = utils.traverseTreeValues(routes, (route) => {
if (!route.name) {
console.warn(
`The route with the path ${route.path} needs to have the field name specified.`
);
}
return route.name;
});
const { getRoutes, hasRoute, removeRoute } = router;
const allRoutes = getRoutes();
allRoutes.forEach(({ name }) => {
if (name && !staticRouteNames.includes(name) && hasRoute(name)) {
removeRoute(name);
}
});
}
exports.resetStaticRoutes = resetStaticRoutes;
import { Router, RouteRecordRaw } from 'vue-router';
declare function resetStaticRoutes(router: Router, routes: RouteRecordRaw[]): void;
export { resetStaticRoutes };
import { Router, RouteRecordRaw } from 'vue-router';
declare function resetStaticRoutes(router: Router, routes: RouteRecordRaw[]): void;
export { resetStaticRoutes };
import { Router, RouteRecordRaw } from 'vue-router';
declare function resetStaticRoutes(router: Router, routes: RouteRecordRaw[]): void;
export { resetStaticRoutes };
import { traverseTreeValues } from '@dlymon-core/shared/utils';
function resetStaticRoutes(router, routes) {
const staticRouteNames = traverseTreeValues(routes, (route) => {
if (!route.name) {
console.warn(
`The route with the path ${route.path} needs to have the field name specified.`
);
}
return route.name;
});
const { getRoutes, hasRoute, removeRoute } = router;
const allRoutes = getRoutes();
allRoutes.forEach(({ name }) => {
if (name && !staticRouteNames.includes(name) && hasRoute(name)) {
removeRoute(name);
}
});
}
export { resetStaticRoutes };
'use strict';
function unmountGlobalLoading() {
const loadingElement = document.querySelector("#__app-loading__");
if (loadingElement) {
loadingElement.classList.add("hidden");
const injectLoadingElements = document.querySelectorAll(
'[data-app-loading^="inject"]'
);
loadingElement.addEventListener(
"transitionend",
() => {
loadingElement.remove();
injectLoadingElements.forEach((el) => el.remove());
},
{ once: true }
);
}
}
exports.unmountGlobalLoading = unmountGlobalLoading;
declare function unmountGlobalLoading(): void;
export { unmountGlobalLoading };
declare function unmountGlobalLoading(): void;
export { unmountGlobalLoading };
declare function unmountGlobalLoading(): void;
export { unmountGlobalLoading };
function unmountGlobalLoading() {
const loadingElement = document.querySelector("#__app-loading__");
if (loadingElement) {
loadingElement.classList.add("hidden");
const injectLoadingElements = document.querySelectorAll(
'[data-app-loading^="inject"]'
);
loadingElement.addEventListener(
"transitionend",
() => {
loadingElement.remove();
injectLoadingElements.forEach((el) => el.remove());
},
{ once: true }
);
}
}
export { unmountGlobalLoading };
+36
-221

@@ -6,237 +6,52 @@ 'use strict';

const utils = require('@dlymon-core/shared/utils');
const helpers_findMenuByPath = require('./helpers/find-menu-by-path.cjs');
const helpers_generateMenus = require('./helpers/generate-menus.cjs');
const helpers_generateRoutesBackend = require('./helpers/generate-routes-backend.cjs');
const helpers_generateRoutesFrontend = require('./helpers/generate-routes-frontend.cjs');
const helpers_getPopupContainer = require('./helpers/get-popup-container.cjs');
const helpers_mergeRouteModules = require('./helpers/merge-route-modules.cjs');
const helpers_resetRoutes = require('./helpers/reset-routes.cjs');
const helpers_unmountGlobalLoading = require('./helpers/unmount-global-loading.cjs');
function findMenuByPath(list, path) {
for (const menu of list) {
if (menu.path === path) {
return menu;
}
const findMenu = menu.children && findMenuByPath(menu.children, path);
if (findMenu) {
return findMenu;
}
}
return null;
}
function findRootMenuByPath(menus, path, level = 0) {
const findMenu = findMenuByPath(menus, path);
const rootMenuPath = findMenu?.parents?.[level];
const rootMenu = rootMenuPath ? menus.find((item) => item.path === rootMenuPath) : void 0;
return {
findMenu,
rootMenu,
rootMenuPath
};
}
function generateMenus(routes, router) {
const finalRoutesMap = Object.fromEntries(
router.getRoutes().map(({ name, path }) => [name, path])
);
let menus = utils.mapTree(routes, (route) => {
const path = finalRoutesMap[route.name] ?? route.path ?? "";
const {
meta = {},
name: routeName,
redirect,
children = []
} = route;
const {
activeIcon,
badge,
badgeType,
badgeVariants,
hideChildrenInMenu = false,
icon,
link,
order,
title = ""
} = meta;
const name = title || routeName || "";
const resultChildren = hideChildrenInMenu ? [] : children ?? [];
if (resultChildren.length > 0) {
resultChildren.forEach((child) => {
child.parents = [...route.parents ?? [], path];
child.parent = path;
});
}
const resultPath = hideChildrenInMenu ? redirect || path : link || path;
return {
activeIcon,
badge,
badgeType,
badgeVariants,
icon,
name,
order,
parent: route.parent,
parents: route.parents,
path: resultPath,
show: !meta.hideInMenu,
children: resultChildren
};
});
menus = menus.sort((a, b) => (a?.order ?? 999) - (b?.order ?? 999));
return utils.filterTree(menus, (menu) => !!menu.show);
}
async function generateRoutesByBackend(options) {
const { fetchMenuListAsync, layoutMap = {}, pageMap = {} } = options;
try {
const menuRoutes = await fetchMenuListAsync?.();
if (!menuRoutes) {
return [];
}
const normalizePageMap = {};
for (const [key, value] of Object.entries(pageMap)) {
normalizePageMap[normalizeViewPath(key)] = value;
}
const routes = convertRoutes(menuRoutes, layoutMap, normalizePageMap);
return routes;
} catch (error) {
console.error(error);
throw error;
}
}
function convertRoutes(routes, layoutMap, pageMap) {
return utils.mapTree(routes, (node) => {
const route = node;
const { component, name } = node;
if (!name) {
console.error("route name is required", route);
}
if (component && layoutMap[component]) {
route.component = layoutMap[component];
} else if (component) {
const normalizePath = normalizeViewPath(component);
const pageKey = normalizePath.endsWith(".vue") ? normalizePath : `${normalizePath}.vue`;
if (pageMap[pageKey]) {
route.component = pageMap[pageKey];
} else {
console.error(`route component is invalid: ${pageKey}`, route);
route.component = pageMap["/_core/fallback/not-found.vue"];
}
}
return route;
});
}
function normalizeViewPath(path) {
const normalizedPath = path.replace(/^(\.\/|\.\.\/)+/, "");
const viewPath = normalizedPath.startsWith("/") ? normalizedPath : `/${normalizedPath}`;
return viewPath.replace(/^\/views/, "");
}
async function generateRoutesByFrontend(routes, roles, forbiddenComponent) {
const finalRoutes = utils.filterTree(routes, (route) => {
return hasAuthority(route, roles);
});
if (!forbiddenComponent) {
return finalRoutes;
}
return utils.mapTree(finalRoutes, (route) => {
if (menuHasVisibleWithForbidden(route)) {
route.component = forbiddenComponent;
}
return route;
});
}
function hasAuthority(route, access) {
const authority = route.meta?.authority;
if (!authority) {
return true;
}
const canAccess = access.some((value) => authority.includes(value));
return canAccess || !canAccess && menuHasVisibleWithForbidden(route);
}
function menuHasVisibleWithForbidden(route) {
return !!route.meta?.authority && Reflect.has(route.meta || {}, "menuVisibleWithForbidden") && !!route.meta?.menuVisibleWithForbidden;
}
function getPopupContainer(node) {
return node?.closest("form") ?? node?.parentNode ?? document.body;
}
function mergeRouteModules(routeModules) {
const mergedRoutes = [];
for (const routeModule of Object.values(routeModules)) {
const moduleRoutes = routeModule?.default ?? [];
mergedRoutes.push(...moduleRoutes);
}
return mergedRoutes;
}
function resetStaticRoutes(router, routes) {
const staticRouteNames = utils.traverseTreeValues(routes, (route) => {
if (!route.name) {
console.warn(
`The route with the path ${route.path} needs to have the field name specified.`
);
}
return route.name;
});
const { getRoutes, hasRoute, removeRoute } = router;
const allRoutes = getRoutes();
allRoutes.forEach(({ name }) => {
if (name && !staticRouteNames.includes(name) && hasRoute(name)) {
removeRoute(name);
}
});
}
function unmountGlobalLoading() {
const loadingElement = document.querySelector("#__app-loading__");
if (loadingElement) {
loadingElement.classList.add("hidden");
const injectLoadingElements = document.querySelectorAll(
'[data-app-loading^="inject"]'
);
loadingElement.addEventListener(
"transitionend",
() => {
loadingElement.remove();
injectLoadingElements.forEach((el) => el.remove());
},
{ once: true }
);
}
}
exports.findMenuByPath = findMenuByPath;
exports.findRootMenuByPath = findRootMenuByPath;
exports.generateMenus = generateMenus;
exports.generateRoutesByBackend = generateRoutesByBackend;
exports.generateRoutesByFrontend = generateRoutesByFrontend;
exports.getPopupContainer = getPopupContainer;
exports.hasAuthority = hasAuthority;
exports.mergeRouteModules = mergeRouteModules;
exports.resetStaticRoutes = resetStaticRoutes;
exports.unmountGlobalLoading = unmountGlobalLoading;
exports.findMenuByPath = helpers_findMenuByPath.findMenuByPath;
exports.findRootMenuByPath = helpers_findMenuByPath.findRootMenuByPath;
exports.generateMenus = helpers_generateMenus.generateMenus;
exports.generateRoutesByBackend = helpers_generateRoutesBackend.generateRoutesByBackend;
exports.generateRoutesByFrontend = helpers_generateRoutesFrontend.generateRoutesByFrontend;
exports.hasAuthority = helpers_generateRoutesFrontend.hasAuthority;
exports.getPopupContainer = helpers_getPopupContainer.getPopupContainer;
exports.mergeRouteModules = helpers_mergeRouteModules.mergeRouteModules;
exports.resetStaticRoutes = helpers_resetRoutes.resetStaticRoutes;
exports.unmountGlobalLoading = helpers_unmountGlobalLoading.unmountGlobalLoading;
Object.prototype.hasOwnProperty.call(cache, '__proto__') &&
!Object.prototype.hasOwnProperty.call(exports, '__proto__') &&
Object.defineProperty(exports, '__proto__', {
enumerable: true,
value: cache['__proto__']
});
!Object.prototype.hasOwnProperty.call(exports, '__proto__') &&
Object.defineProperty(exports, '__proto__', {
enumerable: true,
value: cache['__proto__']
});
Object.keys(cache).forEach(function (k) {
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = cache[k];
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = cache[k];
});
Object.prototype.hasOwnProperty.call(color, '__proto__') &&
!Object.prototype.hasOwnProperty.call(exports, '__proto__') &&
Object.defineProperty(exports, '__proto__', {
enumerable: true,
value: color['__proto__']
});
!Object.prototype.hasOwnProperty.call(exports, '__proto__') &&
Object.defineProperty(exports, '__proto__', {
enumerable: true,
value: color['__proto__']
});
Object.keys(color).forEach(function (k) {
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = color[k];
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = color[k];
});
Object.prototype.hasOwnProperty.call(utils, '__proto__') &&
!Object.prototype.hasOwnProperty.call(exports, '__proto__') &&
Object.defineProperty(exports, '__proto__', {
enumerable: true,
value: utils['__proto__']
});
!Object.prototype.hasOwnProperty.call(exports, '__proto__') &&
Object.defineProperty(exports, '__proto__', {
enumerable: true,
value: utils['__proto__']
});
Object.keys(utils).forEach(function (k) {
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = utils[k];
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = utils[k];
});

@@ -1,33 +0,13 @@

import { MenuRecordRaw, GenerateMenuAndRoutesOptions } from '@dlymon-core/typings';
import { RouteRecordRaw, Router } from 'vue-router';
export * from '@dlymon-core/shared/cache';
export * from '@dlymon-core/shared/color';
export * from '@dlymon-core/shared/utils';
declare function findMenuByPath(list: MenuRecordRaw[], path?: string): MenuRecordRaw | null;
declare function findRootMenuByPath(menus: MenuRecordRaw[], path?: string, level?: number): {
findMenu: MenuRecordRaw | null;
rootMenu: MenuRecordRaw | undefined;
rootMenuPath: string | undefined;
};
declare function generateMenus(routes: RouteRecordRaw[], router: Router): MenuRecordRaw[];
declare function generateRoutesByBackend(options: GenerateMenuAndRoutesOptions): Promise<RouteRecordRaw[]>;
declare function generateRoutesByFrontend(routes: RouteRecordRaw[], roles: string[], forbiddenComponent?: RouteRecordRaw['component']): Promise<RouteRecordRaw[]>;
declare function hasAuthority(route: RouteRecordRaw, access: string[]): boolean;
declare function getPopupContainer(node?: HTMLElement): HTMLElement;
interface RouteModuleType {
default: RouteRecordRaw[];
}
declare function mergeRouteModules(routeModules: Record<string, unknown>): RouteRecordRaw[];
declare function resetStaticRoutes(router: Router, routes: RouteRecordRaw[]): void;
declare function unmountGlobalLoading(): void;
export { findMenuByPath, findRootMenuByPath, generateMenus, generateRoutesByBackend, generateRoutesByFrontend, getPopupContainer, hasAuthority, mergeRouteModules, resetStaticRoutes, unmountGlobalLoading };
export type { RouteModuleType };
export { findMenuByPath, findRootMenuByPath } from './helpers/find-menu-by-path.cjs';
export { generateMenus } from './helpers/generate-menus.cjs';
export { generateRoutesByBackend } from './helpers/generate-routes-backend.cjs';
export { generateRoutesByFrontend, hasAuthority } from './helpers/generate-routes-frontend.cjs';
export { getPopupContainer } from './helpers/get-popup-container.cjs';
export { RouteModuleType, mergeRouteModules } from './helpers/merge-route-modules.cjs';
export { resetStaticRoutes } from './helpers/reset-routes.cjs';
export { unmountGlobalLoading } from './helpers/unmount-global-loading.cjs';
import '@dlymon-core/typings';
import 'vue-router';

@@ -1,33 +0,13 @@

import { MenuRecordRaw, GenerateMenuAndRoutesOptions } from '@dlymon-core/typings';
import { RouteRecordRaw, Router } from 'vue-router';
export * from '@dlymon-core/shared/cache';
export * from '@dlymon-core/shared/color';
export * from '@dlymon-core/shared/utils';
declare function findMenuByPath(list: MenuRecordRaw[], path?: string): MenuRecordRaw | null;
declare function findRootMenuByPath(menus: MenuRecordRaw[], path?: string, level?: number): {
findMenu: MenuRecordRaw | null;
rootMenu: MenuRecordRaw | undefined;
rootMenuPath: string | undefined;
};
declare function generateMenus(routes: RouteRecordRaw[], router: Router): MenuRecordRaw[];
declare function generateRoutesByBackend(options: GenerateMenuAndRoutesOptions): Promise<RouteRecordRaw[]>;
declare function generateRoutesByFrontend(routes: RouteRecordRaw[], roles: string[], forbiddenComponent?: RouteRecordRaw['component']): Promise<RouteRecordRaw[]>;
declare function hasAuthority(route: RouteRecordRaw, access: string[]): boolean;
declare function getPopupContainer(node?: HTMLElement): HTMLElement;
interface RouteModuleType {
default: RouteRecordRaw[];
}
declare function mergeRouteModules(routeModules: Record<string, unknown>): RouteRecordRaw[];
declare function resetStaticRoutes(router: Router, routes: RouteRecordRaw[]): void;
declare function unmountGlobalLoading(): void;
export { findMenuByPath, findRootMenuByPath, generateMenus, generateRoutesByBackend, generateRoutesByFrontend, getPopupContainer, hasAuthority, mergeRouteModules, resetStaticRoutes, unmountGlobalLoading };
export type { RouteModuleType };
export { findMenuByPath, findRootMenuByPath } from './helpers/find-menu-by-path.mjs';
export { generateMenus } from './helpers/generate-menus.mjs';
export { generateRoutesByBackend } from './helpers/generate-routes-backend.mjs';
export { generateRoutesByFrontend, hasAuthority } from './helpers/generate-routes-frontend.mjs';
export { getPopupContainer } from './helpers/get-popup-container.mjs';
export { RouteModuleType, mergeRouteModules } from './helpers/merge-route-modules.mjs';
export { resetStaticRoutes } from './helpers/reset-routes.mjs';
export { unmountGlobalLoading } from './helpers/unmount-global-loading.mjs';
import '@dlymon-core/typings';
import 'vue-router';

@@ -1,33 +0,13 @@

import { MenuRecordRaw, GenerateMenuAndRoutesOptions } from '@dlymon-core/typings';
import { RouteRecordRaw, Router } from 'vue-router';
export * from '@dlymon-core/shared/cache';
export * from '@dlymon-core/shared/color';
export * from '@dlymon-core/shared/utils';
declare function findMenuByPath(list: MenuRecordRaw[], path?: string): MenuRecordRaw | null;
declare function findRootMenuByPath(menus: MenuRecordRaw[], path?: string, level?: number): {
findMenu: MenuRecordRaw | null;
rootMenu: MenuRecordRaw | undefined;
rootMenuPath: string | undefined;
};
declare function generateMenus(routes: RouteRecordRaw[], router: Router): MenuRecordRaw[];
declare function generateRoutesByBackend(options: GenerateMenuAndRoutesOptions): Promise<RouteRecordRaw[]>;
declare function generateRoutesByFrontend(routes: RouteRecordRaw[], roles: string[], forbiddenComponent?: RouteRecordRaw['component']): Promise<RouteRecordRaw[]>;
declare function hasAuthority(route: RouteRecordRaw, access: string[]): boolean;
declare function getPopupContainer(node?: HTMLElement): HTMLElement;
interface RouteModuleType {
default: RouteRecordRaw[];
}
declare function mergeRouteModules(routeModules: Record<string, unknown>): RouteRecordRaw[];
declare function resetStaticRoutes(router: Router, routes: RouteRecordRaw[]): void;
declare function unmountGlobalLoading(): void;
export { findMenuByPath, findRootMenuByPath, generateMenus, generateRoutesByBackend, generateRoutesByFrontend, getPopupContainer, hasAuthority, mergeRouteModules, resetStaticRoutes, unmountGlobalLoading };
export type { RouteModuleType };
export { findMenuByPath, findRootMenuByPath } from './helpers/find-menu-by-path.js';
export { generateMenus } from './helpers/generate-menus.js';
export { generateRoutesByBackend } from './helpers/generate-routes-backend.js';
export { generateRoutesByFrontend, hasAuthority } from './helpers/generate-routes-frontend.js';
export { getPopupContainer } from './helpers/get-popup-container.js';
export { RouteModuleType, mergeRouteModules } from './helpers/merge-route-modules.js';
export { resetStaticRoutes } from './helpers/reset-routes.js';
export { unmountGlobalLoading } from './helpers/unmount-global-loading.js';
import '@dlymon-core/typings';
import 'vue-router';
export * from '@dlymon-core/shared/cache';
export * from '@dlymon-core/shared/color';
import { mapTree, filterTree, traverseTreeValues } from '@dlymon-core/shared/utils';
export * from '@dlymon-core/shared/utils';
function findMenuByPath(list, path) {
for (const menu of list) {
if (menu.path === path) {
return menu;
}
const findMenu = menu.children && findMenuByPath(menu.children, path);
if (findMenu) {
return findMenu;
}
}
return null;
}
function findRootMenuByPath(menus, path, level = 0) {
const findMenu = findMenuByPath(menus, path);
const rootMenuPath = findMenu?.parents?.[level];
const rootMenu = rootMenuPath ? menus.find((item) => item.path === rootMenuPath) : void 0;
return {
findMenu,
rootMenu,
rootMenuPath
};
}
function generateMenus(routes, router) {
const finalRoutesMap = Object.fromEntries(
router.getRoutes().map(({ name, path }) => [name, path])
);
let menus = mapTree(routes, (route) => {
const path = finalRoutesMap[route.name] ?? route.path ?? "";
const {
meta = {},
name: routeName,
redirect,
children = []
} = route;
const {
activeIcon,
badge,
badgeType,
badgeVariants,
hideChildrenInMenu = false,
icon,
link,
order,
title = ""
} = meta;
const name = title || routeName || "";
const resultChildren = hideChildrenInMenu ? [] : children ?? [];
if (resultChildren.length > 0) {
resultChildren.forEach((child) => {
child.parents = [...route.parents ?? [], path];
child.parent = path;
});
}
const resultPath = hideChildrenInMenu ? redirect || path : link || path;
return {
activeIcon,
badge,
badgeType,
badgeVariants,
icon,
name,
order,
parent: route.parent,
parents: route.parents,
path: resultPath,
show: !meta.hideInMenu,
children: resultChildren
};
});
menus = menus.sort((a, b) => (a?.order ?? 999) - (b?.order ?? 999));
return filterTree(menus, (menu) => !!menu.show);
}
async function generateRoutesByBackend(options) {
const { fetchMenuListAsync, layoutMap = {}, pageMap = {} } = options;
try {
const menuRoutes = await fetchMenuListAsync?.();
if (!menuRoutes) {
return [];
}
const normalizePageMap = {};
for (const [key, value] of Object.entries(pageMap)) {
normalizePageMap[normalizeViewPath(key)] = value;
}
const routes = convertRoutes(menuRoutes, layoutMap, normalizePageMap);
return routes;
} catch (error) {
console.error(error);
throw error;
}
}
function convertRoutes(routes, layoutMap, pageMap) {
return mapTree(routes, (node) => {
const route = node;
const { component, name } = node;
if (!name) {
console.error("route name is required", route);
}
if (component && layoutMap[component]) {
route.component = layoutMap[component];
} else if (component) {
const normalizePath = normalizeViewPath(component);
const pageKey = normalizePath.endsWith(".vue") ? normalizePath : `${normalizePath}.vue`;
if (pageMap[pageKey]) {
route.component = pageMap[pageKey];
} else {
console.error(`route component is invalid: ${pageKey}`, route);
route.component = pageMap["/_core/fallback/not-found.vue"];
}
}
return route;
});
}
function normalizeViewPath(path) {
const normalizedPath = path.replace(/^(\.\/|\.\.\/)+/, "");
const viewPath = normalizedPath.startsWith("/") ? normalizedPath : `/${normalizedPath}`;
return viewPath.replace(/^\/views/, "");
}
async function generateRoutesByFrontend(routes, roles, forbiddenComponent) {
const finalRoutes = filterTree(routes, (route) => {
return hasAuthority(route, roles);
});
if (!forbiddenComponent) {
return finalRoutes;
}
return mapTree(finalRoutes, (route) => {
if (menuHasVisibleWithForbidden(route)) {
route.component = forbiddenComponent;
}
return route;
});
}
function hasAuthority(route, access) {
const authority = route.meta?.authority;
if (!authority) {
return true;
}
const canAccess = access.some((value) => authority.includes(value));
return canAccess || !canAccess && menuHasVisibleWithForbidden(route);
}
function menuHasVisibleWithForbidden(route) {
return !!route.meta?.authority && Reflect.has(route.meta || {}, "menuVisibleWithForbidden") && !!route.meta?.menuVisibleWithForbidden;
}
function getPopupContainer(node) {
return node?.closest("form") ?? node?.parentNode ?? document.body;
}
function mergeRouteModules(routeModules) {
const mergedRoutes = [];
for (const routeModule of Object.values(routeModules)) {
const moduleRoutes = routeModule?.default ?? [];
mergedRoutes.push(...moduleRoutes);
}
return mergedRoutes;
}
function resetStaticRoutes(router, routes) {
const staticRouteNames = traverseTreeValues(routes, (route) => {
if (!route.name) {
console.warn(
`The route with the path ${route.path} needs to have the field name specified.`
);
}
return route.name;
});
const { getRoutes, hasRoute, removeRoute } = router;
const allRoutes = getRoutes();
allRoutes.forEach(({ name }) => {
if (name && !staticRouteNames.includes(name) && hasRoute(name)) {
removeRoute(name);
}
});
}
function unmountGlobalLoading() {
const loadingElement = document.querySelector("#__app-loading__");
if (loadingElement) {
loadingElement.classList.add("hidden");
const injectLoadingElements = document.querySelectorAll(
'[data-app-loading^="inject"]'
);
loadingElement.addEventListener(
"transitionend",
() => {
loadingElement.remove();
injectLoadingElements.forEach((el) => el.remove());
},
{ once: true }
);
}
}
export { findMenuByPath, findRootMenuByPath, generateMenus, generateRoutesByBackend, generateRoutesByFrontend, getPopupContainer, hasAuthority, mergeRouteModules, resetStaticRoutes, unmountGlobalLoading };
export { findMenuByPath, findRootMenuByPath } from './helpers/find-menu-by-path.mjs';
export { generateMenus } from './helpers/generate-menus.mjs';
export { generateRoutesByBackend } from './helpers/generate-routes-backend.mjs';
export { generateRoutesByFrontend, hasAuthority } from './helpers/generate-routes-frontend.mjs';
export { getPopupContainer } from './helpers/get-popup-container.mjs';
export { mergeRouteModules } from './helpers/merge-route-modules.mjs';
export { resetStaticRoutes } from './helpers/reset-routes.mjs';
export { unmountGlobalLoading } from './helpers/unmount-global-loading.mjs';
{
"name": "@dlymon/utils",
"version": "8.0.0",
"version": "9.0.0",
"license": "MIT",

@@ -18,6 +18,11 @@ "type": "module",

},
"dependencies": {
"peerDependencies": {
"@dlymon-core/shared": "*",
"@dlymon-core/typings": "*",
"vue-router": "*"
},
"devDependencies": {
"vue-router": "^4.6.3",
"@dlymon-core/shared": "5.0.0",
"@dlymon-core/typings": "4.0.0"
"@dlymon-core/shared": "1.0.0-beta.2",
"@dlymon-core/typings": "1.0.0-beta.2"
},

@@ -24,0 +29,0 @@ "scripts": {