@aleph-alpha/ui-library 1.10.0 → 1.11.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.
package/dist/mcp/index.js DELETED
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env node
2
- import { startServer } from './server.js';
3
-
4
- startServer().catch((error) => {
5
- console.error('Failed to start MCP server:', error);
6
- process.exit(1);
7
- });
@@ -1,236 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // mcp/scripts/generate-component-meta.ts
4
- import * as fs4 from "node:fs";
5
- import * as path3 from "node:path";
6
- import { fileURLToPath as fileURLToPath2 } from "node:url";
7
-
8
- // mcp/constants.ts
9
- import * as fs3 from "node:fs";
10
- import * as path2 from "node:path";
11
-
12
- // mcp/utils/paths.ts
13
- import * as fs from "node:fs";
14
- import * as path from "node:path";
15
- import { fileURLToPath } from "node:url";
16
- var __filename = fileURLToPath(import.meta.url);
17
- var __dirname = path.dirname(__filename);
18
- function getLibrarySourcePath() {
19
- const possiblePaths = [
20
- // Bundled: from dist/mcp/ -> ../../src
21
- path.resolve(__dirname, "../../src"),
22
- // Fallback: running from package root
23
- path.join(process.cwd(), "src")
24
- ];
25
- for (const srcPath of possiblePaths) {
26
- if (fs.existsSync(srcPath)) {
27
- return srcPath;
28
- }
29
- }
30
- throw new Error(
31
- "Could not find UI library source directory. Is the package installed correctly?"
32
- );
33
- }
34
-
35
- // mcp/utils/file-utils.ts
36
- import * as fs2 from "node:fs";
37
-
38
- // mcp/constants.ts
39
- function detectCategoryDirs() {
40
- const srcPath = getSrcPath();
41
- if (!srcPath || !fs3.existsSync(srcPath)) {
42
- return [];
43
- }
44
- const entries = fs3.readdirSync(srcPath, { withFileTypes: true });
45
- return entries.filter((entry) => entry.isDirectory()).filter((entry) => !entry.name.startsWith(".") && entry.name !== "node_modules").filter((entry) => {
46
- try {
47
- const dirPath = path2.join(srcPath, entry.name);
48
- const subEntries = fs3.readdirSync(dirPath, { withFileTypes: true });
49
- return subEntries.some((sub) => sub.isDirectory() && sub.name.startsWith("Ui"));
50
- } catch {
51
- return false;
52
- }
53
- }).map((entry) => entry.name);
54
- }
55
- var cachedCategoryDirs = null;
56
- function getCategoryDirs() {
57
- if (cachedCategoryDirs) return cachedCategoryDirs;
58
- cachedCategoryDirs = detectCategoryDirs();
59
- return cachedCategoryDirs;
60
- }
61
- function getSrcPath() {
62
- try {
63
- return getLibrarySourcePath();
64
- } catch {
65
- return null;
66
- }
67
- }
68
-
69
- // mcp/scripts/generate-component-meta.ts
70
- function escapeRegex(str) {
71
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
72
- }
73
- var __filename2 = fileURLToPath2(import.meta.url);
74
- var __dirname2 = path3.dirname(__filename2);
75
- var PACKAGE_ROOT = path3.resolve(__dirname2, "../../..");
76
- var SRC_PATH = path3.join(PACKAGE_ROOT, "src");
77
- var OUTPUT_PATH = path3.join(PACKAGE_ROOT, "mcp", "components-meta.json");
78
- function extractJSDocTags(content, interfaceName) {
79
- const declarationRegex = new RegExp(
80
- `export\\s+(?:interface|type)\\s+${escapeRegex(interfaceName)}\\b`
81
- );
82
- const declarationMatch = content.match(declarationRegex);
83
- if (!declarationMatch || declarationMatch.index === void 0) {
84
- return { description: "", useCases: [], keywords: [], related: [] };
85
- }
86
- const contentBefore = content.substring(0, declarationMatch.index);
87
- const jsdocEndIndex = contentBefore.lastIndexOf("*/");
88
- if (jsdocEndIndex === -1) {
89
- return { description: "", useCases: [], keywords: [], related: [] };
90
- }
91
- const betweenJsdocAndDeclaration = contentBefore.substring(jsdocEndIndex + 2);
92
- if (betweenJsdocAndDeclaration.trim() !== "") {
93
- return { description: "", useCases: [], keywords: [], related: [] };
94
- }
95
- const jsdocStartIndex = contentBefore.lastIndexOf("/**");
96
- if (jsdocStartIndex === -1 || jsdocStartIndex > jsdocEndIndex) {
97
- return { description: "", useCases: [], keywords: [], related: [] };
98
- }
99
- const jsdoc = contentBefore.substring(jsdocStartIndex + 3, jsdocEndIndex);
100
- const lines = jsdoc.split("\n").map((l) => l.replace(/^\s*\*\s?/, "").trim());
101
- let description = "";
102
- const useCases = [];
103
- const keywords = [];
104
- const related = [];
105
- let category;
106
- for (const line of lines) {
107
- if (line.startsWith("@useCases") || line.startsWith("@use-cases")) {
108
- const values = line.replace(/@use-?[cC]ases\s*/, "").split(",").map((s) => s.trim()).filter(Boolean);
109
- useCases.push(...values);
110
- } else if (line.startsWith("@keywords")) {
111
- const values = line.replace(/@keywords\s*/, "").split(",").map((s) => s.trim()).filter(Boolean);
112
- keywords.push(...values);
113
- } else if (line.startsWith("@related")) {
114
- const values = line.replace(/@related\s*/, "").split(",").map((s) => s.trim()).filter(Boolean);
115
- related.push(...values);
116
- } else if (line.startsWith("@category")) {
117
- category = line.replace(/@category\s*/, "").trim();
118
- } else if (!line.startsWith("@") && line) {
119
- description += (description ? " " : "") + line;
120
- }
121
- }
122
- return { description, useCases, keywords, related, category };
123
- }
124
- function extractKeywordsFromName(componentName) {
125
- const name = componentName.replace(/^Ui/, "");
126
- return name.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().split(/\s+/).filter((word) => word.length > 2);
127
- }
128
- function extractProps(content, interfaceName) {
129
- const regex = new RegExp(
130
- `export\\s+interface\\s+${escapeRegex(interfaceName)}\\s*\\{([\\s\\S]*?)\\n\\}`,
131
- "m"
132
- );
133
- const match = content.match(regex);
134
- if (!match) return [];
135
- const interfaceBody = match[1].replace(/\/\*\*[\s\S]*?\*\//g, "");
136
- const propRegex = /^\s*(\w+)\??:/gm;
137
- const props = [];
138
- let propMatch;
139
- while ((propMatch = propRegex.exec(interfaceBody)) !== null) {
140
- props.push(propMatch[1]);
141
- }
142
- return [...new Set(props)];
143
- }
144
- function extractExamples(storiesPath) {
145
- if (!fs4.existsSync(storiesPath)) return [];
146
- const content = fs4.readFileSync(storiesPath, "utf-8");
147
- const examples = [];
148
- const storyRegex = /export\s+const\s+(\w+):\s*Story/g;
149
- let match;
150
- while ((match = storyRegex.exec(content)) !== null) {
151
- if (match[1] !== "default") {
152
- examples.push(match[1]);
153
- }
154
- }
155
- return examples;
156
- }
157
- function processComponent(componentDir, componentName) {
158
- const typesPath = path3.join(componentDir, "types.ts");
159
- const storiesPath = path3.join(componentDir, `${componentName}.stories.ts`);
160
- let typesContent = "";
161
- if (fs4.existsSync(typesPath)) {
162
- typesContent = fs4.readFileSync(typesPath, "utf-8");
163
- }
164
- const escapedName = escapeRegex(componentName);
165
- const exactPropsRegex = new RegExp(`export\\s+(?:interface|type)\\s+(${escapedName}Props)\\b`);
166
- const exactMatch = typesContent.match(exactPropsRegex);
167
- const subComponentPropsRegex = new RegExp(
168
- `export\\s+(?:interface|type)\\s+(${escapedName}\\w*Props)\\b`
169
- );
170
- const subComponentMatch = typesContent.match(subComponentPropsRegex);
171
- const anyPropsMatch = typesContent.match(/export\s+(?:interface|type)\s+(Ui\w+Props)/);
172
- const interfaceName = exactMatch?.[1] || subComponentMatch?.[1] || anyPropsMatch?.[1] || `${componentName}Props`;
173
- const jsdocData = extractJSDocTags(typesContent, interfaceName);
174
- const nameKeywords = extractKeywordsFromName(componentName);
175
- const keywords = jsdocData.keywords.length > 0 ? jsdocData.keywords : nameKeywords;
176
- const category = jsdocData.category || "Uncategorized";
177
- if (!jsdocData.category) {
178
- console.warn(
179
- ` \u26A0\uFE0F ${componentName}: Missing @category in types.ts. See docs/CONTRIBUTION_GUIDELINES.md`
180
- );
181
- }
182
- const props = extractProps(typesContent, interfaceName);
183
- const examples = extractExamples(storiesPath);
184
- return {
185
- description: jsdocData.description || `${componentName} component`,
186
- category,
187
- useCases: jsdocData.useCases,
188
- keywords: [.../* @__PURE__ */ new Set([...keywords, ...nameKeywords])],
189
- related: jsdocData.related,
190
- props,
191
- examples,
192
- _autoGenerated: true
193
- };
194
- }
195
- function scanComponents() {
196
- const meta = {};
197
- for (const category of getCategoryDirs()) {
198
- const categoryPath = path3.join(SRC_PATH, category);
199
- if (!fs4.existsSync(categoryPath)) continue;
200
- const entries = fs4.readdirSync(categoryPath, { withFileTypes: true });
201
- for (const entry of entries) {
202
- if (!entry.isDirectory()) continue;
203
- if (!entry.name.startsWith("Ui")) continue;
204
- if (entry.name === "shadcn") continue;
205
- const componentDir = path3.join(categoryPath, entry.name);
206
- const componentMeta = processComponent(componentDir, entry.name);
207
- if (componentMeta) {
208
- meta[entry.name] = componentMeta;
209
- }
210
- }
211
- }
212
- return meta;
213
- }
214
- function main() {
215
- console.log("Scanning components...");
216
- const meta = scanComponents();
217
- console.log(`Found ${Object.keys(meta).length} components`);
218
- console.log(`Writing to ${OUTPUT_PATH}...`);
219
- fs4.writeFileSync(OUTPUT_PATH, JSON.stringify(meta, null, 2));
220
- console.log("Done!");
221
- const withUseCases = Object.values(meta).filter((m) => m.useCases.length > 0).length;
222
- const withKeywords = Object.values(meta).filter((m) => m.keywords.length > 0).length;
223
- console.log(`
224
- Summary:`);
225
- console.log(` Components with @useCases: ${withUseCases}/${Object.keys(meta).length}`);
226
- console.log(` Components with keywords: ${withKeywords}/${Object.keys(meta).length}`);
227
- }
228
- var isMain = import.meta.url === `file://${process.argv[1]}`;
229
- if (isMain) {
230
- main();
231
- }
232
- export {
233
- extractJSDocTags,
234
- extractKeywordsFromName,
235
- extractProps
236
- };