@supernovaio/cli
Version:
Supernova.io Command Line Interface
92 lines (90 loc) • 3.83 kB
JavaScript
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4689362b-19c7-5ab6-9737-f981273ed47f")}catch(e){}}();
import { readFile } from "node:fs/promises";
import path from "node:path";
import { collectFiles, toRelative, uniqueSorted } from "./helpers.js";
const storiesPattern = "**/*.stories.{ts,tsx,js,jsx,mdx}";
function inferCandidatesFromFile(storyPath) {
const fileName = path.basename(storyPath);
const [baseName] = fileName.split(".stories");
return uniqueSorted([baseName, baseName.replaceAll(/[-_]+(.)/g, (_, c) => c.toUpperCase())]);
}
function inferCandidatesFromMeta(content) {
const titleMatch = content.match(/title\s*:\s*["']([^"']+)["']/);
if (!titleMatch?.[1]) {
return [];
}
const parts = titleMatch[1].split("/").filter(Boolean);
const maybeComponent = parts.at(-1);
if (!maybeComponent) {
return [];
}
return [maybeComponent];
}
function lineAt(content, index) {
return content.slice(0, index).split("\n").length;
}
function extractStoryExports(content) {
const exports = [...content.matchAll(/export\s+(?:const|function)\s+([A-Za-z0-9_]+)/g)].filter(match => match[1] !== "default");
return exports
.map((match, index) => {
const storyName = match[1];
const start = match.index ?? 0;
const nextStart = exports[index + 1]?.index;
const endExclusive = typeof nextStart === "number" ? nextStart : content.length;
const snippet = content.slice(start, endExclusive).trim();
return {
lineEnd: lineAt(content, Math.max(start, endExclusive - 1)),
lineStart: lineAt(content, start),
snippet,
storyName,
};
})
.sort((a, b) => a.storyName.localeCompare(b.storyName));
}
export async function analyzeStorybookStories(projectRoot, components, excludePaths = []) {
const files = await collectFiles({
excludePaths,
pattern: storiesPattern,
projectRoot,
});
const byExportName = new Map(components.map(component => [component.exportName.toLowerCase(), component]));
const records = {};
for (const file of files) {
const content = await readFile(file, "utf8");
const stories = extractStoryExports(content);
if (stories.length === 0) {
continue;
}
const relativePath = toRelative(projectRoot, file);
const candidates = uniqueSorted([...inferCandidatesFromFile(relativePath), ...inferCandidatesFromMeta(content)]);
for (const candidate of candidates) {
const component = byExportName.get(candidate.toLowerCase());
if (!component) {
continue;
}
if (!records[component.componentKey]) {
records[component.componentKey] = [];
}
for (const story of stories) {
records[component.componentKey].push({
lineEnd: story.lineEnd,
lineStart: story.lineStart,
snippet: story.snippet,
storyName: story.storyName,
storyPath: relativePath,
});
}
}
}
for (const componentKey of Object.keys(records)) {
records[componentKey] = records[componentKey].sort((a, b) => {
if (a.storyPath === b.storyPath) {
return a.lineStart - b.lineStart;
}
return a.storyPath.localeCompare(b.storyPath);
});
}
return records;
}
//# sourceMappingURL=storybook-stories.js.map
//# debugId=4689362b-19c7-5ab6-9737-f981273ed47f