Skip to content

Commit

Permalink
parse pnp paths in storybook metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
yannbf committed Jun 23, 2023
1 parent 6d0596f commit a7014be
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 9 deletions.
34 changes: 28 additions & 6 deletions code/lib/telemetry/src/get-framework-info.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { PackageJson, StorybookConfig } from '@storybook/types';
import path from 'path';
import { frameworkPackages } from '@storybook/core-common';
import { cleanPaths } from './sanitize';
import { getActualPackageJson } from './package-json';

const knownRenderers = [
Expand Down Expand Up @@ -30,20 +33,39 @@ function findMatchingPackage(packageJson: PackageJson, suffixes: string[]) {
return suffixes.map((suffix) => `@storybook/${suffix}`).find((pkg) => allDependencies[pkg]);
}

export async function getFrameworkInfo(mainConfig: StorybookConfig) {
const { framework: frameworkInput } = mainConfig;
export const getFrameworkPackageName = (mainConfig?: StorybookConfig) => {
const packageNameOrPath =
typeof mainConfig?.framework === 'string' ? mainConfig.framework : mainConfig?.framework?.name;

if (!packageNameOrPath) {
return null;
}

const normalizedPath = path.normalize(packageNameOrPath).replace(new RegExp(/\\/, 'g'), '/');

if (!frameworkInput) return {};
const knownFramework = Object.keys(frameworkPackages).find((pkg) => normalizedPath.endsWith(pkg));

return knownFramework || cleanPaths(packageNameOrPath).replace(/.*node_modules\//, '');
};

export async function getFrameworkInfo(mainConfig: StorybookConfig) {
if (!mainConfig.framework) return {};

const framework = typeof frameworkInput === 'string' ? { name: frameworkInput } : frameworkInput;
const frameworkName = getFrameworkPackageName(mainConfig);
if (!frameworkName) return {};
const frameworkOptions =
typeof mainConfig.framework === 'object' ? mainConfig.framework.options : {};

const frameworkPackageJson = await getActualPackageJson(framework.name);
const frameworkPackageJson = await getActualPackageJson(frameworkName);

const builder = findMatchingPackage(frameworkPackageJson, knownBuilders);
const renderer = findMatchingPackage(frameworkPackageJson, knownRenderers);

return {
framework,
framework: {
name: frameworkName,
options: frameworkOptions,
},
builder,
renderer,
};
Expand Down
65 changes: 62 additions & 3 deletions code/lib/telemetry/src/storybook-metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,85 @@ describe('sanitizeAddonName', () => {
// @ts-expect-error the property is read only but we can change it for testing purposes
path.sep = '\\';
const cwdMockPath = `C:\\Users\\username\\storybook-app`;
jest.spyOn(process, `cwd`).mockImplementationOnce(() => cwdMockPath);
const cwdSpy = jest.spyOn(process, `cwd`).mockReturnValue(cwdMockPath);

expect(sanitizeAddonName(`${cwdMockPath}\\local-addon\\themes.js`)).toEqual(
'$SNIP\\local-addon\\themes'
);
cwdSpy.mockRestore();
});

test('Linux paths', () => {
// @ts-expect-error the property is read only but we can change it for testing purposes
path.sep = '/';
const cwdMockPath = `/Users/username/storybook-app`;
jest.spyOn(process, `cwd`).mockImplementationOnce(() => cwdMockPath);
const cwdSpy = jest.spyOn(process, `cwd`).mockReturnValue(cwdMockPath);

expect(sanitizeAddonName(`${cwdMockPath}/local-addon/themes.js`)).toEqual(
'$SNIP/local-addon/themes'
);

cwdSpy.mockRestore();
});
});

describe('await computeStorybookMetadata', () => {
describe('computeStorybookMetadata', () => {
test('should parse pnp paths for known frameworks', async () => {
const reactResult = await computeStorybookMetadata({
packageJson: packageJsonMock,
mainConfig: {
...mainJsMock,
framework: {
name: '/Users/foo/storybook/.yarn/__virtual__/@storybook-react-vite-virtual-769c990b9/0/cache/@storybook-react-vite-npm-7.1.0-alpha.38-512b-a23.zip/node_modules/@storybook/react-vite',
options: {
fastRefresh: false,
},
},
},
});

expect(reactResult.framework).toEqual({
name: '@storybook/react-vite',
options: { fastRefresh: false },
});
});

test('should parse pnp paths for unknown frameworks', async () => {
const pnpResult = await computeStorybookMetadata({
packageJson: packageJsonMock,
mainConfig: {
...mainJsMock,
framework: {
name: '/Users/foo/my-project/.yarn/__virtual__/@storybook-react-vite-virtual-769c990b9/0/cache/@storybook-react-rust-npm-7.1.0-alpha.38-512b-a23.zip/node_modules/storybook-react-rust',
},
},
});

expect(pnpResult.framework).toEqual({
name: 'storybook-react-rust',
});
});

test('should sanitize pnp paths for local frameworks', async () => {
const cwdSpy = jest.spyOn(process, 'cwd').mockReturnValue('/Users/foo/my-project');

const localResult = await computeStorybookMetadata({
packageJson: packageJsonMock,
mainConfig: {
...mainJsMock,
framework: {
name: '/Users/foo/my-project/.storybook/some-local-framework',
},
},
});

expect(localResult.framework).toEqual({
name: '$SNIP/.storybook/some-local-framework',
});

cwdSpy.mockRestore();
});

test('should return frameworkOptions from mainjs', async () => {
const reactResult = await computeStorybookMetadata({
packageJson: packageJsonMock,
Expand Down

0 comments on commit a7014be

Please sign in to comment.