@storybook/codemod
Version:
A collection of codemod scripts written with JSCodeshift
147 lines (143 loc) • 5.42 kB
JavaScript
import CJS_COMPAT_NODE_URL_9smq7eu765a from 'node:url';
import CJS_COMPAT_NODE_PATH_9smq7eu765a from 'node:path';
import CJS_COMPAT_NODE_MODULE_9smq7eu765a from "node:module";
var __filename = CJS_COMPAT_NODE_URL_9smq7eu765a.fileURLToPath(import.meta.url);
var __dirname = CJS_COMPAT_NODE_PATH_9smq7eu765a.dirname(__filename);
var require = CJS_COMPAT_NODE_MODULE_9smq7eu765a.createRequire(import.meta.url);
// ------------------------------------------------------------
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
// ------------------------------------------------------------
import {
__name
} from "../_node-chunks/chunk-HVEWKEW6.js";
// src/transforms/find-implicit-spies.ts
import { core as babel, types as t } from "storybook/internal/babel";
import { loadCsf } from "storybook/internal/csf-tools";
function findImplicitSpies(path, file, keys) {
path.traverse({
Identifier: /* @__PURE__ */ __name((identifier) => {
if (!keys.includes(identifier.node.name) && /^on[A-Z].*/.test(identifier.node.name)) {
console.warn(identifier.buildCodeFrameError(`${file} Possible implicit spy found`).message);
}
}, "Identifier")
});
}
__name(findImplicitSpies, "findImplicitSpies");
function getAnnotationKeys(file, storyName, annotationName) {
const argKeys = [];
file.path.traverse({
// CSF2 play function Story.args =
AssignmentExpression: /* @__PURE__ */ __name((path) => {
const left = path.get("left");
if (!left.isMemberExpression()) {
return;
}
const object = left.get("object");
if (!(object.isIdentifier() && object.node.name === storyName)) {
return;
}
const property = left.get("property");
const right = path.get("right");
if (property.isIdentifier() && property.node.name === annotationName && right.isObjectExpression()) {
argKeys.push(
...right.node.properties.flatMap(
(value) => t.isObjectProperty(value) && t.isIdentifier(value.key) ? [value.key.name] : []
)
);
}
}, "AssignmentExpression"),
// CSF3 const Story = {args: () => {} };
VariableDeclarator: /* @__PURE__ */ __name((path) => {
const id = path.get("id");
const init = path.get("init");
if (!(id.isIdentifier() && id.node.name === storyName) || !init.isObjectExpression()) {
return;
}
const args = init.get("properties").flatMap((it) => it.isObjectProperty() ? [it] : []).find((it) => {
const argKey = it.get("key");
return argKey.isIdentifier() && argKey.node.name === annotationName;
});
if (!args) {
return;
}
const argsValue = args.get("value");
if (!argsValue || !argsValue.isObjectExpression()) {
return;
}
argKeys.push(
...argsValue.node.properties.flatMap(
(value) => t.isObjectProperty(value) && t.isIdentifier(value.key) ? [value.key.name] : []
)
);
}, "VariableDeclarator")
});
return argKeys;
}
__name(getAnnotationKeys, "getAnnotationKeys");
var getObjectExpressionKeys = /* @__PURE__ */ __name((node) => {
return t.isObjectExpression(node) ? node.properties.flatMap(
(value) => t.isObjectProperty(value) && t.isIdentifier(value.key) ? [value.key.name] : []
) : [];
}, "getObjectExpressionKeys");
async function transform(info) {
const csf = loadCsf(info.source, { makeTitle: /* @__PURE__ */ __name((title) => title, "makeTitle") });
const fileNode = csf._ast;
const file = new babel.File(
{ filename: info.path },
{ code: info.source, ast: fileNode }
);
csf.parse();
const metaKeys = [
...getObjectExpressionKeys(csf._metaAnnotations.args),
...getObjectExpressionKeys(csf._metaAnnotations.argTypes)
];
Object.values(csf.stories).forEach(({ name }) => {
if (!name) {
return;
}
const allKeys = [
...metaKeys,
...getAnnotationKeys(file, name, "args"),
...getAnnotationKeys(file, name, "argTypes")
];
file.path.traverse({
// CSF2 play function Story.play =
AssignmentExpression: /* @__PURE__ */ __name((path) => {
const left = path.get("left");
if (!left.isMemberExpression()) {
return;
}
const object = left.get("object");
if (!(object.isIdentifier() && object.node.name === name)) {
return;
}
const property = left.get("property");
if (property.isIdentifier() && property.node.name === "play") {
findImplicitSpies(path, info.path, allKeys);
}
}, "AssignmentExpression"),
// CSF3 play function: const Story = {play: () => {} };
VariableDeclarator: /* @__PURE__ */ __name((path) => {
const id = path.get("id");
const init = path.get("init");
if (!(id.isIdentifier() && id.node.name === name) || !init.isObjectExpression()) {
return;
}
const play = init.get("properties").flatMap((it) => it.isObjectProperty() ? [it] : []).find((it) => {
const argKey = it.get("key");
return argKey.isIdentifier() && argKey.node.name === "play";
});
if (play) {
findImplicitSpies(play, info.path, allKeys);
}
}, "VariableDeclarator")
});
});
return;
}
__name(transform, "transform");
var parser = "tsx";
export {
transform as default,
parser
};