@splunk/splunk-ui-mcp 0.1.0 → 0.2.0

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.
Files changed (33) hide show
  1. package/README.md +10 -3
  2. package/lib/constants/versions.js +3 -3
  3. package/lib/index.js +6 -4
  4. package/lib/resources/components.js +12 -6
  5. package/lib/resources/design-tokens.d.ts +17 -0
  6. package/lib/resources/design-tokens.js +113 -0
  7. package/lib/tools/find_component.d.ts +19 -0
  8. package/lib/tools/find_component.js +93 -0
  9. package/lib/tools/find_design_token.d.ts +16 -0
  10. package/lib/tools/find_design_token.js +126 -0
  11. package/lib/tools/{find_icons.d.ts → find_icon.d.ts} +2 -2
  12. package/lib/tools/{find_icons.js → find_icon.js} +5 -5
  13. package/lib/utils/component-catalog.d.ts +19 -2
  14. package/lib/utils/component-catalog.js +77 -29
  15. package/lib/utils/design-token-catalog.d.ts +33 -0
  16. package/lib/utils/design-token-catalog.js +158 -0
  17. package/lib/utils/package-assets.d.ts +8 -0
  18. package/lib/utils/package-assets.js +35 -0
  19. package/package.json +14 -10
  20. package/lib/resources/tests/components.unit.d.ts +0 -1
  21. package/lib/resources/tests/components.unit.js +0 -133
  22. package/lib/resources/tests/icons.unit.d.ts +0 -1
  23. package/lib/resources/tests/icons.unit.js +0 -161
  24. package/lib/tools/get_component_docs.d.ts +0 -19
  25. package/lib/tools/get_component_docs.js +0 -82
  26. package/lib/tools/tests/find_icons.unit.d.ts +0 -1
  27. package/lib/tools/tests/find_icons.unit.js +0 -149
  28. package/lib/tools/tests/get_component_docs.unit.d.ts +0 -1
  29. package/lib/tools/tests/get_component_docs.unit.js +0 -131
  30. package/lib/tools/tests/requirements.unit.d.ts +0 -1
  31. package/lib/tools/tests/requirements.unit.js +0 -34
  32. package/lib/utils/tests/component-catalog.unit.d.ts +0 -1
  33. package/lib/utils/tests/component-catalog.unit.js +0 -144
