CSF tools: Support Template.bind() substitution

This commit is contained in:
Michael Shilman 2021-06-04 21:46:14 +08:00
parent 6bfa81e9a1
commit 7f9ae2daaa
2 changed files with 60 additions and 4 deletions

View File

@ -158,7 +158,7 @@ describe('csf extract', () => {
- id: foo-bar--a
name: A
parameters:
__isArgsStory: false
__isArgsStory: true
__id: foo-bar--a
`);
});

View File

@ -55,6 +55,63 @@ const parseMeta = (declaration: t.ObjectExpression): Meta => {
});
return meta;
};
const findVarInitialization = (identifier: string, program: t.Program) => {
let init: t.Node = null;
let declarations: t.VariableDeclarator[] = null;
program.body.find((node: t.Node) => {
if (t.isVariableDeclaration(node)) {
declarations = node.declarations;
} else if (t.isExportNamedDeclaration(node) && t.isVariableDeclaration(node.declaration)) {
declarations = node.declaration.declarations;
}
return (
declarations &&
declarations.find((decl: t.Node) => {
if (
t.isVariableDeclarator(decl) &&
t.isIdentifier(decl.id) &&
decl.id.name === identifier
) {
init = decl.init;
return true; // stop looking
}
return false;
})
);
});
return init;
};
const isArgsStory = ({ init }: t.VariableDeclarator, parent: t.Node) => {
let storyFn: t.Node = init;
// export const Foo = Bar.bind({})
if (t.isCallExpression(init)) {
const { callee, arguments: bindArguments } = init;
if (
t.isProgram(parent) &&
t.isMemberExpression(callee) &&
t.isIdentifier(callee.object) &&
t.isIdentifier(callee.property) &&
callee.property.name === 'bind' &&
(bindArguments.length === 0 ||
(bindArguments.length === 1 &&
t.isObjectExpression(bindArguments[0]) &&
bindArguments[0].properties.length === 0))
) {
const boundIdentifier = callee.object.name;
const template = findVarInitialization(boundIdentifier, parent);
if (template) {
storyFn = template;
}
}
}
if (t.isArrowFunctionExpression(storyFn)) {
return storyFn.params.length > 0;
}
return false;
};
export class CsfFile {
_ast: Node;
@ -85,7 +142,7 @@ export class CsfFile {
},
},
ExportNamedDeclaration: {
enter({ node }) {
enter({ node, parent }) {
if (t.isVariableDeclaration(node.declaration)) {
// export const X = ...;
node.declaration.declarations.forEach((decl) => {
@ -94,8 +151,7 @@ export class CsfFile {
const parameters = {
// __id: toId(self._meta.title, name),
// FiXME: Template.bind({});
__isArgsStory:
t.isArrowFunctionExpression(decl.init) && decl.init.params.length > 0,
__isArgsStory: isArgsStory(decl, parent),
};
self._stories[name] = {
id: 'FIXME',