@aleph-alpha/lib-mcp 1.6.0 → 1.6.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/dist/cli.js +170 -10
- package/dist/server.js +170 -10
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -21129,6 +21129,7 @@ import * as path5 from "node:path";
|
|
|
21129
21129
|
|
|
21130
21130
|
// src/readers/types-reader.ts
|
|
21131
21131
|
import * as path2 from "node:path";
|
|
21132
|
+
var TYPE_OR_INTERFACE = "(?:interface|type)";
|
|
21132
21133
|
function parseJSDoc(comment) {
|
|
21133
21134
|
const lines = comment.replace(/\/\*\*|\*\/|\*/g, "").split("\n").map((line) => line.trim()).filter(Boolean);
|
|
21134
21135
|
let description = "";
|
|
@@ -21169,7 +21170,7 @@ function extractType(text2, startIndex) {
|
|
|
21169
21170
|
function parseInterface(content, interfaceName) {
|
|
21170
21171
|
const props = [];
|
|
21171
21172
|
const interfaceRegex = new RegExp(
|
|
21172
|
-
`export\\s+
|
|
21173
|
+
`(?:export\\s+)?${TYPE_OR_INTERFACE}\\s+${interfaceName}\\s*(?:extends\\s+[^{]+)?(?:=\\s*)?\\{([\\s\\S]*?)\\n\\}`,
|
|
21173
21174
|
"m"
|
|
21174
21175
|
);
|
|
21175
21176
|
const match = content.match(interfaceRegex);
|
|
@@ -21201,7 +21202,7 @@ function parseInterface(content, interfaceName) {
|
|
|
21201
21202
|
function extractComponentDescription(content, interfaceName) {
|
|
21202
21203
|
const lines = content.split("\n");
|
|
21203
21204
|
const interfaceLineIndex = lines.findIndex(
|
|
21204
|
-
(line) => line.match(new RegExp(`export\\s
|
|
21205
|
+
(line) => line.match(new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+${interfaceName}`))
|
|
21205
21206
|
);
|
|
21206
21207
|
if (interfaceLineIndex === -1) {
|
|
21207
21208
|
return "";
|
|
@@ -21226,28 +21227,67 @@ function extractComponentDescription(content, interfaceName) {
|
|
|
21226
21227
|
}
|
|
21227
21228
|
return "";
|
|
21228
21229
|
}
|
|
21229
|
-
function
|
|
21230
|
+
function resolveUnionOrIntersectionProps(content, typeName) {
|
|
21231
|
+
const typeDefRegex = new RegExp(`export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`);
|
|
21232
|
+
const match = content.match(typeDefRegex);
|
|
21233
|
+
if (!match) return [];
|
|
21234
|
+
const referencedTypes = match[1].split(/[|&]/).map((t) => t.trim()).filter((t) => t.endsWith("Props"));
|
|
21235
|
+
if (referencedTypes.length === 0) return [];
|
|
21236
|
+
const firstBranch = referencedTypes[0];
|
|
21237
|
+
const extendsRegex = new RegExp(
|
|
21238
|
+
`(?:export\\s+)?${TYPE_OR_INTERFACE}\\s+${firstBranch}\\s+extends\\s+(\\w+)`
|
|
21239
|
+
);
|
|
21240
|
+
const extendsMatch = content.match(extendsRegex);
|
|
21241
|
+
const allProps = [];
|
|
21242
|
+
if (extendsMatch) {
|
|
21243
|
+
allProps.push(...parseInterface(content, extendsMatch[1]));
|
|
21244
|
+
}
|
|
21245
|
+
allProps.push(...parseInterface(content, firstBranch));
|
|
21246
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21247
|
+
return allProps.filter((p) => {
|
|
21248
|
+
if (seen.has(p.name)) return false;
|
|
21249
|
+
seen.add(p.name);
|
|
21250
|
+
return true;
|
|
21251
|
+
});
|
|
21252
|
+
}
|
|
21253
|
+
function readTypesFile(filePath, componentName) {
|
|
21230
21254
|
const content = readTextFile(filePath);
|
|
21231
21255
|
if (!content) {
|
|
21232
21256
|
return null;
|
|
21233
21257
|
}
|
|
21234
|
-
const
|
|
21258
|
+
const resolvedName = componentName || path2.basename(path2.dirname(filePath));
|
|
21259
|
+
const exactRegex = new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}Props)\\b`);
|
|
21260
|
+
let propsInterfaceMatch = content.match(exactRegex);
|
|
21261
|
+
if (!propsInterfaceMatch) {
|
|
21262
|
+
const prefixRegex = new RegExp(
|
|
21263
|
+
`export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}\\w*Props)\\b`
|
|
21264
|
+
);
|
|
21265
|
+
propsInterfaceMatch = content.match(prefixRegex);
|
|
21266
|
+
}
|
|
21267
|
+
if (!propsInterfaceMatch) {
|
|
21268
|
+
propsInterfaceMatch = content.match(
|
|
21269
|
+
new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+(Ui\\w+Props)\\b`)
|
|
21270
|
+
);
|
|
21271
|
+
}
|
|
21235
21272
|
if (!propsInterfaceMatch) {
|
|
21236
21273
|
return null;
|
|
21237
21274
|
}
|
|
21238
21275
|
const interfaceName = propsInterfaceMatch[1];
|
|
21239
|
-
const
|
|
21276
|
+
const matchedComponentName = interfaceName.replace("Props", "");
|
|
21240
21277
|
const description = extractComponentDescription(content, interfaceName);
|
|
21241
|
-
|
|
21278
|
+
let props = parseInterface(content, interfaceName);
|
|
21279
|
+
if (props.length === 0) {
|
|
21280
|
+
props = resolveUnionOrIntersectionProps(content, interfaceName);
|
|
21281
|
+
}
|
|
21242
21282
|
return {
|
|
21243
|
-
name:
|
|
21283
|
+
name: matchedComponentName,
|
|
21244
21284
|
description,
|
|
21245
21285
|
props
|
|
21246
21286
|
};
|
|
21247
21287
|
}
|
|
21248
21288
|
function readComponentTypes(componentDir) {
|
|
21249
21289
|
const typesPath = path2.join(componentDir, "types.ts");
|
|
21250
|
-
return readTypesFile(typesPath);
|
|
21290
|
+
return readTypesFile(typesPath, path2.basename(componentDir));
|
|
21251
21291
|
}
|
|
21252
21292
|
|
|
21253
21293
|
// src/constants.ts
|
|
@@ -21460,6 +21500,40 @@ function extractStories(content) {
|
|
|
21460
21500
|
}
|
|
21461
21501
|
return stories;
|
|
21462
21502
|
}
|
|
21503
|
+
function extractInlineRenderTemplates(content) {
|
|
21504
|
+
const examples = [];
|
|
21505
|
+
const storyExportRegex = /export\s+const\s+(\w+):\s*Story\s*=/g;
|
|
21506
|
+
let match;
|
|
21507
|
+
while ((match = storyExportRegex.exec(content)) !== null) {
|
|
21508
|
+
const storyName = match[1];
|
|
21509
|
+
if (storyName === "default") continue;
|
|
21510
|
+
const afterEquals = content.indexOf("{", match.index + match[0].length);
|
|
21511
|
+
if (afterEquals === -1) continue;
|
|
21512
|
+
const closingBrace = findMatchingBrace(content, afterEquals);
|
|
21513
|
+
if (closingBrace === -1) continue;
|
|
21514
|
+
const storyBlock = content.slice(afterEquals, closingBrace + 1);
|
|
21515
|
+
if (!storyBlock.includes("template:")) continue;
|
|
21516
|
+
const templateMatch = storyBlock.match(/template:\s*`([\s\S]*?)`/);
|
|
21517
|
+
if (!templateMatch) continue;
|
|
21518
|
+
const template = templateMatch[1].trim();
|
|
21519
|
+
if (!template) continue;
|
|
21520
|
+
const componentsMatch = storyBlock.match(/components:\s*\{([^}]+)\}/);
|
|
21521
|
+
const componentNames = componentsMatch ? componentsMatch[1].split(",").map((c) => c.trim()).filter(Boolean) : [];
|
|
21522
|
+
const imports = componentNames.length > 0 ? `<script setup>
|
|
21523
|
+
// Components: ${componentNames.join(", ")}
|
|
21524
|
+
</script>
|
|
21525
|
+
|
|
21526
|
+
` : "";
|
|
21527
|
+
examples.push({
|
|
21528
|
+
name: storyName,
|
|
21529
|
+
description: "",
|
|
21530
|
+
code: `${imports}<template>
|
|
21531
|
+
${template}
|
|
21532
|
+
</template>`
|
|
21533
|
+
});
|
|
21534
|
+
}
|
|
21535
|
+
return examples;
|
|
21536
|
+
}
|
|
21463
21537
|
function extractArgTypes(content) {
|
|
21464
21538
|
const argTypes = [];
|
|
21465
21539
|
const argTypesKeyIndex = content.indexOf("argTypes");
|
|
@@ -21516,6 +21590,56 @@ function extractTitle(content) {
|
|
|
21516
21590
|
const titleMatch = content.match(/title:\s*['"]([^'"]+)['"]/);
|
|
21517
21591
|
return titleMatch ? titleMatch[1] : "";
|
|
21518
21592
|
}
|
|
21593
|
+
function extractMetaArgs(content) {
|
|
21594
|
+
const metaDefaultIndex = content.indexOf("export default");
|
|
21595
|
+
if (metaDefaultIndex === -1) return void 0;
|
|
21596
|
+
const metaSection = content.slice(0, metaDefaultIndex);
|
|
21597
|
+
const argsKeyIndex = metaSection.lastIndexOf("args:");
|
|
21598
|
+
if (argsKeyIndex !== -1) {
|
|
21599
|
+
return extractArgsFromPosition(content, argsKeyIndex);
|
|
21600
|
+
}
|
|
21601
|
+
const afterExport = content.slice(metaDefaultIndex + "export default".length);
|
|
21602
|
+
const trimmed = afterExport.trimStart();
|
|
21603
|
+
if (!trimmed.startsWith("{")) return void 0;
|
|
21604
|
+
const blockStart = content.indexOf("{", metaDefaultIndex);
|
|
21605
|
+
const blockEnd = findMatchingBrace(content, blockStart);
|
|
21606
|
+
if (blockEnd === -1) return void 0;
|
|
21607
|
+
const metaBlock = content.slice(blockStart + 1, blockEnd);
|
|
21608
|
+
const inlineArgsIndex = metaBlock.indexOf("args:");
|
|
21609
|
+
if (inlineArgsIndex === -1) return void 0;
|
|
21610
|
+
return extractArgsFromPosition(content, blockStart + 1 + inlineArgsIndex);
|
|
21611
|
+
}
|
|
21612
|
+
function extractArgsFromPosition(content, argsKeyIndex) {
|
|
21613
|
+
const colonIndex = content.indexOf(":", argsKeyIndex + 4);
|
|
21614
|
+
if (colonIndex === -1) {
|
|
21615
|
+
return void 0;
|
|
21616
|
+
}
|
|
21617
|
+
const openingBraceIndex = content.indexOf("{", colonIndex);
|
|
21618
|
+
if (openingBraceIndex === -1) {
|
|
21619
|
+
return void 0;
|
|
21620
|
+
}
|
|
21621
|
+
const closingBraceIndex = findMatchingBrace(content, openingBraceIndex);
|
|
21622
|
+
if (closingBraceIndex === -1) {
|
|
21623
|
+
return void 0;
|
|
21624
|
+
}
|
|
21625
|
+
const argsBlock = content.slice(openingBraceIndex + 1, closingBraceIndex);
|
|
21626
|
+
const args = {};
|
|
21627
|
+
const kvRegex = /(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|(\d+(?:\.\d+)?)|(\btrue\b|\bfalse\b))/g;
|
|
21628
|
+
let match;
|
|
21629
|
+
while ((match = kvRegex.exec(argsBlock)) !== null) {
|
|
21630
|
+
const key = match[1];
|
|
21631
|
+
if (match[2] !== void 0) {
|
|
21632
|
+
args[key] = match[2];
|
|
21633
|
+
} else if (match[3] !== void 0) {
|
|
21634
|
+
args[key] = match[3];
|
|
21635
|
+
} else if (match[4] !== void 0) {
|
|
21636
|
+
args[key] = Number(match[4]);
|
|
21637
|
+
} else if (match[5] !== void 0) {
|
|
21638
|
+
args[key] = match[5] === "true";
|
|
21639
|
+
}
|
|
21640
|
+
}
|
|
21641
|
+
return Object.keys(args).length > 0 ? args : void 0;
|
|
21642
|
+
}
|
|
21519
21643
|
function readStoriesFile(filePath) {
|
|
21520
21644
|
const content = readTextFile(filePath);
|
|
21521
21645
|
if (!content) {
|
|
@@ -21527,6 +21651,7 @@ function readStoriesFile(filePath) {
|
|
|
21527
21651
|
const storyTemplateMap = extractStories(content);
|
|
21528
21652
|
const examples = [];
|
|
21529
21653
|
const usageGuidance = [];
|
|
21654
|
+
const coveredStories = /* @__PURE__ */ new Set();
|
|
21530
21655
|
for (const [storyName, templateVar] of storyTemplateMap) {
|
|
21531
21656
|
const code = templateSources.get(templateVar);
|
|
21532
21657
|
const description = extractStoryJSDoc(content, storyName);
|
|
@@ -21536,16 +21661,29 @@ function readStoriesFile(filePath) {
|
|
|
21536
21661
|
description,
|
|
21537
21662
|
code
|
|
21538
21663
|
});
|
|
21664
|
+
coveredStories.add(storyName);
|
|
21539
21665
|
}
|
|
21540
21666
|
if (description) {
|
|
21541
21667
|
usageGuidance.push(description);
|
|
21542
21668
|
}
|
|
21543
21669
|
}
|
|
21670
|
+
const inlineExamples = extractInlineRenderTemplates(content);
|
|
21671
|
+
for (const example of inlineExamples) {
|
|
21672
|
+
if (!coveredStories.has(example.name)) {
|
|
21673
|
+
const description = extractStoryJSDoc(content, example.name);
|
|
21674
|
+
examples.push({ ...example, description });
|
|
21675
|
+
if (description) {
|
|
21676
|
+
usageGuidance.push(description);
|
|
21677
|
+
}
|
|
21678
|
+
}
|
|
21679
|
+
}
|
|
21680
|
+
const defaultArgs = extractMetaArgs(content);
|
|
21544
21681
|
return {
|
|
21545
21682
|
title,
|
|
21546
21683
|
examples,
|
|
21547
21684
|
argTypes,
|
|
21548
|
-
usageGuidance
|
|
21685
|
+
usageGuidance,
|
|
21686
|
+
defaultArgs
|
|
21549
21687
|
};
|
|
21550
21688
|
}
|
|
21551
21689
|
function readComponentStories(componentDir) {
|
|
@@ -21619,7 +21757,8 @@ function getComponentDocs(componentName) {
|
|
|
21619
21757
|
examples,
|
|
21620
21758
|
usageGuidance: [...new Set(usageGuidance)],
|
|
21621
21759
|
// Remove duplicates
|
|
21622
|
-
subComponents: subComponents && subComponents.length > 0 ? subComponents : void 0
|
|
21760
|
+
subComponents: subComponents && subComponents.length > 0 ? subComponents : void 0,
|
|
21761
|
+
defaultArgs: storiesInfo?.defaultArgs
|
|
21623
21762
|
};
|
|
21624
21763
|
}
|
|
21625
21764
|
|
|
@@ -21665,6 +21804,27 @@ function formatComponentDocs(docs) {
|
|
|
21665
21804
|
sections.push("## Props", "");
|
|
21666
21805
|
docs.props.forEach((prop) => sections.push(...formatProp(prop)));
|
|
21667
21806
|
}
|
|
21807
|
+
if (docs.defaultArgs && Object.keys(docs.defaultArgs).length > 0) {
|
|
21808
|
+
const filteredArgs = Object.entries(docs.defaultArgs).filter(([key, value]) => {
|
|
21809
|
+
const prop = docs.props.find((p) => p.name === key);
|
|
21810
|
+
if (!prop?.default) return true;
|
|
21811
|
+
return String(value) !== prop.default;
|
|
21812
|
+
});
|
|
21813
|
+
if (filteredArgs.length > 0) {
|
|
21814
|
+
sections.push("## Storybook Defaults", "");
|
|
21815
|
+
sections.push(
|
|
21816
|
+
"These are the recommended prop values used in the component's Storybook stories:",
|
|
21817
|
+
""
|
|
21818
|
+
);
|
|
21819
|
+
sections.push("| Prop | Value |");
|
|
21820
|
+
sections.push("|------|-------|");
|
|
21821
|
+
for (const [key, value] of filteredArgs) {
|
|
21822
|
+
const formatted = typeof value === "string" ? `"${value}"` : String(value);
|
|
21823
|
+
sections.push(`| \`${key}\` | \`${formatted}\` |`);
|
|
21824
|
+
}
|
|
21825
|
+
sections.push("");
|
|
21826
|
+
}
|
|
21827
|
+
}
|
|
21668
21828
|
if (docs.subComponents && docs.subComponents.length > 0) {
|
|
21669
21829
|
sections.push("## Sub-components", "");
|
|
21670
21830
|
docs.subComponents.forEach((name) => sections.push(`- \`${name}\``));
|
package/dist/server.js
CHANGED
|
@@ -21033,6 +21033,7 @@ function findMatchingBrace(text2, openingBraceIndex, openChar = "{", closeChar =
|
|
|
21033
21033
|
}
|
|
21034
21034
|
|
|
21035
21035
|
// src/readers/types-reader.ts
|
|
21036
|
+
var TYPE_OR_INTERFACE = "(?:interface|type)";
|
|
21036
21037
|
function parseJSDoc(comment) {
|
|
21037
21038
|
const lines = comment.replace(/\/\*\*|\*\/|\*/g, "").split("\n").map((line) => line.trim()).filter(Boolean);
|
|
21038
21039
|
let description = "";
|
|
@@ -21073,7 +21074,7 @@ function extractType(text2, startIndex) {
|
|
|
21073
21074
|
function parseInterface(content, interfaceName) {
|
|
21074
21075
|
const props = [];
|
|
21075
21076
|
const interfaceRegex = new RegExp(
|
|
21076
|
-
`export\\s+
|
|
21077
|
+
`(?:export\\s+)?${TYPE_OR_INTERFACE}\\s+${interfaceName}\\s*(?:extends\\s+[^{]+)?(?:=\\s*)?\\{([\\s\\S]*?)\\n\\}`,
|
|
21077
21078
|
"m"
|
|
21078
21079
|
);
|
|
21079
21080
|
const match = content.match(interfaceRegex);
|
|
@@ -21105,7 +21106,7 @@ function parseInterface(content, interfaceName) {
|
|
|
21105
21106
|
function extractComponentDescription(content, interfaceName) {
|
|
21106
21107
|
const lines = content.split("\n");
|
|
21107
21108
|
const interfaceLineIndex = lines.findIndex(
|
|
21108
|
-
(line) => line.match(new RegExp(`export\\s
|
|
21109
|
+
(line) => line.match(new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+${interfaceName}`))
|
|
21109
21110
|
);
|
|
21110
21111
|
if (interfaceLineIndex === -1) {
|
|
21111
21112
|
return "";
|
|
@@ -21130,28 +21131,67 @@ function extractComponentDescription(content, interfaceName) {
|
|
|
21130
21131
|
}
|
|
21131
21132
|
return "";
|
|
21132
21133
|
}
|
|
21133
|
-
function
|
|
21134
|
+
function resolveUnionOrIntersectionProps(content, typeName) {
|
|
21135
|
+
const typeDefRegex = new RegExp(`export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`);
|
|
21136
|
+
const match = content.match(typeDefRegex);
|
|
21137
|
+
if (!match) return [];
|
|
21138
|
+
const referencedTypes = match[1].split(/[|&]/).map((t) => t.trim()).filter((t) => t.endsWith("Props"));
|
|
21139
|
+
if (referencedTypes.length === 0) return [];
|
|
21140
|
+
const firstBranch = referencedTypes[0];
|
|
21141
|
+
const extendsRegex = new RegExp(
|
|
21142
|
+
`(?:export\\s+)?${TYPE_OR_INTERFACE}\\s+${firstBranch}\\s+extends\\s+(\\w+)`
|
|
21143
|
+
);
|
|
21144
|
+
const extendsMatch = content.match(extendsRegex);
|
|
21145
|
+
const allProps = [];
|
|
21146
|
+
if (extendsMatch) {
|
|
21147
|
+
allProps.push(...parseInterface(content, extendsMatch[1]));
|
|
21148
|
+
}
|
|
21149
|
+
allProps.push(...parseInterface(content, firstBranch));
|
|
21150
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21151
|
+
return allProps.filter((p) => {
|
|
21152
|
+
if (seen.has(p.name)) return false;
|
|
21153
|
+
seen.add(p.name);
|
|
21154
|
+
return true;
|
|
21155
|
+
});
|
|
21156
|
+
}
|
|
21157
|
+
function readTypesFile(filePath, componentName) {
|
|
21134
21158
|
const content = readTextFile(filePath);
|
|
21135
21159
|
if (!content) {
|
|
21136
21160
|
return null;
|
|
21137
21161
|
}
|
|
21138
|
-
const
|
|
21162
|
+
const resolvedName = componentName || path.basename(path.dirname(filePath));
|
|
21163
|
+
const exactRegex = new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}Props)\\b`);
|
|
21164
|
+
let propsInterfaceMatch = content.match(exactRegex);
|
|
21165
|
+
if (!propsInterfaceMatch) {
|
|
21166
|
+
const prefixRegex = new RegExp(
|
|
21167
|
+
`export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}\\w*Props)\\b`
|
|
21168
|
+
);
|
|
21169
|
+
propsInterfaceMatch = content.match(prefixRegex);
|
|
21170
|
+
}
|
|
21171
|
+
if (!propsInterfaceMatch) {
|
|
21172
|
+
propsInterfaceMatch = content.match(
|
|
21173
|
+
new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+(Ui\\w+Props)\\b`)
|
|
21174
|
+
);
|
|
21175
|
+
}
|
|
21139
21176
|
if (!propsInterfaceMatch) {
|
|
21140
21177
|
return null;
|
|
21141
21178
|
}
|
|
21142
21179
|
const interfaceName = propsInterfaceMatch[1];
|
|
21143
|
-
const
|
|
21180
|
+
const matchedComponentName = interfaceName.replace("Props", "");
|
|
21144
21181
|
const description = extractComponentDescription(content, interfaceName);
|
|
21145
|
-
|
|
21182
|
+
let props = parseInterface(content, interfaceName);
|
|
21183
|
+
if (props.length === 0) {
|
|
21184
|
+
props = resolveUnionOrIntersectionProps(content, interfaceName);
|
|
21185
|
+
}
|
|
21146
21186
|
return {
|
|
21147
|
-
name:
|
|
21187
|
+
name: matchedComponentName,
|
|
21148
21188
|
description,
|
|
21149
21189
|
props
|
|
21150
21190
|
};
|
|
21151
21191
|
}
|
|
21152
21192
|
function readComponentTypes(componentDir) {
|
|
21153
21193
|
const typesPath = path.join(componentDir, "types.ts");
|
|
21154
|
-
return readTypesFile(typesPath);
|
|
21194
|
+
return readTypesFile(typesPath, path.basename(componentDir));
|
|
21155
21195
|
}
|
|
21156
21196
|
|
|
21157
21197
|
// src/constants.ts
|
|
@@ -21364,6 +21404,40 @@ function extractStories(content) {
|
|
|
21364
21404
|
}
|
|
21365
21405
|
return stories;
|
|
21366
21406
|
}
|
|
21407
|
+
function extractInlineRenderTemplates(content) {
|
|
21408
|
+
const examples = [];
|
|
21409
|
+
const storyExportRegex = /export\s+const\s+(\w+):\s*Story\s*=/g;
|
|
21410
|
+
let match;
|
|
21411
|
+
while ((match = storyExportRegex.exec(content)) !== null) {
|
|
21412
|
+
const storyName = match[1];
|
|
21413
|
+
if (storyName === "default") continue;
|
|
21414
|
+
const afterEquals = content.indexOf("{", match.index + match[0].length);
|
|
21415
|
+
if (afterEquals === -1) continue;
|
|
21416
|
+
const closingBrace = findMatchingBrace(content, afterEquals);
|
|
21417
|
+
if (closingBrace === -1) continue;
|
|
21418
|
+
const storyBlock = content.slice(afterEquals, closingBrace + 1);
|
|
21419
|
+
if (!storyBlock.includes("template:")) continue;
|
|
21420
|
+
const templateMatch = storyBlock.match(/template:\s*`([\s\S]*?)`/);
|
|
21421
|
+
if (!templateMatch) continue;
|
|
21422
|
+
const template = templateMatch[1].trim();
|
|
21423
|
+
if (!template) continue;
|
|
21424
|
+
const componentsMatch = storyBlock.match(/components:\s*\{([^}]+)\}/);
|
|
21425
|
+
const componentNames = componentsMatch ? componentsMatch[1].split(",").map((c) => c.trim()).filter(Boolean) : [];
|
|
21426
|
+
const imports = componentNames.length > 0 ? `<script setup>
|
|
21427
|
+
// Components: ${componentNames.join(", ")}
|
|
21428
|
+
</script>
|
|
21429
|
+
|
|
21430
|
+
` : "";
|
|
21431
|
+
examples.push({
|
|
21432
|
+
name: storyName,
|
|
21433
|
+
description: "",
|
|
21434
|
+
code: `${imports}<template>
|
|
21435
|
+
${template}
|
|
21436
|
+
</template>`
|
|
21437
|
+
});
|
|
21438
|
+
}
|
|
21439
|
+
return examples;
|
|
21440
|
+
}
|
|
21367
21441
|
function extractArgTypes(content) {
|
|
21368
21442
|
const argTypes = [];
|
|
21369
21443
|
const argTypesKeyIndex = content.indexOf("argTypes");
|
|
@@ -21420,6 +21494,56 @@ function extractTitle(content) {
|
|
|
21420
21494
|
const titleMatch = content.match(/title:\s*['"]([^'"]+)['"]/);
|
|
21421
21495
|
return titleMatch ? titleMatch[1] : "";
|
|
21422
21496
|
}
|
|
21497
|
+
function extractMetaArgs(content) {
|
|
21498
|
+
const metaDefaultIndex = content.indexOf("export default");
|
|
21499
|
+
if (metaDefaultIndex === -1) return void 0;
|
|
21500
|
+
const metaSection = content.slice(0, metaDefaultIndex);
|
|
21501
|
+
const argsKeyIndex = metaSection.lastIndexOf("args:");
|
|
21502
|
+
if (argsKeyIndex !== -1) {
|
|
21503
|
+
return extractArgsFromPosition(content, argsKeyIndex);
|
|
21504
|
+
}
|
|
21505
|
+
const afterExport = content.slice(metaDefaultIndex + "export default".length);
|
|
21506
|
+
const trimmed = afterExport.trimStart();
|
|
21507
|
+
if (!trimmed.startsWith("{")) return void 0;
|
|
21508
|
+
const blockStart = content.indexOf("{", metaDefaultIndex);
|
|
21509
|
+
const blockEnd = findMatchingBrace(content, blockStart);
|
|
21510
|
+
if (blockEnd === -1) return void 0;
|
|
21511
|
+
const metaBlock = content.slice(blockStart + 1, blockEnd);
|
|
21512
|
+
const inlineArgsIndex = metaBlock.indexOf("args:");
|
|
21513
|
+
if (inlineArgsIndex === -1) return void 0;
|
|
21514
|
+
return extractArgsFromPosition(content, blockStart + 1 + inlineArgsIndex);
|
|
21515
|
+
}
|
|
21516
|
+
function extractArgsFromPosition(content, argsKeyIndex) {
|
|
21517
|
+
const colonIndex = content.indexOf(":", argsKeyIndex + 4);
|
|
21518
|
+
if (colonIndex === -1) {
|
|
21519
|
+
return void 0;
|
|
21520
|
+
}
|
|
21521
|
+
const openingBraceIndex = content.indexOf("{", colonIndex);
|
|
21522
|
+
if (openingBraceIndex === -1) {
|
|
21523
|
+
return void 0;
|
|
21524
|
+
}
|
|
21525
|
+
const closingBraceIndex = findMatchingBrace(content, openingBraceIndex);
|
|
21526
|
+
if (closingBraceIndex === -1) {
|
|
21527
|
+
return void 0;
|
|
21528
|
+
}
|
|
21529
|
+
const argsBlock = content.slice(openingBraceIndex + 1, closingBraceIndex);
|
|
21530
|
+
const args = {};
|
|
21531
|
+
const kvRegex = /(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|(\d+(?:\.\d+)?)|(\btrue\b|\bfalse\b))/g;
|
|
21532
|
+
let match;
|
|
21533
|
+
while ((match = kvRegex.exec(argsBlock)) !== null) {
|
|
21534
|
+
const key = match[1];
|
|
21535
|
+
if (match[2] !== void 0) {
|
|
21536
|
+
args[key] = match[2];
|
|
21537
|
+
} else if (match[3] !== void 0) {
|
|
21538
|
+
args[key] = match[3];
|
|
21539
|
+
} else if (match[4] !== void 0) {
|
|
21540
|
+
args[key] = Number(match[4]);
|
|
21541
|
+
} else if (match[5] !== void 0) {
|
|
21542
|
+
args[key] = match[5] === "true";
|
|
21543
|
+
}
|
|
21544
|
+
}
|
|
21545
|
+
return Object.keys(args).length > 0 ? args : void 0;
|
|
21546
|
+
}
|
|
21423
21547
|
function readStoriesFile(filePath) {
|
|
21424
21548
|
const content = readTextFile(filePath);
|
|
21425
21549
|
if (!content) {
|
|
@@ -21431,6 +21555,7 @@ function readStoriesFile(filePath) {
|
|
|
21431
21555
|
const storyTemplateMap = extractStories(content);
|
|
21432
21556
|
const examples = [];
|
|
21433
21557
|
const usageGuidance = [];
|
|
21558
|
+
const coveredStories = /* @__PURE__ */ new Set();
|
|
21434
21559
|
for (const [storyName, templateVar] of storyTemplateMap) {
|
|
21435
21560
|
const code = templateSources.get(templateVar);
|
|
21436
21561
|
const description = extractStoryJSDoc(content, storyName);
|
|
@@ -21440,16 +21565,29 @@ function readStoriesFile(filePath) {
|
|
|
21440
21565
|
description,
|
|
21441
21566
|
code
|
|
21442
21567
|
});
|
|
21568
|
+
coveredStories.add(storyName);
|
|
21443
21569
|
}
|
|
21444
21570
|
if (description) {
|
|
21445
21571
|
usageGuidance.push(description);
|
|
21446
21572
|
}
|
|
21447
21573
|
}
|
|
21574
|
+
const inlineExamples = extractInlineRenderTemplates(content);
|
|
21575
|
+
for (const example of inlineExamples) {
|
|
21576
|
+
if (!coveredStories.has(example.name)) {
|
|
21577
|
+
const description = extractStoryJSDoc(content, example.name);
|
|
21578
|
+
examples.push({ ...example, description });
|
|
21579
|
+
if (description) {
|
|
21580
|
+
usageGuidance.push(description);
|
|
21581
|
+
}
|
|
21582
|
+
}
|
|
21583
|
+
}
|
|
21584
|
+
const defaultArgs = extractMetaArgs(content);
|
|
21448
21585
|
return {
|
|
21449
21586
|
title,
|
|
21450
21587
|
examples,
|
|
21451
21588
|
argTypes,
|
|
21452
|
-
usageGuidance
|
|
21589
|
+
usageGuidance,
|
|
21590
|
+
defaultArgs
|
|
21453
21591
|
};
|
|
21454
21592
|
}
|
|
21455
21593
|
function readComponentStories(componentDir) {
|
|
@@ -21523,7 +21661,8 @@ function getComponentDocs(componentName) {
|
|
|
21523
21661
|
examples,
|
|
21524
21662
|
usageGuidance: [...new Set(usageGuidance)],
|
|
21525
21663
|
// Remove duplicates
|
|
21526
|
-
subComponents: subComponents && subComponents.length > 0 ? subComponents : void 0
|
|
21664
|
+
subComponents: subComponents && subComponents.length > 0 ? subComponents : void 0,
|
|
21665
|
+
defaultArgs: storiesInfo?.defaultArgs
|
|
21527
21666
|
};
|
|
21528
21667
|
}
|
|
21529
21668
|
|
|
@@ -21569,6 +21708,27 @@ function formatComponentDocs(docs) {
|
|
|
21569
21708
|
sections.push("## Props", "");
|
|
21570
21709
|
docs.props.forEach((prop) => sections.push(...formatProp(prop)));
|
|
21571
21710
|
}
|
|
21711
|
+
if (docs.defaultArgs && Object.keys(docs.defaultArgs).length > 0) {
|
|
21712
|
+
const filteredArgs = Object.entries(docs.defaultArgs).filter(([key, value]) => {
|
|
21713
|
+
const prop = docs.props.find((p) => p.name === key);
|
|
21714
|
+
if (!prop?.default) return true;
|
|
21715
|
+
return String(value) !== prop.default;
|
|
21716
|
+
});
|
|
21717
|
+
if (filteredArgs.length > 0) {
|
|
21718
|
+
sections.push("## Storybook Defaults", "");
|
|
21719
|
+
sections.push(
|
|
21720
|
+
"These are the recommended prop values used in the component's Storybook stories:",
|
|
21721
|
+
""
|
|
21722
|
+
);
|
|
21723
|
+
sections.push("| Prop | Value |");
|
|
21724
|
+
sections.push("|------|-------|");
|
|
21725
|
+
for (const [key, value] of filteredArgs) {
|
|
21726
|
+
const formatted = typeof value === "string" ? `"${value}"` : String(value);
|
|
21727
|
+
sections.push(`| \`${key}\` | \`${formatted}\` |`);
|
|
21728
|
+
}
|
|
21729
|
+
sections.push("");
|
|
21730
|
+
}
|
|
21731
|
+
}
|
|
21572
21732
|
if (docs.subComponents && docs.subComponents.length > 0) {
|
|
21573
21733
|
sections.push("## Sub-components", "");
|
|
21574
21734
|
docs.subComponents.forEach((name) => sections.push(`- \`${name}\``));
|