Skip to content

Commit

Permalink
feat: extract components props info
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Mar 11, 2020
1 parent cb2ee07 commit 051341d
Show file tree
Hide file tree
Showing 17 changed files with 601 additions and 87 deletions.
59 changes: 49 additions & 10 deletions core/instrument/src/babel/extract-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,52 @@ import {
StoryAttributes,
StoryComponent,
StoriesKind,
ComponentInfo,
} from '@component-controls/specification';
import { followImports } from './follow-imports';
import { packageInfo } from '../project/packageInfo';
import { InstrumentOptions } from '../types';
import {
InstrumentOptions,
PropsLoaderConfig,
PropsInfoExtractorFunction,
} from '../types';

const extractComponentProps = async (
options: PropsLoaderConfig[],
filePath: string,
componentName?: string,
source?: string,
): Promise<ComponentInfo | undefined> => {
const loaders = options.filter(loader => {
const include = Array.isArray(loader.use)
? loader.use
: loader.use
? [loader.use]
: undefined;
const exclude = Array.isArray(loader.exclude)
? loader.exclude
: loader.exclude
? [loader.exclude]
: undefined;
return (
include &&
include.some(mask => filePath.match(mask)) &&
(!exclude || !exclude.some(mask => filePath.match(mask)))
);
});

if (loaders.length > 1) {
console.error(`Multiple propsloaders found for file ${filePath}`);
}
const propsLoaderName = loaders.length === 1 ? loaders[0] : undefined;
if (propsLoaderName) {
const propsLoader: PropsInfoExtractorFunction = require(propsLoaderName.name)(
propsLoaderName.options,
);
return await propsLoader(filePath, componentName, source);
}
return undefined;
};
const componentFromParams = (
attributes?: StoryAttributes,
): string | undefined => {
Expand Down Expand Up @@ -73,20 +114,18 @@ export const extractComponent = async (
: {
name: componentName,
};
const { extractPropsFn } = options || {};
if (follow && follow.filePath && typeof extractPropsFn === 'function') {
component.info = await extractPropsFn(
const { propsLoaders } = options || {};
if (follow && follow.filePath && Array.isArray(propsLoaders)) {
const info = await extractComponentProps(
propsLoaders,
follow.filePath,
component.importedName,
follow.importedName,
follow.source,
);
if (component.info) {
console.log(component.info);
} else {
console.log(follow.filePath);
if (info) {
component.info = info;
}
}

globalCache[filePath] = component;
return component;
};
Expand Down
3 changes: 2 additions & 1 deletion core/instrument/src/babel/follow-imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const followImports = (
named: {},
};
traverse(ast, traverseExports(exports));

const folderName = path.dirname(fileName);
const findExport =
baseImportedName === 'default' || baseImportedName === 'namespace'
Expand Down Expand Up @@ -105,8 +106,8 @@ export const followImports = (
}
const imports: ImportTypes = {};
traverse(ast, traverseImports(imports));
const findImport = imports[baseImportedName];

const findImport = imports[baseImportedName];
if (findImport) {
try {
const resolvedFilePath = resolve.sync(findImport.from, {
Expand Down
8 changes: 4 additions & 4 deletions core/instrument/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,19 @@ const parseSource = async (
resolver: resolveOptions = {},
components: componentOptions = {},
stories: storiesOptions = {},
extractPropsFn,
propsLoaders,
} = options || {};

const mergedOptions = {
const mergedOptions: Required<InstrumentOptions> = {
parser: deepMerge<ParserOptions>(defaultParserOptions, parserOptions),
resolve: deepMerge<ResolveOptions>(defaultResolveOptions, resolveOptions),
resolver: deepMerge<ResolveOptions>(defaultResolveOptions, resolveOptions),
prettier: prettierOptions,
components: deepMerge<ComponentOptions>(
defaultComponentOptions,
componentOptions,
),
stories: deepMerge<StoriesOptions>(defaultStoriesOptions, storiesOptions),
extractPropsFn,
propsLoaders: propsLoaders || [],
};

const prettify = async (c: string): Promise<string> => {
Expand Down
33 changes: 30 additions & 3 deletions core/instrument/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const defaultParserOptions: ParserOptions = {
* callback function to extract props info table - ie docgen type libraries
* used to extract displayName, and props tables for a component
*/
export type PropsInfoExtractor = (
export type PropsInfoExtractorFunction = (
/**
* full name and path of the component path
* react-docgen needs it to extract babel configurations
Expand All @@ -44,6 +44,32 @@ export type PropsInfoExtractor = (
source?: string,
) => Promise<ComponentInfo | undefined>;

/**
* settings to load component props tables
* each component file extension must resolve to only 1 props info loader
*/
export interface PropsLoaderConfig {
/**
* module name - must be usable by require(....)
* if a local file name, use require.esolve('../..')
*/
name: string;

/**
* a regex or a list of regex masks
* ex: use: /\.(js|jsx)$/
*/
use: RegExp | RegExp[];
/**
* a regex or a list of regex masks for files to be excluded
*/
exclude?: RegExp | RegExp[];
/**
* options specific to the props info loader module
*/
options?: any;
}

export const defaultPackageOptions: PackageInfoOptions = {
maxLevels: 10,
packageJsonName: 'package.json',
Expand Down Expand Up @@ -154,9 +180,10 @@ export interface InstrumentOptions {
stories?: StoriesOptions;

/**
* optional module to extract prop tables information for components
* props tables loaders
* must have a default export that returns a PropsInfoExtractorFunction
*/
extractPropsFn?: PropsInfoExtractor;
propsLoaders?: PropsLoaderConfig[];
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

exports[`csf-parameters name-and-parameters.js 1`] = `
Object {
"components": Object {
"ControlsTable": Object {
"name": "ControlsTable",
},
},
"components": Object {},
"kinds": Object {},
"stories": Object {
"myStory": Object {
Expand All @@ -20,7 +16,6 @@ Object {
"component": "ControlsTable",
},
},
"component": "ControlsTable",
"loc": Object {
"end": Object {
"column": 31,
Expand Down
11 changes: 9 additions & 2 deletions core/instrument/test/__snapshots__/csf-story-kind.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Object {
exports[`csf-story-kind title-and-parameters.js 1`] = `
Object {
"components": Object {
"ControlsTable": Object {
"/Users/atanasster/component-controls/core/instrument/test/examples/csf/kind/title-and-parameters.js": Object {
"name": "ControlsTable",
},
},
Expand All @@ -51,6 +51,9 @@ Object {
"title": "Storybook/Blocks/ControlsTable",
},
"component": "ControlsTable",
"components": Object {
"ControlsTable": "/Users/atanasster/component-controls/core/instrument/test/examples/csf/kind/title-and-parameters.js",
},
"repository": Object {
"browse": "https://github.com/ccontrols/component-controls/tree/master/core/instrument/test/examples/csf/kind/title-and-parameters.js",
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
Expand All @@ -76,7 +79,7 @@ Object {
exports[`csf-story-kind title-controls-and-parameters.js 1`] = `
Object {
"components": Object {
"ControlsTable": Object {
"/Users/atanasster/component-controls/core/instrument/test/examples/csf/kind/title-controls-and-parameters.js": Object {
"name": "ControlsTable",
},
},
Expand All @@ -97,6 +100,9 @@ Object {
"title": "Storybook/Kind",
},
"component": "ControlsTable",
"components": Object {
"ControlsTable": "/Users/atanasster/component-controls/core/instrument/test/examples/csf/kind/title-controls-and-parameters.js",
},
"repository": Object {
"browse": "https://github.com/ccontrols/component-controls/tree/master/core/instrument/test/examples/csf/kind/title-controls-and-parameters.js",
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
Expand Down Expand Up @@ -132,6 +138,7 @@ Object {
"attributes": Object {
"title": "Storybook/Blocks/ControlsTable",
},
"components": Object {},
"repository": Object {
"browse": "https://github.com/ccontrols/component-controls/tree/master/core/instrument/test/examples/csf/kind/with-title.js",
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
Expand Down
5 changes: 4 additions & 1 deletion core/instrument/test/__snapshots__/csf-toggle.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exports[`csf-toggle toggle-story.js 1`] = `
Object {
"components": Object {
"Toggle": Object {
"/Users/atanasster/component-controls/core/instrument/test/examples/csf/toggle/toggle-story.js": Object {
"from": "./Toggle",
"importedName": "Toggle",
"loc": undefined,
Expand All @@ -20,6 +20,9 @@ Object {
"title": "Components/Toggle",
},
"component": "Toggle",
"components": Object {
"Toggle": "/Users/atanasster/component-controls/core/instrument/test/examples/csf/toggle/toggle-story.js",
},
"repository": Object {
"browse": "https://github.com/ccontrols/component-controls/tree/master/core/instrument/test/examples/csf/toggle/toggle-story.js",
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
Expand Down
Loading

0 comments on commit 051341d

Please sign in to comment.