@iress-oss/ids-mcp-server 0.0.1-dev.4 → 0.0.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/LICENSE +193 -0
- package/README.md +159 -29
- package/build/componentHandlers.js +205 -0
- package/{dist → build}/config.js +5 -5
- package/build/index.js +51 -0
- package/{dist → build}/iressHandlers.js +46 -52
- package/{dist → build}/resourceHandlers.js +22 -23
- package/{dist → build}/searchHandlers.js +92 -107
- package/{dist → build}/toolHandler.js +13 -13
- package/build/tools.js +165 -0
- package/{dist → build}/utils.js +15 -11
- package/docs/api-reference.md +0 -0
- package/docs/best-practices.md +0 -0
- package/docs/configuration.md +0 -0
- package/docs/examples.md +0 -0
- package/docs/guidelines.md +269 -0
- package/{generated/docs → docs/ids}/components-autocomplete-docs.md +5 -5
- package/{generated/docs → docs/ids}/components-autocomplete-recipes-docs.md +51 -17
- package/{generated/docs → docs/ids}/components-card-recipes-docs.md +1 -1
- package/{generated/docs → docs/ids}/components-checkbox-docs.md +19 -6
- package/{generated/docs → docs/ids}/components-checkboxgroup-docs.md +18 -18
- package/{generated/docs → docs/ids}/components-checkboxgroup-recipes-docs.md +9 -9
- package/{generated/docs → docs/ids}/components-col-docs.md +1 -1
- package/{generated/docs → docs/ids}/components-combobox-docs.md +6 -6
- package/{generated/docs → docs/ids}/components-container-docs.md +42 -8
- package/{generated/docs → docs/ids}/components-filter-docs.md +66 -13
- package/{generated/docs → docs/ids}/components-form-docs.md +368 -342
- package/{generated/docs → docs/ids}/components-form-recipes-docs.md +11 -202
- package/{generated/docs → docs/ids}/components-hide-docs.md +70 -16
- package/{generated/docs → docs/ids}/components-icon-docs.md +4 -4
- package/{generated/docs → docs/ids}/components-input-recipes-docs.md +2 -2
- package/{generated/docs → docs/ids}/components-inputcurrency-recipes-docs.md +40 -6
- package/{generated/docs → docs/ids}/components-modal-docs.md +113 -3
- package/docs/ids/components-popover-docs.md +4 -0
- package/{generated/docs → docs/ids}/components-radiogroup-docs.md +21 -21
- package/{generated/docs → docs/ids}/components-richselect-docs.md +111 -149
- package/{generated/docs → docs/ids}/components-row-docs.md +4 -4
- package/{generated/docs → docs/ids}/components-skeleton-docs.md +3 -3
- package/{generated/docs → docs/ids}/components-skeleton-recipes-docs.md +1 -1
- package/{generated/docs → docs/ids}/components-skiplink-docs.md +1 -1
- package/{generated/docs → docs/ids}/components-slideout-docs.md +113 -3
- package/docs/ids/components-table-ag-grid-docs.md +2694 -0
- package/{generated/docs → docs/ids}/components-table-docs.md +597 -92
- package/{generated/docs → docs/ids}/components-tabset-docs.md +2 -2
- package/{generated/docs → docs/ids}/components-tag-docs.md +1 -1
- package/{generated/docs → docs/ids}/components-toaster-docs.md +5 -56
- package/{generated/docs → docs/ids}/extensions-editor-docs.md +5 -5
- package/{generated/docs → docs/ids}/foundations-colours-docs.md +1 -1
- package/{generated/docs → docs/ids}/foundations-typography-docs.md +2 -7
- package/docs/ids/get-started-develop-docs.md +48 -0
- package/{generated/docs → docs/ids}/introduction-docs.md +4 -4
- package/{generated/docs → docs/ids}/patterns-loading-docs.md +2 -332
- package/docs/ids/resources-migration-guides-from-v4-to-v5-docs.md +639 -0
- package/docs/ids/themes-available-themes-docs.md +74 -0
- package/docs/ids/themes-tokens-docs.md +4580 -0
- package/docs/ids/versions-docs.md +27 -0
- package/docs/tutorials/basic-integration.md +0 -0
- package/package.json +15 -44
- package/LICENSE.txt +0 -201
- package/dist/componentHandlers.js +0 -241
- package/dist/componentHandlers.test.js +0 -380
- package/dist/index.js +0 -53
- package/dist/iressHandlers.test.js +0 -316
- package/dist/resourceHandlers.test.js +0 -352
- package/dist/searchHandlers.test.js +0 -524
- package/dist/toolHandler.test.js +0 -369
- package/dist/tools.js +0 -165
- package/dist/utils.test.js +0 -286
- package/generated/docs/components-popover-docs.md +0 -464
- package/generated/docs/components-provider-docs.md +0 -105
- package/generated/docs/components-table-ag-grid-docs.md +0 -1074
- package/generated/docs/foundations-accessibility-docs.md +0 -62
- package/generated/docs/foundations-consistency-docs.md +0 -52
- package/generated/docs/foundations-content-docs.md +0 -23
- package/generated/docs/foundations-introduction-docs.md +0 -17
- package/generated/docs/foundations-principles-docs.md +0 -70
- package/generated/docs/foundations-user-experience-docs.md +0 -63
- package/generated/docs/foundations-visual-design-docs.md +0 -46
- package/generated/docs/get-started-develop-docs.md +0 -209
- package/generated/docs/guidelines.md +0 -812
- package/generated/docs/resources-migration-guides-from-v4-to-v5-docs.md +0 -437
- package/generated/docs/themes-available-themes-docs.md +0 -66
- package/generated/docs/themes-tokens-docs.md +0 -1200
- package/generated/docs/versions-docs.md +0 -17
- /package/{dist → build}/types.js +0 -0
- /package/{generated/docs → docs/ids}/components-alert-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-badge-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-button-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-button-recipes-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-buttongroup-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-card-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-divider-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-expander-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-field-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-inline-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-input-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-inputcurrency-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-label-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-menu-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-menu-menuitem-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-navbar-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-navbar-recipes-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-panel-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-placeholder-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-popover-recipes-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-progress-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-radio-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-readonly-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-select-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-slider-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-spinner-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-stack-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-tabset-tab-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-text-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-toaster-toast-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-toggle-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-tooltip-docs.md +0 -0
- /package/{generated/docs → docs/ids}/components-validationmessage-docs.md +0 -0
- /package/{generated/docs → docs/ids}/contact-us-docs.md +0 -0
- /package/{generated/docs → docs/ids}/extensions-editor-recipes-docs.md +0 -0
- /package/{generated/docs → docs/ids}/frequently-asked-questions-docs.md +0 -0
- /package/{generated/docs → docs/ids}/get-started-using-storybook-docs.md +0 -0
- /package/{generated/docs → docs/ids}/resources-changelog-docs.md +0 -0
- /package/{generated/docs → docs/ids}/resources-code-katas-docs.md +0 -0
- /package/{generated/docs → docs/ids}/themes-introduction-docs.md +0 -0
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for component handlers
|
|
3
|
-
*/
|
|
4
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
5
|
-
import { handleFindComponent, handleGetComponentProps, handleListComponents, } from './componentHandlers.js';
|
|
6
|
-
import * as utils from './utils.js';
|
|
7
|
-
// Mock the utils module
|
|
8
|
-
vi.mock('./utils.js', () => ({
|
|
9
|
-
getMarkdownFiles: vi.fn(),
|
|
10
|
-
mapIressComponentToFile: vi.fn(),
|
|
11
|
-
extractIressComponents: vi.fn(),
|
|
12
|
-
readFileContent: vi.fn(),
|
|
13
|
-
}));
|
|
14
|
-
// Mock the config module
|
|
15
|
-
vi.mock('./config.js', () => ({
|
|
16
|
-
DOCS_DIR: '/mocked/docs/path',
|
|
17
|
-
}));
|
|
18
|
-
const mockUtils = vi.mocked(utils);
|
|
19
|
-
describe('componentHandlers', () => {
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
vi.clearAllMocks();
|
|
22
|
-
});
|
|
23
|
-
afterEach(() => {
|
|
24
|
-
vi.restoreAllMocks();
|
|
25
|
-
});
|
|
26
|
-
describe('handleFindComponent', () => {
|
|
27
|
-
const mockMarkdownFiles = [
|
|
28
|
-
'components-button-docs.md',
|
|
29
|
-
'components-input-docs.md',
|
|
30
|
-
'components-table-docs.md',
|
|
31
|
-
'foundations-colors-docs.md',
|
|
32
|
-
'resources-icons-docs.md',
|
|
33
|
-
];
|
|
34
|
-
const mockButtonContent = `# Button Component
|
|
35
|
-
|
|
36
|
-
A versatile button component for user interactions.
|
|
37
|
-
|
|
38
|
-
## Props
|
|
39
|
-
- variant: string - Button style variant
|
|
40
|
-
- size: string - Button size
|
|
41
|
-
|
|
42
|
-
## Examples
|
|
43
|
-
\`\`\`jsx
|
|
44
|
-
<Button variant="primary">Click me</Button>
|
|
45
|
-
\`\`\`
|
|
46
|
-
`;
|
|
47
|
-
it('should find exact match for Iress component', () => {
|
|
48
|
-
const args = {
|
|
49
|
-
query: 'IressButton',
|
|
50
|
-
};
|
|
51
|
-
mockUtils.mapIressComponentToFile.mockReturnValue('components-button-docs.md');
|
|
52
|
-
const result = handleFindComponent(args);
|
|
53
|
-
expect(mockUtils.mapIressComponentToFile).toHaveBeenCalledWith('IressButton');
|
|
54
|
-
expect(result.content).toHaveLength(1);
|
|
55
|
-
expect(result.content[0].type).toBe('text');
|
|
56
|
-
expect(result.content[0].text).toContain('Found exact match for **IressButton**');
|
|
57
|
-
expect(result.content[0].text).toContain('components-button-docs.md');
|
|
58
|
-
expect(result.content[0].text).toContain('Use `get_iress_component_info` with "IressButton"');
|
|
59
|
-
});
|
|
60
|
-
it('should return null for non-matching Iress component', () => {
|
|
61
|
-
const args = {
|
|
62
|
-
query: 'IressNonExistent',
|
|
63
|
-
};
|
|
64
|
-
mockUtils.mapIressComponentToFile.mockReturnValue(null);
|
|
65
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
66
|
-
mockUtils.readFileContent.mockReturnValue('No relevant content');
|
|
67
|
-
mockUtils.extractIressComponents.mockReturnValue([]);
|
|
68
|
-
const result = handleFindComponent(args);
|
|
69
|
-
expect(result.content[0].text).toContain('No IDS components found matching "IressNonExistent"');
|
|
70
|
-
});
|
|
71
|
-
it('should search and rank components by relevance', () => {
|
|
72
|
-
const args = {
|
|
73
|
-
query: 'button',
|
|
74
|
-
};
|
|
75
|
-
mockUtils.mapIressComponentToFile.mockReturnValue(null);
|
|
76
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
77
|
-
mockUtils.extractIressComponents.mockReturnValue([]);
|
|
78
|
-
// Mock file content with different relevance scores
|
|
79
|
-
mockUtils.readFileContent.mockImplementation((filePath) => {
|
|
80
|
-
if (filePath.includes('button')) {
|
|
81
|
-
return mockButtonContent;
|
|
82
|
-
}
|
|
83
|
-
return 'Some other component content';
|
|
84
|
-
});
|
|
85
|
-
const result = handleFindComponent(args);
|
|
86
|
-
expect(result.content[0].text).toContain('Found');
|
|
87
|
-
expect(result.content[0].text).toContain('relevant IDS components');
|
|
88
|
-
expect(result.content[0].text).toContain('button-docs.md');
|
|
89
|
-
});
|
|
90
|
-
it('should filter by category when specified', () => {
|
|
91
|
-
const args = {
|
|
92
|
-
query: 'component',
|
|
93
|
-
category: 'components',
|
|
94
|
-
};
|
|
95
|
-
mockUtils.mapIressComponentToFile.mockReturnValue(null);
|
|
96
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
97
|
-
mockUtils.extractIressComponents.mockReturnValue([]);
|
|
98
|
-
mockUtils.readFileContent.mockReturnValue('Component content');
|
|
99
|
-
handleFindComponent(args);
|
|
100
|
-
// Should only search components category files
|
|
101
|
-
expect(mockUtils.readFileContent).toHaveBeenCalledWith('/mocked/docs/path/components-button-docs.md');
|
|
102
|
-
expect(mockUtils.readFileContent).toHaveBeenCalledWith('/mocked/docs/path/components-input-docs.md');
|
|
103
|
-
expect(mockUtils.readFileContent).not.toHaveBeenCalledWith('/mocked/docs/path/foundations-colors-docs.md');
|
|
104
|
-
});
|
|
105
|
-
it('should handle Iress component mentions in content', () => {
|
|
106
|
-
const args = {
|
|
107
|
-
query: 'button',
|
|
108
|
-
};
|
|
109
|
-
mockUtils.mapIressComponentToFile.mockReturnValue(null);
|
|
110
|
-
mockUtils.getMarkdownFiles.mockReturnValue(['components-form-docs.md']);
|
|
111
|
-
mockUtils.extractIressComponents.mockReturnValue(['IressButton']);
|
|
112
|
-
mockUtils.readFileContent.mockReturnValue('This form uses IressButton component');
|
|
113
|
-
const result = handleFindComponent(args);
|
|
114
|
-
expect(result.content[0].text).toContain('relevant IDS components');
|
|
115
|
-
});
|
|
116
|
-
it('should validate input parameters using zod schema', () => {
|
|
117
|
-
const invalidArgs = {
|
|
118
|
-
query: 123, // Should be string
|
|
119
|
-
};
|
|
120
|
-
expect(() => handleFindComponent(invalidArgs)).toThrow();
|
|
121
|
-
});
|
|
122
|
-
it('should validate category parameter using zod schema', () => {
|
|
123
|
-
const invalidArgs = {
|
|
124
|
-
query: 'button',
|
|
125
|
-
category: 'invalid-category', // Should be enum value
|
|
126
|
-
};
|
|
127
|
-
expect(() => handleFindComponent(invalidArgs)).toThrow();
|
|
128
|
-
});
|
|
129
|
-
it('should handle file reading errors gracefully', () => {
|
|
130
|
-
const args = {
|
|
131
|
-
query: 'button',
|
|
132
|
-
};
|
|
133
|
-
mockUtils.mapIressComponentToFile.mockReturnValue(null);
|
|
134
|
-
mockUtils.getMarkdownFiles.mockReturnValue(['components-button-docs.md']);
|
|
135
|
-
mockUtils.readFileContent.mockImplementation(() => {
|
|
136
|
-
throw new Error('File read error');
|
|
137
|
-
});
|
|
138
|
-
// Should not throw, but handle error gracefully
|
|
139
|
-
const result = handleFindComponent(args);
|
|
140
|
-
expect(result.content[0].text).toContain('No IDS components found matching "button"');
|
|
141
|
-
});
|
|
142
|
-
it('should limit results to top 10', () => {
|
|
143
|
-
const args = {
|
|
144
|
-
query: 'component',
|
|
145
|
-
};
|
|
146
|
-
const manyFiles = Array.from({ length: 15 }, (_, i) => `components-comp${i}-docs.md`);
|
|
147
|
-
mockUtils.mapIressComponentToFile.mockReturnValue(null);
|
|
148
|
-
mockUtils.getMarkdownFiles.mockReturnValue(manyFiles);
|
|
149
|
-
mockUtils.extractIressComponents.mockReturnValue([]);
|
|
150
|
-
mockUtils.readFileContent.mockReturnValue('component content');
|
|
151
|
-
const result = handleFindComponent(args);
|
|
152
|
-
// Count the number of component entries by splitting on numbered items
|
|
153
|
-
const entries = result.content[0].text.split(/\n\d+\. /).length - 1;
|
|
154
|
-
expect(entries).toBeLessThanOrEqual(10);
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
describe('handleGetComponentProps', () => {
|
|
158
|
-
const mockMarkdownFiles = [
|
|
159
|
-
'components-button-docs.md',
|
|
160
|
-
'components-input-docs.md',
|
|
161
|
-
];
|
|
162
|
-
const mockComponentContent = `# Button Component
|
|
163
|
-
|
|
164
|
-
## Overview
|
|
165
|
-
A button component
|
|
166
|
-
|
|
167
|
-
## Props
|
|
168
|
-
- variant: string - The button variant
|
|
169
|
-
- size: string - The button size
|
|
170
|
-
|
|
171
|
-
Some text after props
|
|
172
|
-
|
|
173
|
-
## API
|
|
174
|
-
Additional API methods
|
|
175
|
-
|
|
176
|
-
Some text after API
|
|
177
|
-
|
|
178
|
-
## Examples
|
|
179
|
-
Usage examples here
|
|
180
|
-
|
|
181
|
-
Some text after examples
|
|
182
|
-
`;
|
|
183
|
-
it('should return component props when component exists', () => {
|
|
184
|
-
const args = {
|
|
185
|
-
component: 'button',
|
|
186
|
-
};
|
|
187
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
188
|
-
mockUtils.readFileContent.mockReturnValue(mockComponentContent);
|
|
189
|
-
const result = handleGetComponentProps(args);
|
|
190
|
-
expect(result.content).toHaveLength(1);
|
|
191
|
-
expect(result.content[0].type).toBe('text');
|
|
192
|
-
expect(result.content[0].text).toContain('**button Component Props & API**');
|
|
193
|
-
expect(result.content[0].text).toContain('## API');
|
|
194
|
-
expect(result.content[0].text).toContain('Additional API methods');
|
|
195
|
-
});
|
|
196
|
-
it('should return error when component not found', () => {
|
|
197
|
-
const args = {
|
|
198
|
-
component: 'nonexistent',
|
|
199
|
-
};
|
|
200
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
201
|
-
const result = handleGetComponentProps(args);
|
|
202
|
-
expect(result.content[0].text).toContain('Component "nonexistent" not found');
|
|
203
|
-
expect(result.content[0].text).toContain('Available components:');
|
|
204
|
-
expect(result.content[0].text).toContain('- button');
|
|
205
|
-
expect(result.content[0].text).toContain('- input');
|
|
206
|
-
});
|
|
207
|
-
it('should handle case-insensitive component matching', () => {
|
|
208
|
-
const args = {
|
|
209
|
-
component: 'BUTTON',
|
|
210
|
-
};
|
|
211
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
212
|
-
mockUtils.readFileContent.mockReturnValue(mockComponentContent);
|
|
213
|
-
const result = handleGetComponentProps(args);
|
|
214
|
-
expect(result.content[0].text).toContain('**BUTTON Component Props & API**');
|
|
215
|
-
});
|
|
216
|
-
it('should extract props from content with no specific props sections', () => {
|
|
217
|
-
const args = {
|
|
218
|
-
component: 'button',
|
|
219
|
-
};
|
|
220
|
-
const contentWithoutProps = `# Button Component
|
|
221
|
-
This is a simple button component without specific props sections.
|
|
222
|
-
Here is some general documentation.`;
|
|
223
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
224
|
-
mockUtils.readFileContent.mockReturnValue(contentWithoutProps);
|
|
225
|
-
const result = handleGetComponentProps(args);
|
|
226
|
-
expect(result.content[0].text).toContain('This is a simple button component');
|
|
227
|
-
});
|
|
228
|
-
it('should throw error when file reading fails', () => {
|
|
229
|
-
const args = {
|
|
230
|
-
component: 'button',
|
|
231
|
-
};
|
|
232
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
233
|
-
mockUtils.readFileContent.mockImplementation(() => {
|
|
234
|
-
throw new Error('File access denied');
|
|
235
|
-
});
|
|
236
|
-
expect(() => handleGetComponentProps(args)).toThrow('Failed to read component file components-button-docs.md: File access denied');
|
|
237
|
-
});
|
|
238
|
-
it('should validate input parameters using zod schema', () => {
|
|
239
|
-
const invalidArgs = {
|
|
240
|
-
component: 123, // Should be string
|
|
241
|
-
};
|
|
242
|
-
expect(() => handleGetComponentProps(invalidArgs)).toThrow();
|
|
243
|
-
});
|
|
244
|
-
it('should handle multiple prop-related sections', () => {
|
|
245
|
-
const contentWithMultipleSections = `# Button Component
|
|
246
|
-
|
|
247
|
-
## Props
|
|
248
|
-
- variant: string
|
|
249
|
-
|
|
250
|
-
## API
|
|
251
|
-
Methods available
|
|
252
|
-
|
|
253
|
-
## Properties
|
|
254
|
-
Additional properties
|
|
255
|
-
|
|
256
|
-
## mode
|
|
257
|
-
Different modes
|
|
258
|
-
`;
|
|
259
|
-
const args = {
|
|
260
|
-
component: 'button',
|
|
261
|
-
};
|
|
262
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
263
|
-
mockUtils.readFileContent.mockReturnValue(contentWithMultipleSections);
|
|
264
|
-
const result = handleGetComponentProps(args);
|
|
265
|
-
expect(result.content[0].text).toContain('Props');
|
|
266
|
-
expect(result.content[0].text).toContain('API');
|
|
267
|
-
expect(result.content[0].text).toContain('Properties');
|
|
268
|
-
expect(result.content[0].text).toContain('mode');
|
|
269
|
-
});
|
|
270
|
-
});
|
|
271
|
-
describe('handleListComponents', () => {
|
|
272
|
-
const mockMarkdownFiles = [
|
|
273
|
-
'components-button-docs.md',
|
|
274
|
-
'components-input-docs.md',
|
|
275
|
-
'components-table-docs.md',
|
|
276
|
-
'foundations-colors-docs.md',
|
|
277
|
-
'foundations-typography-docs.md',
|
|
278
|
-
'resources-icons-docs.md',
|
|
279
|
-
];
|
|
280
|
-
it('should list all components by default', () => {
|
|
281
|
-
const args = {};
|
|
282
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
283
|
-
const result = handleListComponents(args);
|
|
284
|
-
expect(result.content).toHaveLength(1);
|
|
285
|
-
expect(result.content[0].type).toBe('text');
|
|
286
|
-
expect(result.content[0].text).toContain('**IDS Component Library**');
|
|
287
|
-
expect(result.content[0].text).toContain('**Components (3)**');
|
|
288
|
-
expect(result.content[0].text).toContain('- button');
|
|
289
|
-
expect(result.content[0].text).toContain('- input');
|
|
290
|
-
expect(result.content[0].text).toContain('- table');
|
|
291
|
-
expect(result.content[0].text).toContain('**Foundations (2)**');
|
|
292
|
-
expect(result.content[0].text).toContain('- colors');
|
|
293
|
-
expect(result.content[0].text).toContain('- typography');
|
|
294
|
-
expect(result.content[0].text).toContain('**Resources (1)**');
|
|
295
|
-
expect(result.content[0].text).toContain('- icons');
|
|
296
|
-
});
|
|
297
|
-
it('should list only components when category is "components"', () => {
|
|
298
|
-
const args = {
|
|
299
|
-
category: 'components',
|
|
300
|
-
};
|
|
301
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
302
|
-
const result = handleListComponents(args);
|
|
303
|
-
expect(result.content[0].text).toContain('**Components (3)**');
|
|
304
|
-
expect(result.content[0].text).toContain('- button');
|
|
305
|
-
expect(result.content[0].text).toContain('- input');
|
|
306
|
-
expect(result.content[0].text).toContain('- table');
|
|
307
|
-
expect(result.content[0].text).not.toContain('**Foundations');
|
|
308
|
-
expect(result.content[0].text).not.toContain('**Resources');
|
|
309
|
-
});
|
|
310
|
-
it('should list only foundations when category is "foundations"', () => {
|
|
311
|
-
const args = {
|
|
312
|
-
category: 'foundations',
|
|
313
|
-
};
|
|
314
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
315
|
-
const result = handleListComponents(args);
|
|
316
|
-
expect(result.content[0].text).toContain('**Foundations (2)**');
|
|
317
|
-
expect(result.content[0].text).toContain('- colors');
|
|
318
|
-
expect(result.content[0].text).toContain('- typography');
|
|
319
|
-
expect(result.content[0].text).not.toContain('**Components');
|
|
320
|
-
expect(result.content[0].text).not.toContain('**Resources');
|
|
321
|
-
});
|
|
322
|
-
it('should list only resources when category is "resources"', () => {
|
|
323
|
-
const args = {
|
|
324
|
-
category: 'resources',
|
|
325
|
-
};
|
|
326
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
327
|
-
const result = handleListComponents(args);
|
|
328
|
-
expect(result.content[0].text).toContain('**Resources (1)**');
|
|
329
|
-
expect(result.content[0].text).toContain('- icons');
|
|
330
|
-
expect(result.content[0].text).not.toContain('**Components');
|
|
331
|
-
expect(result.content[0].text).not.toContain('**Foundations');
|
|
332
|
-
});
|
|
333
|
-
it('should list all categories when category is "all"', () => {
|
|
334
|
-
const args = {
|
|
335
|
-
category: 'all',
|
|
336
|
-
};
|
|
337
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
338
|
-
const result = handleListComponents(args);
|
|
339
|
-
expect(result.content[0].text).toContain('**Components (3)**');
|
|
340
|
-
expect(result.content[0].text).toContain('**Foundations (2)**');
|
|
341
|
-
expect(result.content[0].text).toContain('**Resources (1)**');
|
|
342
|
-
});
|
|
343
|
-
it('should handle empty file lists', () => {
|
|
344
|
-
const args = {
|
|
345
|
-
category: 'components',
|
|
346
|
-
};
|
|
347
|
-
mockUtils.getMarkdownFiles.mockReturnValue([]);
|
|
348
|
-
const result = handleListComponents(args);
|
|
349
|
-
expect(result.content[0].text).toContain('**Components (0)**');
|
|
350
|
-
});
|
|
351
|
-
it('should validate category parameter using zod schema', () => {
|
|
352
|
-
const invalidArgs = {
|
|
353
|
-
category: 'invalid-category', // Should be enum value
|
|
354
|
-
};
|
|
355
|
-
expect(() => handleListComponents(invalidArgs)).toThrow();
|
|
356
|
-
});
|
|
357
|
-
it('should use default category when not specified', () => {
|
|
358
|
-
const args = {};
|
|
359
|
-
mockUtils.getMarkdownFiles.mockReturnValue(mockMarkdownFiles);
|
|
360
|
-
const result = handleListComponents(args);
|
|
361
|
-
// Should default to 'all' and show all categories
|
|
362
|
-
expect(result.content[0].text).toContain('**Components');
|
|
363
|
-
expect(result.content[0].text).toContain('**Foundations');
|
|
364
|
-
expect(result.content[0].text).toContain('**Resources');
|
|
365
|
-
});
|
|
366
|
-
it('should properly format component names by removing prefixes and suffixes', () => {
|
|
367
|
-
const customFiles = [
|
|
368
|
-
'components-complex-button-component-docs.md',
|
|
369
|
-
'foundations-design-tokens-docs.md',
|
|
370
|
-
'resources-icon-library-docs.md',
|
|
371
|
-
];
|
|
372
|
-
const args = {};
|
|
373
|
-
mockUtils.getMarkdownFiles.mockReturnValue(customFiles);
|
|
374
|
-
const result = handleListComponents(args);
|
|
375
|
-
expect(result.content[0].text).toContain('- complex-button-component');
|
|
376
|
-
expect(result.content[0].text).toContain('- design-tokens');
|
|
377
|
-
expect(result.content[0].text).toContain('- icon-library');
|
|
378
|
-
});
|
|
379
|
-
});
|
|
380
|
-
});
|
package/dist/index.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
-
import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
-
import { SERVER_CONFIG, CAPABILITIES } from './config.js';
|
|
6
|
-
import { toolDefinitions } from './tools.js';
|
|
7
|
-
import { handleToolCall } from './toolHandler.js';
|
|
8
|
-
import { handleListResources, handleReadResource } from './resourceHandlers.js';
|
|
9
|
-
/**
|
|
10
|
-
* Create MCP server for Iress Design System (IDS) component library context
|
|
11
|
-
*/
|
|
12
|
-
const server = new Server(SERVER_CONFIG, { capabilities: CAPABILITIES });
|
|
13
|
-
/**
|
|
14
|
-
* List available IDS component documentation resources
|
|
15
|
-
*/
|
|
16
|
-
server.setRequestHandler(ListResourcesRequestSchema, () => {
|
|
17
|
-
const result = handleListResources();
|
|
18
|
-
return result;
|
|
19
|
-
});
|
|
20
|
-
/**
|
|
21
|
-
* Read content from a specific markdown file
|
|
22
|
-
*/
|
|
23
|
-
server.setRequestHandler(ReadResourceRequestSchema, (request) => {
|
|
24
|
-
const result = handleReadResource(request);
|
|
25
|
-
return result;
|
|
26
|
-
});
|
|
27
|
-
/**
|
|
28
|
-
* List available IDS development tools
|
|
29
|
-
*/
|
|
30
|
-
server.setRequestHandler(ListToolsRequestSchema, () => {
|
|
31
|
-
return {
|
|
32
|
-
tools: toolDefinitions,
|
|
33
|
-
};
|
|
34
|
-
});
|
|
35
|
-
/**
|
|
36
|
-
* Handle IDS component library tool calls
|
|
37
|
-
*/
|
|
38
|
-
server.setRequestHandler(CallToolRequestSchema, (request) => {
|
|
39
|
-
const result = handleToolCall(request);
|
|
40
|
-
return result;
|
|
41
|
-
});
|
|
42
|
-
/**
|
|
43
|
-
* Start the server
|
|
44
|
-
*/
|
|
45
|
-
async function main() {
|
|
46
|
-
const transport = new StdioServerTransport();
|
|
47
|
-
await server.connect(transport);
|
|
48
|
-
console.error('IDS Component Library MCP Server running on stdio');
|
|
49
|
-
}
|
|
50
|
-
main().catch((error) => {
|
|
51
|
-
console.error('Server error:', error);
|
|
52
|
-
process.exit(1);
|
|
53
|
-
});
|