Skip to content

Commit

Permalink
Merge branch 'experimental-support-svelte-v5' of github.com:storybook…
Browse files Browse the repository at this point in the history
…js/addon-svelte-csf into experimental-support-svelte-v5
  • Loading branch information
JReinhold committed Jun 11, 2024
2 parents 484cc1e + c2fefdb commit 2f0a74f
Show file tree
Hide file tree
Showing 6 changed files with 267 additions and 33 deletions.
125 changes: 125 additions & 0 deletions ERRORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Errors

List of errors that can be thrown by this addon.

## `PARSER_EXTRACT_SVELTE`

### `SB_SVELTE_CSF_PARSER_EXTRACT_SVELTE_1`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_EXTRACT_SVELTE_2`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_EXTRACT_SVELTE_3`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_EXTRACT_SVELTE_4`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_EXTRACT_SVELTE_5`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_EXTRACT_SVELTE_6`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_EXTRACT_SVELTE_7`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_EXTRACT_SVELTE_8`

<!-- TODO: -->

## `PARSER_EXTRACT_COMPILED`

### `SB_SVELTE_CSF_PARSER_EXTRACT_COMPILED_1`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_EXTRACT_COMPILED_2`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_EXTRACT_COMPILED_3`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_EXTRACT_COMPILED_4`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_EXTRACT_COMPILED_5`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_EXTRACT_COMPILED_6`

## `PARSER_ANALYSE_DEFINE_META`

### `SB_SVELTE_CSF_PARSER_ANALYSE_DEFINE_META_1`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_ANALYSE_DEFINE_META_2`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_ANALYSE_DEFINE_META_3`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_ANALYSE_DEFINE_META_4`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_ANALYSE_DEFINE_META_5`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_ANALYSE_DEFINE_META_6`

## `PARSER_ANALYSE_STORY`

### `SB_SVELTE_CSF_PARSER_ANALYSE_STORY_1`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_ANALYSE_STORY_2`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_ANALYSE_STORY_3`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_ANALYSE_STORY_4`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_ANALYSE_STORY_5`

<!-- TODO: -->

### `SB_SVELTE_CSF_PARSER_ANALYSE_STORY_6`

<!-- TODO: -->

## `COMPILER`

### `SB_SVELTE_CSF_COMPILER_1`

<!-- TODO: -->

### `SB_SVELTE_CSF_COMPILER_2`

<!-- TODO: -->

### `SB_SVELTE_CSF_COMPILER_3`

<!-- TODO: -->
1 change: 1 addition & 0 deletions src/indexer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const indexer: Indexer = {
attributes: ['exportName', 'name', 'tags'],
});
const { exportName, name } = getStoryIdentifiers({
component,
nameNode: attributeNode.name,
exportNameNode: attributeNode.exportName,
filename,
Expand Down
25 changes: 17 additions & 8 deletions src/parser/analyse/story/attributes/identifiers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ describe(getStoryIdentifiers.name, () => {
filename: 'invalid.stories.svelte',
})
).toThrowErrorMatchingInlineSnapshot(

Check failure on line 79 in src/parser/analyse/story/attributes/identifiers.test.ts

View workflow job for this annotation

GitHub Actions / Test

src/parser/analyse/story/attributes/identifiers.test.ts > getStoryIdentifiers > throws when '<Story />' doesn't provide an 'exportName' or 'name' attribute prop

Error: Snapshot `getStoryIdentifiers > throws when '<Story />' doesn't provide an 'exportName' or 'name' attribute prop 1` mismatched - Expected + Received - [SB_SVELTE_CSF_PARSER_ANALYSE_STORY_0004 (NoStoryIdentifierError): Missing 'name' or 'exportName' attribute (prop) in a '<Story />' definition in the stories file: 'file:///Users/xeho91/Nextcloud/Projects/oss/addon-svelte-csf/invalid.stories.svelte'. + [SB_SVELTE_CSF_PARSER_ANALYSE_STORY_0004 (NoStoryIdentifierError): Missing 'name' or 'exportName' attribute (prop) in a '<Story />' definition in the stories file: 'file:///home/runner/work/addon-svelte-csf/addon-svelte-csf/invalid.stories.svelte'. All stories must either have a 'name' or an 'exportName' prop.] ❯ src/parser/analyse/story/attributes/identifiers.test.ts:79:7
`[Error: Missing 'name' or 'exportName' prop in a <Story /> definition in the 'invalid.stories.svelte' file. All stories must either have a 'name' or an 'exportName' prop.]`
`
[SB_SVELTE_CSF_PARSER_ANALYSE_STORY_0004 (NoStoryIdentifierError): Missing 'name' or 'exportName' attribute (prop) in a '<Story />' definition in the stories file: 'file:///Users/xeho91/Nextcloud/Projects/oss/addon-svelte-csf/invalid.stories.svelte'.
All stories must either have a 'name' or an 'exportName' prop.]
`
);
});

