fix: 修复管理端前端 lint 与构建问题

- 收敛 easyflow-ui-admin 的 lint、格式和类型问题

- 修正 demo 页面与管理端前端构建失败点

- 验证 pnpm lint 与 pnpm build 均已通过
This commit is contained in:
2026-04-05 21:39:13 +08:00
parent bb72e19c84
commit 7e7c236c2a
240 changed files with 5151 additions and 4701 deletions

View File

@@ -1,175 +1,175 @@
import { describe, expect, it } from 'vitest';
import {
flattenParameterCandidates,
findBackspaceTokenRange,
findTokenRangeAtCursor,
flattenParameterNames,
insertTextAtCursor,
parseTokenParts,
splitTokenDisplay
flattenParameterCandidates,
findBackspaceTokenRange,
findTokenRangeAtCursor,
flattenParameterNames,
insertTextAtCursor,
parseTokenParts,
splitTokenDisplay,
} from './paramToken';
describe('paramToken utils', () => {
it('should flatten parameter names with nested paths', () => {
const result = flattenParameterNames([
{
name: 'input'
},
{
name: 'documents',
children: [
{
name: 'title'
},
{
name: 'meta',
children: [
{
name: 'author'
}
]
}
]
}
]);
it('should flatten parameter names with nested paths', () => {
const result = flattenParameterNames([
{
name: 'input',
},
{
name: 'documents',
children: [
{
name: 'title',
},
{
name: 'meta',
children: [
{
name: 'author',
},
],
},
],
},
]);
expect(result).toEqual([
'input',
'documents',
'documents.title',
'documents.meta',
'documents.meta.author'
]);
expect(result).toEqual([
'input',
'documents',
'documents.title',
'documents.meta',
'documents.meta.author',
]);
});
it('should keep unresolved candidates in parameter list', () => {
const result = flattenParameterCandidates([
{
name: 'input',
refType: 'ref',
ref: '',
},
{
name: 'docs',
refType: 'ref',
ref: 'documents',
},
{
name: 'runtimeInput',
refType: 'input',
},
]);
expect(result).toEqual([
{
name: 'input',
resolved: false,
},
{
name: 'docs',
resolved: true,
},
{
name: 'runtimeInput',
resolved: true,
},
]);
});
it('should insert token text in the middle by cursor range', () => {
const result = insertTextAtCursor('hello world', '{{input}}', 6, 11);
expect(result).toEqual({
value: 'hello {{input}}',
cursor: 15,
});
});
it('should append token text when cursor info is missing', () => {
const result = insertTextAtCursor('hello', '{{name}}');
expect(result).toEqual({
value: 'hello{{name}}',
cursor: 13,
});
});
it('should parse token parts and mark valid tokens', () => {
const parts = parseTokenParts('你好 {{ user.name }} 与 {{unknown}}', [
'user.name',
'docs',
]);
expect(parts).toEqual([
{
type: 'text',
text: '你好 ',
},
{
type: 'token',
text: '{{ user.name }}',
key: 'user.name',
valid: true,
},
{
type: 'text',
text: ' 与 ',
},
{
type: 'token',
text: '{{unknown}}',
key: 'unknown',
valid: false,
},
]);
});
it('should keep plain text when token syntax is invalid', () => {
const parts = parseTokenParts('abc {{}} def', ['a']);
expect(parts).toEqual([
{
type: 'text',
text: 'abc {{}} def',
},
]);
});
it('should split token display and hide braces text', () => {
const result = splitTokenDisplay('{{ user.name }}', 'user.name');
expect(result).toEqual({
hiddenPrefix: '{{ ',
visibleText: 'user.name',
hiddenSuffix: ' }}',
});
});
it('should find full token range for backspace delete', () => {
const content = 'hello {{input}} world';
const tokenEndCursor = 'hello {{input}}'.length;
const range = findBackspaceTokenRange(content, tokenEndCursor);
expect(range).toEqual({
start: 6,
end: 15,
text: '{{input}}',
key: 'input',
});
});
it('should support boundary match for arrow skip behavior', () => {
const content = 'x{{docs}}y';
const tokenStart = 1;
const tokenEnd = 9;
const rightBoundary = findTokenRangeAtCursor(content, tokenStart, {
includeStart: true,
includeEnd: false,
});
const leftBoundary = findTokenRangeAtCursor(content, tokenEnd, {
includeStart: false,
includeEnd: true,
});
it('should keep unresolved candidates in parameter list', () => {
const result = flattenParameterCandidates([
{
name: 'input',
refType: 'ref',
ref: ''
},
{
name: 'docs',
refType: 'ref',
ref: 'documents'
},
{
name: 'runtimeInput',
refType: 'input'
}
]);
expect(result).toEqual([
{
name: 'input',
resolved: false
},
{
name: 'docs',
resolved: true
},
{
name: 'runtimeInput',
resolved: true
}
]);
});
it('should insert token text in the middle by cursor range', () => {
const result = insertTextAtCursor('hello world', '{{input}}', 6, 11);
expect(result).toEqual({
value: 'hello {{input}}',
cursor: 15
});
});
it('should append token text when cursor info is missing', () => {
const result = insertTextAtCursor('hello', '{{name}}');
expect(result).toEqual({
value: 'hello{{name}}',
cursor: 13
});
});
it('should parse token parts and mark valid tokens', () => {
const parts = parseTokenParts(
'你好 {{ user.name }} 与 {{unknown}}',
['user.name', 'docs']
);
expect(parts).toEqual([
{
type: 'text',
text: '你好 '
},
{
type: 'token',
text: '{{ user.name }}',
key: 'user.name',
valid: true
},
{
type: 'text',
text: ' 与 '
},
{
type: 'token',
text: '{{unknown}}',
key: 'unknown',
valid: false
}
]);
});
it('should keep plain text when token syntax is invalid', () => {
const parts = parseTokenParts('abc {{}} def', ['a']);
expect(parts).toEqual([
{
type: 'text',
text: 'abc {{}} def'
}
]);
});
it('should split token display and hide braces text', () => {
const result = splitTokenDisplay('{{ user.name }}', 'user.name');
expect(result).toEqual({
hiddenPrefix: '{{ ',
visibleText: 'user.name',
hiddenSuffix: ' }}'
});
});
it('should find full token range for backspace delete', () => {
const content = 'hello {{input}} world';
const tokenEndCursor = 'hello {{input}}'.length;
const range = findBackspaceTokenRange(content, tokenEndCursor);
expect(range).toEqual({
start: 6,
end: 15,
text: '{{input}}',
key: 'input'
});
});
it('should support boundary match for arrow skip behavior', () => {
const content = 'x{{docs}}y';
const tokenStart = 1;
const tokenEnd = 9;
const rightBoundary = findTokenRangeAtCursor(content, tokenStart, {
includeStart: true,
includeEnd: false
});
const leftBoundary = findTokenRangeAtCursor(content, tokenEnd, {
includeStart: false,
includeEnd: true
});
expect(rightBoundary?.key).toBe('docs');
expect(leftBoundary?.key).toBe('docs');
});
expect(rightBoundary?.key).toBe('docs');
expect(leftBoundary?.key).toBe('docs');
});
});