fix: harden module outline normalization
This commit is contained in:
@@ -11,8 +11,10 @@ function textFromFields(value, fallback = '') {
|
||||
return cleanText(value.title ?? value.name ?? value.code, fallback)
|
||||
}
|
||||
|
||||
function menuTitle(menu, index) {
|
||||
return cleanText(menu?.name ?? menu?.title ?? menu?.code, `功能${index + 1}`)
|
||||
function menuToItem(menu) {
|
||||
if (!menu || typeof menu !== 'object') return null
|
||||
const title = cleanText(menu.name ?? menu.title ?? menu.code)
|
||||
return title ? { title } : null
|
||||
}
|
||||
|
||||
function warning(code, line) {
|
||||
@@ -30,12 +32,15 @@ export function normalizeModuleOutline(outline = {}) {
|
||||
const groups = Array.isArray(outline.groups) ? outline.groups : []
|
||||
return {
|
||||
title: textFromFields(outline),
|
||||
groups: groups.map((group) => ({
|
||||
title: textFromFields(group),
|
||||
items: (Array.isArray(group?.items) ? group.items : []).map((item) => ({
|
||||
groups: groups.map((group) => {
|
||||
const items = (Array.isArray(group?.items) ? group.items : []).map((item) => ({
|
||||
title: textFromFields(item)
|
||||
})).filter((item) => item.title)
|
||||
})).filter((group) => group.title || group.items.length)
|
||||
return {
|
||||
title: textFromFields(group, items.length ? FALLBACK_GROUP_TITLE : ''),
|
||||
items
|
||||
}
|
||||
}).filter((group) => group.title || group.items.length)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,15 +99,11 @@ export function blueprintToModuleOutline(blueprint = {}, options = {}) {
|
||||
const groups = [
|
||||
{
|
||||
title: '管理员端',
|
||||
items: (Array.isArray(blueprint.adminMenus) ? blueprint.adminMenus : []).map((menu, index) => ({
|
||||
title: menuTitle(menu, index)
|
||||
})).filter((item) => item.title)
|
||||
items: (Array.isArray(blueprint.adminMenus) ? blueprint.adminMenus : []).map(menuToItem).filter(Boolean)
|
||||
},
|
||||
{
|
||||
title: '普通用户端',
|
||||
items: (Array.isArray(blueprint.frontendMenus) ? blueprint.frontendMenus : []).map((menu, index) => ({
|
||||
title: menuTitle(menu, index)
|
||||
})).filter((item) => item.title)
|
||||
items: (Array.isArray(blueprint.frontendMenus) ? blueprint.frontendMenus : []).map(menuToItem).filter(Boolean)
|
||||
}
|
||||
].filter((group) => group.items.length)
|
||||
|
||||
|
||||
@@ -95,6 +95,39 @@ test('blueprintToModuleOutline maps project menus into standard groups', () => {
|
||||
assert.deepEqual(outline.groups[1].items.map((item) => item.title), ['社团浏览', 'profile'])
|
||||
})
|
||||
|
||||
test('blueprintToModuleOutline skips invalid menus while preserving code-only menus', () => {
|
||||
const outline = blueprintToModuleOutline({
|
||||
adminMenus: [
|
||||
null,
|
||||
'菜单',
|
||||
{},
|
||||
{ name: ' ', title: '', code: '\t' },
|
||||
{ code: 'users' }
|
||||
],
|
||||
frontendMenus: [
|
||||
undefined,
|
||||
{ title: ' ' },
|
||||
{ code: 'browse' }
|
||||
]
|
||||
})
|
||||
|
||||
assert.deepEqual(outline.groups.map((group) => group.title), ['管理员端', '普通用户端'])
|
||||
assert.deepEqual(outline.groups[0].items.map((item) => item.title), ['users'])
|
||||
assert.deepEqual(outline.groups[1].items.map((item) => item.title), ['browse'])
|
||||
})
|
||||
|
||||
test('normalizeModuleOutline gives untitled groups with items the fallback group title', () => {
|
||||
const outline = normalizeModuleOutline({
|
||||
title: '客户管理系统',
|
||||
groups: [
|
||||
{ title: ' ', items: [{ title: '客户列表' }] }
|
||||
]
|
||||
})
|
||||
|
||||
assert.equal(outline.groups[0].title, '未分组模块')
|
||||
assert.equal(moduleOutlineToText(outline), '客户管理系统\n 未分组模块\n 客户列表')
|
||||
})
|
||||
|
||||
test('moduleOutlineToText serializes normalized outlines with two-space levels', () => {
|
||||
const outline = normalizeModuleOutline({
|
||||
title: '学生社团管理系统',
|
||||
|
||||
Reference in New Issue
Block a user