Expand Down Expand Up @@ -177,9 +180,11 @@ describe(getStoryIdentifiers.name, () => {
})
).toThrowErrorMatchingInlineSnapshot(

Check failure on line 181 in src/parser/analyse/story/attributes/identifiers.test.ts

View workflow job for this annotation

GitHub Actions / Test

src/parser/analyse/story/attributes/identifiers.test.ts > getStoryIdentifiers > throws when 'exportName' is not a valid JavaScript variable name

Error: Snapshot `getStoryIdentifiers > throws when 'exportName' is not a valid JavaScript variable name 1` mismatched - Expected + Received - [SB_SVELTE_CSF_PARSER_ANALYSE_STORY_0005 (InvalidStoryExportNameError): Invalid attribute 'exportName' value 'default' found in '<Story />' component inside stories file: file:///Users/xeho91/Nextcloud/Projects/oss/addon-svelte-csf/invalid.stories.svelte + [SB_SVELTE_CSF_PARSER_ANALYSE_STORY_0005 (InvalidStoryExportNameError): Invalid attribute 'exportName' value 'default' found in '<Story />' component inside stories file: file:///home/runner/work/addon-svelte-csf/addon-svelte-csf/invalid.stories.svelte 'exportName' alue must be a valid JavaScript variable name. It must start with a letter, $ or _, followed by letters, numbers, $ or _. Reserved words like 'default' are also not allowed (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#reserved_words)] ❯ src/parser/analyse/story/attributes/identifiers.test.ts:181:7
`
[Error: Invalid exportName 'default' found in <Story /> component in 'invalid.stories.svelte'.
exportName must be a valid JavaScript variable name. It must start with a letter, $ or _, followed by letters, numbers, $ or _.
Reserved words like 'default' are also not allowed (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#reserved_words)]
[SB_SVELTE_CSF_PARSER_ANALYSE_STORY_0005 (InvalidStoryExportNameError): Invalid attribute 'exportName' value 'default' found in '<Story />' component inside stories file: file:///Users/xeho91/Nextcloud/Projects/oss/addon-svelte-csf/invalid.stories.svelte
'exportName' alue must be a valid JavaScript variable name.
It must start with a letter, $ or _, followed by letters, numbers, $ or _.
Reserved words like 'default' are also not allowed (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#reserved_words)]
`
);
});
Expand Down Expand Up @@ -244,11 +249,13 @@ describe(getStoriesIdentifiers.name, () => {
})
).toThrowErrorMatchingInlineSnapshot(

Check failure on line 250 in src/parser/analyse/story/attributes/identifiers.test.ts

View workflow job for this annotation

GitHub Actions / Test

src/parser/analyse/story/attributes/identifiers.test.ts > getStoriesIdentifiers > throws on identical 'exportName' attributes

Error: Snapshot `getStoriesIdentifiers > throws on identical 'exportName' attributes 1` mismatched - Expected + Received @@ -1,6 +1,6 @@ - [SB_SVELTE_CSF_PARSER_ANALYSE_STORY_0006 (DuplicateStoryIdentifiersError): Duplicate exportNames found between two '<Story />' definitions in stories file: file:///Users/xeho91/Nextcloud/Projects/oss/addon-svelte-csf/duplicate-identifiers.stories.svelte + [SB_SVELTE_CSF_PARSER_ANALYSE_STORY_0006 (DuplicateStoryIdentifiersError): Duplicate exportNames found between two '<Story />' definitions in stories file: file:///home/runner/work/addon-svelte-csf/addon-svelte-csf/duplicate-identifiers.stories.svelte First instance: <Story name={undefined} exportName="SomeExportName" ... /> Second instance: <Story name={undefined} exportName="SomeExportName" ... /> This can happen when 'exportName' is implicitly derived by 'name'. ❯ src/parser/analyse/story/attributes/identifiers.test.ts:250:7
`
[Error: Duplicate exportNames found between two <Story /> definitions in 'duplicate-identifiers.stories.svelte':
[SB_SVELTE_CSF_PARSER_ANALYSE_STORY_0006 (DuplicateStoryIdentifiersError): Duplicate exportNames found between two '<Story />' definitions in stories file: file:///Users/xeho91/Nextcloud/Projects/oss/addon-svelte-csf/duplicate-identifiers.stories.svelte
First instance: <Story name={undefined} exportName="SomeExportName" ... />
Second instance: <Story name={undefined} exportName="SomeExportName" ... />
This can happen when 'exportName' is implicitly derived by 'name'. Complex names will be simplified to a PascalCased, valid JavaScript variable name,
This can happen when 'exportName' is implicitly derived by 'name'.
Complex names will be simplified to a PascalCased, valid JavaScript variable name,
eg. 'Some story name!!' will be converted to 'SomeStoryName'.
You can fix this collision by providing a unique 'exportName' prop with <Story exportName="SomeUniqueExportName" ... />.]
`
Expand All @@ -275,11 +282,13 @@ describe(getStoriesIdentifiers.name, () => {
})
).toThrowErrorMatchingInlineSnapshot(

Check failure on line 283 in src/parser/analyse/story/attributes/identifiers.test.ts

View workflow job for this annotation

GitHub Actions / Test

src/parser/analyse/story/attributes/identifiers.test.ts > getStoriesIdentifiers > throws on identical 'exportName' attributes when deriving from 'name' attributes

Error: Snapshot `getStoriesIdentifiers > throws on identical 'exportName' attributes when deriving from 'name' attributes 1` mismatched - Expected + Received @@ -1,6 +1,6 @@ - [SB_SVELTE_CSF_PARSER_ANALYSE_STORY_0006 (DuplicateStoryIdentifiersError): Duplicate exportNames found between two '<Story />' definitions in stories file: file:///Users/xeho91/Nextcloud/Projects/oss/addon-svelte-csf/duplicate-identifiers.stories.svelte + [SB_SVELTE_CSF_PARSER_ANALYSE_STORY_0006 (DuplicateStoryIdentifiersError): Duplicate exportNames found between two '<Story />' definitions in stories file: file:///home/runner/work/addon-svelte-csf/addon-svelte-csf/duplicate-identifiers.stories.svelte First instance: <Story name={undefined} exportName="SomeStoryName" ... /> Second instance: <Story name="some story name!!!" exportName="SomeStoryName" ... /> This can happen when 'exportName' is implicitly derived by 'name'. ❯ src/parser/analyse/story/attributes/identifiers.test.ts:283:7
`
[Error: Duplicate exportNames found between two <Story /> definitions in 'duplicate-identifiers.stories.svelte':
[SB_SVELTE_CSF_PARSER_ANALYSE_STORY_0006 (DuplicateStoryIdentifiersError): Duplicate exportNames found between two '<Story />' definitions in stories file: file:///Users/xeho91/Nextcloud/Projects/oss/addon-svelte-csf/duplicate-identifiers.stories.svelte
First instance: <Story name={undefined} exportName="SomeStoryName" ... />
Second instance: <Story name="some story name!!!" exportName="SomeStoryName" ... />
This can happen when 'exportName' is implicitly derived by 'name'. Complex names will be simplified to a PascalCased, valid JavaScript variable name,
This can happen when 'exportName' is implicitly derived by 'name'.
Complex names will be simplified to a PascalCased, valid JavaScript variable name,
eg. 'Some story name!!' will be converted to 'SomeStoryName'.
You can fix this collision by providing a unique 'exportName' prop with <Story exportName="SomeUniqueExportName" ... />.]
`
Expand Down
48 changes: 29 additions & 19 deletions src/parser/analyse/story/attributes/identifiers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import dedent from 'dedent';
import type { Attribute } from 'svelte/compiler';
import type { Attribute, Component } from 'svelte/compiler';

import { getStringValueFromAttribute } from '../attributes';

import type { SvelteASTNodes } from '#parser/extract/svelte/nodes';
import { extractStoryAttributesNodes } from '#parser/extract/svelte/story/attributes';
import { isValidVariableName, storyNameToExportName } from '#utils/identifier-utils';
import {
DuplicateStoryIdentifiersError,
InvalidStoryExportNameError,
NoStoryIdentifierError,
} from '#utils/error/parser/analyse/story';

type StoryIdentifiers = {
exportName: string;
Expand All @@ -16,31 +20,39 @@ interface GetIdentifiersParams {
nameNode?: Attribute | undefined;
exportNameNode?: Attribute | undefined;
filename?: string;
component: Component;
}

export function getStoryIdentifiers(options: GetIdentifiersParams): StoryIdentifiers {
const { nameNode, exportNameNode, filename } = options;
const { nameNode, exportNameNode, filename, component } = options;

let exportName = getStringValueFromAttribute({
node: exportNameNode,
filename,
component,
});
const name = getStringValueFromAttribute({
node: nameNode,
filename,
component,
});
const name = getStringValueFromAttribute({ node: nameNode, filename });

if (!exportName) {
if (!name) {
throw new Error(
`Missing 'name' or 'exportName' prop in a <Story /> definition in the '${filename}' file. All stories must either have a 'name' or an 'exportName' prop.`
);
throw new NoStoryIdentifierError({
component,
filename,
});
}
exportName = storyNameToExportName(name);
}

if (!isValidVariableName(exportName)) {
throw new Error(dedent`Invalid exportName '${exportName}' found in <Story /> component in '${filename}'.
exportName must be a valid JavaScript variable name. It must start with a letter, $ or _, followed by letters, numbers, $ or _.
Reserved words like 'default' are also not allowed (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#reserved_words)
`);
throw new InvalidStoryExportNameError({
filename,
component,
value: exportName,
});
}

return {
Expand Down Expand Up @@ -70,21 +82,19 @@ export function getStoriesIdentifiers(params: GetStoriesIdentifiersParams): Stor
exportNameNode: exportName,
nameNode: name,
filename,
component: story.component,
});

const duplicateIdentifiers = allIdentifiers.find(
(existingIdentifiers) => existingIdentifiers.exportName === identifiers.exportName
);

if (duplicateIdentifiers) {
throw new Error(dedent`Duplicate exportNames found between two <Story /> definitions in '${filename}':
First instance: <Story name=${duplicateIdentifiers.name ? `"${duplicateIdentifiers.name}"` : '{undefined}'} exportName="${duplicateIdentifiers.exportName}" ... />
Second instance: <Story name=${identifiers.name ? `"${identifiers.name}"` : '{undefined}'} exportName="${identifiers.exportName}" ... />
This can happen when 'exportName' is implicitly derived by 'name'. Complex names will be simplified to a PascalCased, valid JavaScript variable name,
eg. 'Some story name!!' will be converted to 'SomeStoryName'.
You can fix this collision by providing a unique 'exportName' prop with <Story exportName="SomeUniqueExportName" ... />.
`);
throw new DuplicateStoryIdentifiersError({
filename,
identifiers,
duplicateIdentifiers,
});
}

allIdentifiers.push(identifiers);
Expand Down
12 changes: 6 additions & 6 deletions src/utils/error/parser/analyse/define-meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class InvalidComponentValueError extends StorybookSvelteCSFError {
filename,
componentProperty,
}: {
filename: StorybookSvelteCSFError['storiesFilename'];
filename: StorybookSvelteCSFError['filename'];
componentProperty: InvalidComponentValueError['componentProperty'];
}) {
super({ filename });
Expand Down Expand Up @@ -41,7 +41,7 @@ export class NoDestructuredDefineMetaCallError extends StorybookSvelteCSFError {
filename,
defineMetaVariableDeclarator,
}: {
filename: StorybookSvelteCSFError['storiesFilename'];
filename: StorybookSvelteCSFError['filename'];
defineMetaVariableDeclarator: NoDestructuredDefineMetaCallError['defineMetaVariableDeclarator'];
}) {
super({ filename });
Expand All @@ -68,7 +68,7 @@ export class NoMetaIdentifierFoundError extends StorybookSvelteCSFError {
readonly category = StorybookSvelteCSFError.CATEGORY.parserAnalyseDefineMeta;
readonly code = 3;

constructor(filename: StorybookSvelteCSFError['storiesFilename']) {
constructor(filename: StorybookSvelteCSFError['filename']) {
super({ filename });
}

Expand Down Expand Up @@ -97,7 +97,7 @@ export class NoStringLiteralError extends StorybookSvelteCSFError {
filename,
property,
}: {
filename: StorybookSvelteCSFError['storiesFilename'];
filename: StorybookSvelteCSFError['filename'];
property: NoStringLiteralError['property'];
}) {
super({ filename });
Expand Down Expand Up @@ -126,7 +126,7 @@ export class NoArrayExpressionError extends StorybookSvelteCSFError {
filename,
property,
}: {
filename: StorybookSvelteCSFError['storiesFilename'];
filename: StorybookSvelteCSFError['filename'];
property: NoArrayExpressionError['property'];
}) {
super({ filename });
Expand Down Expand Up @@ -157,7 +157,7 @@ export class ArrayElementNotStringError extends StorybookSvelteCSFError {
property,
element,
}: {
filename: StorybookSvelteCSFError['storiesFilename'];
filename: StorybookSvelteCSFError['filename'];
property: ArrayElementNotStringError['property'];
element: ArrayElementNotStringError['element'];
}) {
Expand Down
Loading

0 comments on commit 2f0a74f

Please sign in to comment.