@taocompany/magic-grid-mcp 0.0.0-stage → 0.14.1
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/bin/magic-grid-mcp.js +7 -0
- package/bin/mgc.js +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +43 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/mcpServer.d.ts +7 -0
- package/dist/mcpServer.d.ts.map +1 -0
- package/dist/mcpServer.js +105 -0
- package/dist/packageVersion.d.ts +3 -0
- package/dist/packageVersion.d.ts.map +1 -0
- package/dist/packageVersion.js +10 -0
- package/dist/resolveManifest.d.ts +25 -0
- package/dist/resolveManifest.d.ts.map +1 -0
- package/dist/resolveManifest.js +169 -0
- package/dist/scan/collectSourceFiles.d.ts +2 -0
- package/dist/scan/collectSourceFiles.d.ts.map +1 -0
- package/dist/scan/collectSourceFiles.js +30 -0
- package/dist/scan/parseMagicGrid.d.ts +18 -0
- package/dist/scan/parseMagicGrid.d.ts.map +1 -0
- package/dist/scan/parseMagicGrid.js +85 -0
- package/dist/tools/findRecipes.d.ts +19 -0
- package/dist/tools/findRecipes.d.ts.map +1 -0
- package/dist/tools/findRecipes.js +104 -0
- package/dist/tools/getComponentApi.d.ts +33 -0
- package/dist/tools/getComponentApi.d.ts.map +1 -0
- package/dist/tools/getComponentApi.js +138 -0
- package/dist/types.d.ts +110 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/validate/propTypeLiteral.d.ts +4 -0
- package/dist/validate/propTypeLiteral.d.ts.map +1 -0
- package/dist/validate/propTypeLiteral.js +48 -0
- package/dist/validate/validateUsage.d.ts +9 -0
- package/dist/validate/validateUsage.d.ts.map +1 -0
- package/dist/validate/validateUsage.js +342 -0
- package/package.json +52 -4
- package/README.md +0 -3
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const STOP = new Set([
|
|
2
|
+
'a',
|
|
3
|
+
'an',
|
|
4
|
+
'the',
|
|
5
|
+
'and',
|
|
6
|
+
'or',
|
|
7
|
+
'to',
|
|
8
|
+
'for',
|
|
9
|
+
'with',
|
|
10
|
+
'的',
|
|
11
|
+
'与',
|
|
12
|
+
'和',
|
|
13
|
+
'表格',
|
|
14
|
+
'magic',
|
|
15
|
+
'grid',
|
|
16
|
+
]);
|
|
17
|
+
function tokenize(text) {
|
|
18
|
+
return text
|
|
19
|
+
.toLowerCase()
|
|
20
|
+
.split(/[^\p{L}\p{N}_]+/u)
|
|
21
|
+
.map((t) => t.trim())
|
|
22
|
+
.filter((t) => t.length > 1 && !STOP.has(t));
|
|
23
|
+
}
|
|
24
|
+
function camelToKebab(name) {
|
|
25
|
+
return name.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
26
|
+
}
|
|
27
|
+
function extractUsedProps(code, knownProps) {
|
|
28
|
+
const used = [];
|
|
29
|
+
for (const name of knownProps) {
|
|
30
|
+
const kebab = camelToKebab(name);
|
|
31
|
+
const patterns = [
|
|
32
|
+
new RegExp(`\\b${name}\\b`),
|
|
33
|
+
new RegExp(`:${name}\\s*=`),
|
|
34
|
+
new RegExp(`\\b${kebab}\\s*=`),
|
|
35
|
+
new RegExp(`:${kebab}\\s*=`),
|
|
36
|
+
];
|
|
37
|
+
if (patterns.some((re) => re.test(code))) {
|
|
38
|
+
used.push(name);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return used.sort();
|
|
42
|
+
}
|
|
43
|
+
function scoreRecipe(queryTokens, recipe) {
|
|
44
|
+
const docTokens = tokenize(`${recipe.id} ${recipe.intent} ${recipe.code}`);
|
|
45
|
+
const docSet = new Set(docTokens);
|
|
46
|
+
let score = 0;
|
|
47
|
+
for (const t of queryTokens) {
|
|
48
|
+
if (docSet.has(t))
|
|
49
|
+
score += 2;
|
|
50
|
+
else if (docTokens.some((d) => d.includes(t) || t.includes(d)))
|
|
51
|
+
score += 1;
|
|
52
|
+
}
|
|
53
|
+
if (queryTokens.some((t) => recipe.id.includes(t)))
|
|
54
|
+
score += 3;
|
|
55
|
+
return score;
|
|
56
|
+
}
|
|
57
|
+
export function findRecipes(manifest, input) {
|
|
58
|
+
const limit = Math.min(Math.max(input.limit ?? 3, 1), 5);
|
|
59
|
+
const recipes = manifest.recipes ?? [];
|
|
60
|
+
const queryTokens = tokenize(input.intent);
|
|
61
|
+
if (recipes.length === 0) {
|
|
62
|
+
return {
|
|
63
|
+
libraryVersion: manifest.libraryVersion,
|
|
64
|
+
matches: [],
|
|
65
|
+
warn: 'manifest 中无 recipes;请升级 @taocompany/magic-grid 并重新 build。',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (queryTokens.length === 0) {
|
|
69
|
+
const fallback = recipes.slice(0, limit);
|
|
70
|
+
const propNames = new Set(manifest.props.map((p) => p.name));
|
|
71
|
+
return {
|
|
72
|
+
libraryVersion: manifest.libraryVersion,
|
|
73
|
+
matches: fallback.map((r) => ({
|
|
74
|
+
id: r.id,
|
|
75
|
+
intent: r.intent,
|
|
76
|
+
score: 0,
|
|
77
|
+
code: r.code,
|
|
78
|
+
propsUsed: extractUsedProps(r.code, propNames),
|
|
79
|
+
})),
|
|
80
|
+
warn: 'intent 过短,返回前几条 recipe 作为兜底。',
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const propNames = new Set(manifest.props.map((p) => p.name));
|
|
84
|
+
const ranked = recipes
|
|
85
|
+
.map((recipe) => ({
|
|
86
|
+
recipe,
|
|
87
|
+
score: scoreRecipe(queryTokens, recipe),
|
|
88
|
+
}))
|
|
89
|
+
.filter((r) => r.score > 0)
|
|
90
|
+
.sort((a, b) => b.score - a.score);
|
|
91
|
+
const top = ranked.length > 0
|
|
92
|
+
? ranked.slice(0, limit)
|
|
93
|
+
: recipes.slice(0, limit).map((recipe) => ({ recipe, score: 0 }));
|
|
94
|
+
return {
|
|
95
|
+
libraryVersion: manifest.libraryVersion,
|
|
96
|
+
matches: top.map(({ recipe, score }) => ({
|
|
97
|
+
id: recipe.id,
|
|
98
|
+
intent: recipe.intent,
|
|
99
|
+
score,
|
|
100
|
+
code: recipe.code,
|
|
101
|
+
propsUsed: extractUsedProps(recipe.code, propNames),
|
|
102
|
+
})),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ResolveManifestResult } from '../types.js';
|
|
2
|
+
export type ComponentApiSection = 'props' | 'emits' | 'slots' | 'api' | 'expose' | 'types' | 'columnDef';
|
|
3
|
+
export interface GetComponentApiInput {
|
|
4
|
+
section?: ComponentApiSection;
|
|
5
|
+
names?: string[];
|
|
6
|
+
query?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ApiItemBase {
|
|
9
|
+
name: string;
|
|
10
|
+
type?: string;
|
|
11
|
+
default?: string;
|
|
12
|
+
required?: boolean;
|
|
13
|
+
notes?: string;
|
|
14
|
+
signature?: string;
|
|
15
|
+
payloadType?: string;
|
|
16
|
+
kind?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface GetComponentApiResult {
|
|
20
|
+
libraryVersion: string;
|
|
21
|
+
source: 'manifest' | 'package-parse';
|
|
22
|
+
section: ComponentApiSection;
|
|
23
|
+
items: ApiItemBase[];
|
|
24
|
+
total: number;
|
|
25
|
+
truncated?: boolean;
|
|
26
|
+
versionMismatch?: {
|
|
27
|
+
installed: string;
|
|
28
|
+
manifest: string;
|
|
29
|
+
};
|
|
30
|
+
warn?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function getComponentApi(resolved: ResolveManifestResult, input?: GetComponentApiInput): GetComponentApiResult;
|
|
33
|
+
//# sourceMappingURL=getComponentApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getComponentApi.d.ts","sourceRoot":"","sources":["../../src/tools/getComponentApi.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAe,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAErE,MAAM,MAAM,mBAAmB,GAC3B,OAAO,GACP,OAAO,GACP,OAAO,GACP,KAAK,GACL,QAAQ,GACR,OAAO,GACP,WAAW,CAAA;AAEf,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,mBAAmB,CAAA;IAC7B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,UAAU,GAAG,eAAe,CAAA;IACpC,OAAO,EAAE,mBAAmB,CAAA;IAC5B,KAAK,EAAE,WAAW,EAAE,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,eAAe,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;IACzD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAqGD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,qBAAqB,EAC/B,KAAK,GAAE,oBAAyB,GAC/B,qBAAqB,CA+DvB"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const MAX_OUTPUT_CHARS = 28_000;
|
|
4
|
+
function readInstalledVersion(packageRoot) {
|
|
5
|
+
try {
|
|
6
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
|
|
7
|
+
return pkg.version;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function matchesFilter(name, notes, names, query) {
|
|
14
|
+
if (names && names.length > 0) {
|
|
15
|
+
const set = new Set(names.map((n) => n.toLowerCase()));
|
|
16
|
+
if (!set.has(name.toLowerCase()))
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
if (query && query.trim()) {
|
|
20
|
+
const q = query.trim().toLowerCase();
|
|
21
|
+
const hay = `${name} ${notes ?? ''}`.toLowerCase();
|
|
22
|
+
if (!hay.includes(q))
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
function sectionItems(manifest, section) {
|
|
28
|
+
switch (section) {
|
|
29
|
+
case 'props':
|
|
30
|
+
return manifest.props.map((p) => ({
|
|
31
|
+
name: p.name,
|
|
32
|
+
type: p.type,
|
|
33
|
+
default: p.default,
|
|
34
|
+
required: p.required,
|
|
35
|
+
notes: p.notes,
|
|
36
|
+
}));
|
|
37
|
+
case 'emits':
|
|
38
|
+
return (manifest.emits ?? []).map((e) => ({
|
|
39
|
+
name: e.name,
|
|
40
|
+
payloadType: e.payloadType,
|
|
41
|
+
notes: e.notes,
|
|
42
|
+
}));
|
|
43
|
+
case 'slots':
|
|
44
|
+
return (manifest.slots ?? []).map((s) => ({
|
|
45
|
+
name: s.name,
|
|
46
|
+
kind: s.kind,
|
|
47
|
+
description: s.description,
|
|
48
|
+
notes: s.description,
|
|
49
|
+
}));
|
|
50
|
+
case 'api':
|
|
51
|
+
return (manifest.gridApi ?? []).map((m) => ({
|
|
52
|
+
name: m.name,
|
|
53
|
+
signature: m.signature,
|
|
54
|
+
notes: m.notes,
|
|
55
|
+
}));
|
|
56
|
+
case 'expose':
|
|
57
|
+
return (manifest.expose ?? []).map((e) => ({
|
|
58
|
+
name: e.name,
|
|
59
|
+
type: e.type,
|
|
60
|
+
notes: e.notes,
|
|
61
|
+
}));
|
|
62
|
+
case 'columnDef':
|
|
63
|
+
return manifest.columnDef.map((c) => ({
|
|
64
|
+
name: c.name,
|
|
65
|
+
type: c.type,
|
|
66
|
+
notes: c.notes,
|
|
67
|
+
}));
|
|
68
|
+
case 'types':
|
|
69
|
+
return (manifest.types ?? []).map((t) => ({
|
|
70
|
+
name: t.name,
|
|
71
|
+
type: t.kind,
|
|
72
|
+
notes: t.kind === 'type'
|
|
73
|
+
? [t.definition, t.notes].filter(Boolean).join(' · ')
|
|
74
|
+
: [
|
|
75
|
+
t.notes,
|
|
76
|
+
t.fields
|
|
77
|
+
?.map((f) => `${f.name}${f.optional ? '?' : ''}: ${f.type}${f.notes ? ` — ${f.notes}` : ''}`)
|
|
78
|
+
.join('; '),
|
|
79
|
+
]
|
|
80
|
+
.filter(Boolean)
|
|
81
|
+
.join(' · '),
|
|
82
|
+
}));
|
|
83
|
+
default:
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export function getComponentApi(resolved, input = {}) {
|
|
88
|
+
const { manifest, source, packageRoot } = resolved;
|
|
89
|
+
const section = input.section ?? 'props';
|
|
90
|
+
const installed = readInstalledVersion(packageRoot);
|
|
91
|
+
const versionMismatch = installed && installed !== manifest.libraryVersion
|
|
92
|
+
? { installed, manifest: manifest.libraryVersion }
|
|
93
|
+
: undefined;
|
|
94
|
+
const all = sectionItems(manifest, section);
|
|
95
|
+
if (section === 'types' && all.length === 0) {
|
|
96
|
+
return {
|
|
97
|
+
libraryVersion: manifest.libraryVersion,
|
|
98
|
+
source,
|
|
99
|
+
section,
|
|
100
|
+
items: [],
|
|
101
|
+
total: 0,
|
|
102
|
+
versionMismatch,
|
|
103
|
+
warn: 'manifest 无 types 分片;请升级 @taocompany/magic-grid 或阅读 @taocompany/magic-grid/types/core。',
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const items = all.filter((item) => matchesFilter(item.name, item.notes ?? item.description, input.names, input.query));
|
|
107
|
+
let payload = {
|
|
108
|
+
libraryVersion: manifest.libraryVersion,
|
|
109
|
+
source,
|
|
110
|
+
section,
|
|
111
|
+
items,
|
|
112
|
+
total: items.length,
|
|
113
|
+
versionMismatch,
|
|
114
|
+
...(section === 'expose' && !input.names?.length && !input.query?.trim()
|
|
115
|
+
? {
|
|
116
|
+
warn: 'MagicGridExpose 仅为 ref 便捷面;addRows / setData / stopEditing / 完整 GridApi 请 section=api(query 如 applyTransaction)。组件 ref 上 getData / applyTransaction 与 api 等价。',
|
|
117
|
+
}
|
|
118
|
+
: {}),
|
|
119
|
+
...(section === 'api' && !input.names?.length && !input.query?.trim()
|
|
120
|
+
? {
|
|
121
|
+
warn: 'GridApi 含 getData、setData、applyTransaction、addRows、stopEditing 等;用 names 或 query 缩小范围,types 分片见 section=types names=[RowTransaction]。',
|
|
122
|
+
}
|
|
123
|
+
: {}),
|
|
124
|
+
};
|
|
125
|
+
let json = JSON.stringify(payload);
|
|
126
|
+
if (json.length > MAX_OUTPUT_CHARS) {
|
|
127
|
+
const ratio = MAX_OUTPUT_CHARS / json.length;
|
|
128
|
+
const keep = Math.max(5, Math.floor(items.length * ratio * 0.9));
|
|
129
|
+
payload = {
|
|
130
|
+
...payload,
|
|
131
|
+
items: items.slice(0, keep),
|
|
132
|
+
total: items.length,
|
|
133
|
+
truncated: true,
|
|
134
|
+
warn: `结果过大(${items.length} 项);已截断为 ${keep} 项。请用 names 或 query 缩小范围。`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return payload;
|
|
138
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
export interface ManifestRuleMeta {
|
|
2
|
+
id: string;
|
|
3
|
+
severity: 'error' | 'warning';
|
|
4
|
+
autoFix: boolean;
|
|
5
|
+
detectable?: 'literal-only' | 'heuristic' | 'static';
|
|
6
|
+
}
|
|
7
|
+
export interface CommonMistake {
|
|
8
|
+
wrong: string;
|
|
9
|
+
right: string;
|
|
10
|
+
kind: 'prop' | 'columnDef';
|
|
11
|
+
}
|
|
12
|
+
export interface ManifestProp {
|
|
13
|
+
name: string;
|
|
14
|
+
type?: string;
|
|
15
|
+
default?: string;
|
|
16
|
+
required?: boolean;
|
|
17
|
+
notes?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ManifestEmit {
|
|
20
|
+
name: string;
|
|
21
|
+
payloadType?: string;
|
|
22
|
+
notes?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ManifestSlot {
|
|
25
|
+
name: string;
|
|
26
|
+
kind?: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface ManifestGridApiMethod {
|
|
30
|
+
name: string;
|
|
31
|
+
signature?: string;
|
|
32
|
+
notes?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface ManifestExposeField {
|
|
35
|
+
name: string;
|
|
36
|
+
type?: string;
|
|
37
|
+
notes?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface ManifestColumnDefField {
|
|
40
|
+
name: string;
|
|
41
|
+
type?: string;
|
|
42
|
+
notes?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface ManifestRecipe {
|
|
45
|
+
id: string;
|
|
46
|
+
intent: string;
|
|
47
|
+
code: string;
|
|
48
|
+
}
|
|
49
|
+
export interface ManifestTypeField {
|
|
50
|
+
name: string;
|
|
51
|
+
type: string;
|
|
52
|
+
optional?: boolean;
|
|
53
|
+
notes?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface ManifestTypeDefinition {
|
|
56
|
+
name: string;
|
|
57
|
+
kind: 'interface' | 'type';
|
|
58
|
+
definition?: string;
|
|
59
|
+
fields?: ManifestTypeField[];
|
|
60
|
+
notes?: string;
|
|
61
|
+
}
|
|
62
|
+
export interface ApiManifest {
|
|
63
|
+
manifestVersion: number;
|
|
64
|
+
libraryVersion: string;
|
|
65
|
+
props: ManifestProp[];
|
|
66
|
+
emits?: ManifestEmit[];
|
|
67
|
+
slots?: ManifestSlot[];
|
|
68
|
+
expose?: ManifestExposeField[];
|
|
69
|
+
gridApi?: ManifestGridApiMethod[];
|
|
70
|
+
columnDef: ManifestColumnDefField[];
|
|
71
|
+
rules: ManifestRuleMeta[];
|
|
72
|
+
commonMistakes: CommonMistake[];
|
|
73
|
+
recipes?: ManifestRecipe[];
|
|
74
|
+
types?: ManifestTypeDefinition[];
|
|
75
|
+
}
|
|
76
|
+
export interface ValidationFix {
|
|
77
|
+
kind: string;
|
|
78
|
+
from?: string;
|
|
79
|
+
to?: string;
|
|
80
|
+
}
|
|
81
|
+
export interface ValidationIssue {
|
|
82
|
+
file: string;
|
|
83
|
+
line: number;
|
|
84
|
+
rule: string;
|
|
85
|
+
severity: 'error' | 'warning';
|
|
86
|
+
message: string;
|
|
87
|
+
fix?: ValidationFix;
|
|
88
|
+
}
|
|
89
|
+
export interface UncheckedItem {
|
|
90
|
+
reason: string;
|
|
91
|
+
at: string;
|
|
92
|
+
detail: string;
|
|
93
|
+
}
|
|
94
|
+
export type ValidateScore = 'pass' | 'pass-with-warnings' | 'fail';
|
|
95
|
+
export interface ValidateUsageResult {
|
|
96
|
+
libraryVersion: string;
|
|
97
|
+
source: 'manifest' | 'package-parse';
|
|
98
|
+
manifestPath?: string;
|
|
99
|
+
errors: ValidationIssue[];
|
|
100
|
+
unchecked: UncheckedItem[];
|
|
101
|
+
coverage: number;
|
|
102
|
+
score: ValidateScore;
|
|
103
|
+
}
|
|
104
|
+
export interface ResolveManifestResult {
|
|
105
|
+
manifest: ApiManifest;
|
|
106
|
+
source: 'manifest' | 'package-parse';
|
|
107
|
+
manifestPath: string;
|
|
108
|
+
packageRoot: string;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ParsedAttr } from '../scan/parseMagicGrid.js';
|
|
2
|
+
import type { ValidationIssue } from '../types.js';
|
|
3
|
+
export declare function checkPropTypeLiteral(file: string, attr: ParsedAttr, errors: ValidationIssue[]): boolean;
|
|
4
|
+
//# sourceMappingURL=propTypeLiteral.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propTypeLiteral.d.ts","sourceRoot":"","sources":["../../src/validate/propTypeLiteral.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAoBlD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,eAAe,EAAE,GACxB,OAAO,CAqCT"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** 字面量 prop 的枚举/形态校验(v1 · 仅高频误写) */
|
|
2
|
+
const STRING_ENUM_PROPS = {
|
|
3
|
+
rowSelection: ['single', 'multiple'],
|
|
4
|
+
size: ['mini', 'small', 'default', 'large'],
|
|
5
|
+
};
|
|
6
|
+
const NUMERIC_PROPS = new Set([
|
|
7
|
+
'rowHeight',
|
|
8
|
+
'rowBuffer',
|
|
9
|
+
'scrollEndFlushMs',
|
|
10
|
+
'headerHeight',
|
|
11
|
+
'floatingFiltersHeight',
|
|
12
|
+
]);
|
|
13
|
+
function resolvePropName(name) {
|
|
14
|
+
return name.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
15
|
+
}
|
|
16
|
+
export function checkPropTypeLiteral(file, attr, errors) {
|
|
17
|
+
if (attr.isBinding || attr.literalValue === true) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const value = typeof attr.literalValue === 'string' ? attr.literalValue.trim() : null;
|
|
21
|
+
if (value === null) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const propKey = resolvePropName(attr.name);
|
|
25
|
+
const allowed = STRING_ENUM_PROPS[propKey];
|
|
26
|
+
if (allowed && !allowed.includes(value)) {
|
|
27
|
+
errors.push({
|
|
28
|
+
file,
|
|
29
|
+
line: attr.line,
|
|
30
|
+
rule: 'prop-type-literal',
|
|
31
|
+
severity: 'error',
|
|
32
|
+
message: `${attr.name}="${value}" 无效,允许值:${allowed.join(' | ')}`,
|
|
33
|
+
fix: { kind: 'fix-literal', from: value, to: allowed[0] ?? '' },
|
|
34
|
+
});
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
if (NUMERIC_PROPS.has(propKey) && value !== '' && Number.isNaN(Number(value))) {
|
|
38
|
+
errors.push({
|
|
39
|
+
file,
|
|
40
|
+
line: attr.line,
|
|
41
|
+
rule: 'prop-type-literal',
|
|
42
|
+
severity: 'error',
|
|
43
|
+
message: `${attr.name} 应为数字字面量,收到 "${value}"`,
|
|
44
|
+
});
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ResolveManifestResult } from '../resolveManifest.js';
|
|
2
|
+
import type { ValidateUsageResult } from '../types.js';
|
|
3
|
+
interface ValidateOptions {
|
|
4
|
+
cwd?: string;
|
|
5
|
+
paths: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function validateMagicGridUsage(resolved: ResolveManifestResult, options: ValidateOptions): ValidateUsageResult;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=validateUsage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateUsage.d.ts","sourceRoot":"","sources":["../../src/validate/validateUsage.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,KAAK,EAGV,mBAAmB,EAEpB,MAAM,aAAa,CAAA;AAWpB,UAAU,eAAe;IACvB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,eAAe,GACvB,mBAAmB,CAmIrB"}
|