storybook-framework-cedarjs
Version:
Storybook for CedarJS
107 lines (106 loc) • 3.31 kB
JavaScript
import { existsSync } from "node:fs";
import { relative, sep } from "node:path";
import { createFilter } from "@rollup/pluginutils";
import * as find from "empathic/find";
import MagicString from "magic-string";
import {
ERROR_CODES,
builtinHandlers as docgenHandlers,
builtinResolvers as docgenResolver,
makeFsImporter,
parse
} from "react-docgen";
import { getProjectRoot } from "storybook/internal/common";
import * as TsconfigPaths from "tsconfig-paths";
import actualNameHandler from "./docgen-handlers/actualNameHandler.js";
import {
RESOLVE_EXTENSIONS,
ReactDocgenResolveError,
defaultLookupModule
} from "./docgen-resolver.js";
const defaultHandlers = Object.values(docgenHandlers).map((handler) => handler);
const defaultResolver = new docgenResolver.FindExportedDefinitionsResolver();
const handlers = [...defaultHandlers, actualNameHandler];
async function reactDocgen({
include = /\.(mjs|tsx?|jsx?)$/,
exclude = [/node_modules\/.*/]
} = {}) {
const cwd = process.cwd();
const filter = createFilter(include, exclude);
const tsconfigPath = find.up("tsconfig.json", { cwd, last: getProjectRoot() });
const tsconfig = TsconfigPaths.loadConfig(tsconfigPath);
let matchPath;
if (tsconfig.resultType === "success") {
matchPath = TsconfigPaths.createMatchPath(
tsconfig.absoluteBaseUrl,
tsconfig.paths,
["browser", "module", "main"]
);
}
return {
name: "storybook:react-docgen-plugin",
enforce: "pre",
async transform(src, id) {
if (!filter(relative(cwd, id))) {
return;
}
try {
const docgenResults = parse(src, {
resolver: defaultResolver,
handlers,
importer: getReactDocgenImporter(matchPath),
filename: id
});
const s = new MagicString(src);
docgenResults.forEach((info) => {
const { actualName, definedInFile, ...docgenInfo } = info;
if (actualName && definedInFile == id) {
const docNode = JSON.stringify(docgenInfo);
s.append(`;${actualName}.__docgenInfo=${docNode}`);
}
});
return {
code: s.toString(),
map: s.generateMap({ hires: true, source: id })
};
} catch (e) {
if (e.code === ERROR_CODES.MISSING_DEFINITION) {
return;
}
throw e;
}
}
};
}
function getReactDocgenImporter(matchPath) {
return makeFsImporter((filename, basedir) => {
const mappedFilenameByPaths = (() => {
if (matchPath) {
const match = matchPath(filename);
return match || filename;
} else {
return filename;
}
})();
const result = defaultLookupModule(mappedFilenameByPaths, basedir);
if (result.includes(`${sep}react-native${sep}index.js`)) {
const replaced = result.replace(
`${sep}react-native${sep}index.js`,
`${sep}react-native-web${sep}dist${sep}index.js`
);
if (existsSync(replaced)) {
if (RESOLVE_EXTENSIONS.find((ext) => result.endsWith(ext))) {
return replaced;
}
}
}
if (RESOLVE_EXTENSIONS.find((ext) => result.endsWith(ext))) {
return result;
}
throw new ReactDocgenResolveError(filename);
});
}
export {
getReactDocgenImporter,
reactDocgen
};