@@ -1,144 +0,0 @@
1
- import { beforeEach, describe, expect, it, vi } from 'vitest';
2
- const MOCK_LLMS_TXT = `# React UI (@splunk/react-ui)
3
-
4
- A library of UI components, all independent of the Splunk Enterprise environment.
5
-
6
- ## Base
7
-
8
- - **Anchor**
9
- - **Avatar**
10
- - **Button**
11
- - **Card Layout**
12
-
13
- ## Content
14
-
15
- - **Heading**
16
- - **Paragraph**
17
-
18
- ## Deprecated
19
-
20
- - **Accordion**
21
- `;
22
- const MOCK_BUTTON_DOCS = `# Button
23
-
24
- ## Overview
25
-
26
- A button component for triggering actions.
27
-
28
- ## Examples
29
-
30
- \`\`\`typescript
31
- import Button from '@splunk/react-ui/Button';
32
- \`\`\`
33
- `;
34
- // Mock file system operations
35
- vi.mock('fs', () => ({
36
- readFileSync: vi.fn((path) => {
37
- if (path.includes('llms.txt')) {
38
- return MOCK_LLMS_TXT;
39
- }
40
- if (path.includes('Button.md')) {
41
- return MOCK_BUTTON_DOCS;
42
- }
43
- throw new Error(`File not found: ${path}`);
44
- }),
45
- }));
46
- describe('component-catalog', () => {
47
- beforeEach(async () => {
48
- vi.resetModules();
49
- const { setDocsLlmPath } = await import("../component-catalog.js");
50
- setDocsLlmPath('/mocked/docs-llm');
51
- });
52
- describe('getComponentList', () => {
53
- it('parses components from llms.txt', async () => {
54
- const { getComponentList } = await import("../component-catalog.js");
55
- const components = getComponentList();
56
- expect(components).toHaveLength(7);
57
- expect(components[0]).toEqual({
58
- name: 'Anchor',
59
- filename: 'Anchor.md',
60
- category: 'Base',
61
- });
62
- expect(components[2]).toEqual({
63
- name: 'Button',
64
- filename: 'Button.md',
65
- category: 'Base',
66
- });
67
- });
68
- it('preserves category information', async () => {
69
- const { getComponentList } = await import("../component-catalog.js");
70
- const components = getComponentList();
71
- const heading = components.find((c) => c.name === 'Heading');
72
- expect(heading?.category).toBe('Content');
73
- const accordion = components.find((c) => c.name === 'Accordion');
74
- expect(accordion?.category).toBe('Deprecated');
75
- });
76
- it('caches the result on subsequent calls', async () => {
77
- // Need to clear mocks and reload in this test to accurately count calls
78
- vi.clearAllMocks();
79
- vi.resetModules();
80
- const { readFileSync } = await import('fs');
81
- const { setDocsLlmPath, getComponentList } = await import("../component-catalog.js");
82
- setDocsLlmPath('/mocked/docs-llm');
83
- getComponentList();
84
- getComponentList();
85
- getComponentList();
86
- // Should only read the llms.txt file once (cached after first read)
87
- const llmsTxtCalls = readFileSync.mock.calls.filter((call) => call[0].includes('llms.txt'));
88
- expect(llmsTxtCalls).toHaveLength(1);
89
- });
90
- });
91
- describe('componentExists', () => {
92
- it('returns true for components in the catalog', async () => {
93
- const { componentExists } = await import("../component-catalog.js");
94
- expect(componentExists('Button')).toBe(true);
95
- expect(componentExists('Heading')).toBe(true);
96
- });
97
- it('returns false for components not in the catalog', async () => {
98
- const { componentExists } = await import("../component-catalog.js");
99
- expect(componentExists('NonExistent')).toBe(false);
100
- expect(componentExists('Unknown')).toBe(false);
101
- });
102
- });
103
- describe('getComponentInfo', () => {
104
- it('returns component info for existing components', async () => {
105
- const { getComponentInfo } = await import("../component-catalog.js");
106
- const buttonInfo = getComponentInfo('Button');
107
- expect(buttonInfo).toEqual({
108
- name: 'Button',
109
- filename: 'Button.md',
110
- category: 'Base',
111
- });
112
- });
113
- it('returns undefined for non-existent components', async () => {
114
- const { getComponentInfo } = await import("../component-catalog.js");
115
- expect(getComponentInfo('NonExistent')).toBeUndefined();
116
- });
117
- });
118
- describe('getComponentDocs', () => {
119
- it('reads and returns markdown documentation', async () => {
120
- const { getComponentDocs } = await import("../component-catalog.js");
121
- const docs = getComponentDocs('Button');
122
- expect(docs).toBe(MOCK_BUTTON_DOCS);
123
- });
124
- it('throws error for non-existent component', async () => {
125
- const { getComponentDocs } = await import("../component-catalog.js");
126
- expect(() => getComponentDocs('NonExistent')).toThrow('Component "NonExistent" not found in catalog');
127
- });
128
- it('rejects component names with path separators', async () => {
129
- const { getComponentDocs } = await import("../component-catalog.js");
130
- expect(() => getComponentDocs('some/path/Button')).toThrow(/Invalid component name/);
131
- expect(() => getComponentDocs('some\\path\\Button')).toThrow(/Invalid component name/);
132
- });
133
- it('rejects component names with parent directory references', async () => {
134
- const { getComponentDocs } = await import("../component-catalog.js");
135
- expect(() => getComponentDocs('../../etc/passwd')).toThrow(/Invalid component name/);
136
- expect(() => getComponentDocs('Button/../../../etc/passwd')).toThrow(/Invalid component name/);
137
- });
138
- it('rejects absolute paths', async () => {
139
- const { getComponentDocs } = await import("../component-catalog.js");
140
- expect(() => getComponentDocs('/etc/passwd')).toThrow(/Invalid component name/);
141
- expect(() => getComponentDocs('C:\\Windows\\System32\\config\\sam')).toThrow(/Invalid component name/);
142
- });
143
- });
144
- });