-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: parse component import into stories
- Loading branch information
1 parent
b17ba66
commit 04c986a
Showing
16 changed files
with
1,505 additions
and
177 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import traverse from '@babel/traverse'; | ||
import { | ||
StoriesGroup, | ||
StoryArguments, | ||
StoryComponent, | ||
} from '@component-controls/specification'; | ||
|
||
const componentFromParams = ( | ||
parameters?: StoryArguments, | ||
): string | undefined => { | ||
if (parameters) { | ||
let component = parameters.find(p => p.name === 'component'); | ||
if (!component) { | ||
const params = parameters.find(p => p.name === 'parameters'); | ||
if (params) { | ||
component = (params.value as StoryArguments).find( | ||
p => p.name === 'component', | ||
); | ||
} | ||
} | ||
if (component) { | ||
if (typeof component.value === 'string') { | ||
return component.value as string; | ||
} | ||
if ( | ||
Array.isArray(component.value) && | ||
component.value.length > 0 && | ||
typeof component.value[0].value === 'string' | ||
) { | ||
return component.value[0].value; | ||
} | ||
} | ||
} | ||
return undefined; | ||
}; | ||
|
||
const findComponentImport = ( | ||
ast: any, | ||
componentName: string, | ||
): StoryComponent | undefined => { | ||
let result: StoryComponent | undefined = undefined; | ||
traverse(ast, { | ||
ImportDeclaration: (path: any) => { | ||
const node = path.node; | ||
for (let i = 0; i < node.specifiers.length; i += 1) { | ||
const specifier = node.specifiers[i]; | ||
if (specifier.local && specifier.local.name === componentName) { | ||
result = { | ||
name: specifier.local.name, | ||
imported: specifier.imported | ||
? specifier.imported.name | ||
: specifier.type === 'ImportDefaultSpecifier' | ||
? 'default' | ||
: undefined, | ||
from: node.source ? node.source.value : undefined, | ||
loc: node.loc, | ||
}; | ||
path.skip(); | ||
break; | ||
} | ||
} | ||
}, | ||
}); | ||
return result; | ||
}; | ||
|
||
export const extractComponent = (ast: any, kind: StoriesGroup) => { | ||
const componentName = componentFromParams(kind.parameters); | ||
if (componentName) { | ||
const component = findComponentImport(ast, componentName); | ||
if (component) { | ||
kind.component = component; | ||
} | ||
} | ||
Object.keys(kind.stories).forEach(name => { | ||
const story = kind.stories[name]; | ||
const componentName = componentFromParams(story.parameters); | ||
if (componentName) { | ||
const component = findComponentImport(ast, componentName); | ||
if (component) { | ||
story.component = component; | ||
} | ||
} | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,65 @@ | ||
import { StoryArguments } from '@component-controls/specification'; | ||
import { | ||
StoryArguments, | ||
StoryArgument, | ||
} from '@component-controls/specification'; | ||
import { sourceLocation } from './utils'; | ||
|
||
export const extractProperties = (node: any): StoryArguments | undefined => { | ||
if (node && node.properties) { | ||
const properties: StoryArguments = node.properties | ||
.map((property: any) => { | ||
if (property.value) { | ||
switch (property.value.type) { | ||
case 'BooleanLiteral': | ||
case 'NumericLiteral': | ||
case 'StringLiteral': { | ||
return { | ||
value: property.value.value, | ||
name: property.key.name, | ||
loc: property.loc, | ||
}; | ||
} | ||
case 'Identifier': | ||
return { | ||
value: property.value.name, | ||
name: property.key.name, | ||
loc: property.loc, | ||
}; | ||
case 'MemberExpression': | ||
return { | ||
value: `${property.value.object.name}.${property.value.property.name}`, | ||
name: property.key.name, | ||
loc: property.loc, | ||
}; | ||
|
||
case 'ObjectExpression': { | ||
return { | ||
value: extractProperties(property.value), | ||
name: property.key.name, | ||
loc: property.loc, | ||
}; | ||
} | ||
default: | ||
// console.log(property.value); | ||
return null; | ||
} | ||
const nodeToParameter = (node: any): StoryArgument | undefined => { | ||
const value = node.value || node; | ||
const name = node.key ? node.key.name : node.name; | ||
if (value) { | ||
switch (value.type) { | ||
case 'BooleanLiteral': | ||
case 'NumericLiteral': | ||
case 'StringLiteral': { | ||
return { | ||
value: value.value, | ||
name, | ||
loc: sourceLocation(node.loc), | ||
}; | ||
} | ||
case 'Identifier': | ||
return { | ||
value: value.name, | ||
name, | ||
loc: sourceLocation(node.loc), | ||
}; | ||
case 'MemberExpression': | ||
return { | ||
value: `${value.object.name}.${value.property.name}`, | ||
name, | ||
loc: sourceLocation(node.loc), | ||
}; | ||
case 'ObjectExpression': { | ||
const val = extractProperties(value); | ||
if (val) { | ||
return { | ||
value: val, | ||
name, | ||
loc: sourceLocation(node.loc), | ||
}; | ||
} | ||
return null; | ||
}) | ||
.filter((p: any) => p); | ||
return properties; | ||
break; | ||
} | ||
default: | ||
// console.log(property.value); | ||
return undefined; | ||
} | ||
} | ||
return undefined; | ||
}; | ||
export const extractProperties = (node: any): StoryArguments | undefined => { | ||
if (node) { | ||
if (node.properties) { | ||
const properties: StoryArguments = node.properties | ||
.map((propNode: any) => nodeToParameter(propNode)) | ||
.filter((p: any) => p); | ||
return properties; | ||
} | ||
const parameter = nodeToParameter(node); | ||
if (parameter) { | ||
return [parameter]; | ||
} | ||
} | ||
return undefined; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.