@storybook/addon-svelte-csf
Advanced tools
Comparing version 5.0.0--canary.190.0ab0039.0 to 5.0.0--canary.228.5081d3b.0
@@ -1,16 +0,47 @@ | ||
import type { Args as BaseArgs } from '@storybook/types'; | ||
import type { EmptyObject } from 'type-fest'; | ||
import type { Meta as MetaType, StoryCmp, StoryContext as BaseStoryContext, StoryAnnotations, Cmp } from '#types'; | ||
import StoryComponent from './runtime/Story.svelte'; | ||
import LegacyMetaComponent from './runtime/LegacyMeta.svelte'; | ||
import LegacyStoryComponent from './runtime/LegacyStory.svelte'; | ||
import LegacyTemplateComponent from './runtime/LegacyTemplate.svelte'; | ||
export { setTemplate } from './runtime/contexts/template.svelte'; | ||
export declare function defineMeta<const TOverrideArgs extends BaseArgs = EmptyObject, const TCmp extends Cmp = Cmp>(meta: MetaType<TCmp>): { | ||
Story: StoryCmp<EmptyObject, TCmp, typeof meta>; | ||
import type { Meta as MetaType, StoryContext as BaseStoryContext, StoryAnnotations, Cmp } from './types'; | ||
export declare function defineMeta<const TCmp extends Cmp>(meta: MetaType<TCmp>): { | ||
Story: typeof StoryComponent<TCmp>; | ||
meta: MetaType<TCmp>; | ||
}; | ||
export type Args<TStoryCmp> = TStoryCmp extends StoryCmp<infer _TOverrideArgs, infer TCmpOrArgs, infer TMeta> ? NonNullable<StoryAnnotations<TCmpOrArgs, TMeta>['args']> : never; | ||
export type StoryContext<TStoryCmp> = TStoryCmp extends StoryCmp<infer _TOverrideArgs, infer TCmpOrArgs, infer TMeta> ? BaseStoryContext<TCmpOrArgs, TMeta> : never; | ||
/** | ||
* Infer **first** parameter type `args` in template snippet specified at the root of fragment _(a shared one)_. | ||
* @template TStoryCmp destructured `Story` property from the {@link defineMeta} call. | ||
* | ||
* @example | ||
* ```svelte | ||
* {#snippet template(args: Args<typeof Story>)} | ||
* <!-- 👆 first parameter -> | ||
* {/snippet} | ||
* ``` | ||
*/ | ||
export type Args<TStoryCmp> = TStoryCmp extends typeof StoryComponent<infer TCmp extends Cmp> ? NonNullable<StoryAnnotations<TCmp>['args']> : never; | ||
/** | ||
* Infer **second** parameter type `storyContext` in template snippet specified at the root of fragment _(a shared one)_. | ||
* @template TStoryCmp destructured `Story` property from the {@link defineMeta} call. | ||
* | ||
* @example | ||
* ```svelte | ||
* {#snippet template(args: Args<typeof Story>, context: StoryContext<typeof Story>)} | ||
* <!-- 👆 second parameter -> | ||
* {/snippet} | ||
* ``` | ||
*/ | ||
export type StoryContext<TStoryCmp> = TStoryCmp extends typeof StoryComponent<infer TCmp extends Cmp> ? BaseStoryContext<TCmp> : never; | ||
/** | ||
* Fill the generic type parameter for [`createRawSnippet()`](https://svelte.dev/docs/svelte/svelte#createRawSnippet) | ||
* to get better type-safety experience. | ||
* @template TStoryCmp destructured `Story` property from the {@link defineMeta} call. | ||
*/ | ||
export type TemplateSnippet<TStoryCmp> = [Args<TStoryCmp>, StoryContext<TStoryCmp>]; | ||
export { | ||
/** | ||
* @deprecated Use `defineMeta` instead | ||
* @see {@link https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#meta-component-removed-in-favor-of-definemeta} | ||
*/ | ||
export declare const Meta: () => never; | ||
LegacyMetaComponent as Meta, | ||
/** | ||
@@ -20,3 +51,3 @@ * @deprecated Use `Story` component returned from `defineMeta` instead | ||
*/ | ||
export declare const Story: () => never; | ||
LegacyStoryComponent as Story, | ||
/** | ||
@@ -26,2 +57,3 @@ * @deprecated Use snippets instead | ||
*/ | ||
export declare const Template: () => never; | ||
LegacyTemplateComponent as Template, }; | ||
export * from './legacy-types.d'; |
@@ -1,3 +0,8 @@ | ||
import dedent from 'dedent'; | ||
import StoryComponent from './runtime/Story.svelte'; | ||
// TODO: Remove in next major release | ||
import LegacyMetaComponent from './runtime/LegacyMeta.svelte'; | ||
// TODO: Remove in next major release | ||
import LegacyStoryComponent from './runtime/LegacyStory.svelte'; | ||
// TODO: Remove in next major release | ||
import LegacyTemplateComponent from './runtime/LegacyTemplate.svelte'; | ||
export { setTemplate } from './runtime/contexts/template.svelte'; | ||
@@ -10,2 +15,4 @@ export function defineMeta(meta) { | ||
} | ||
// TODO: Remove in next major release | ||
export { | ||
/** | ||
@@ -15,8 +22,3 @@ * @deprecated Use `defineMeta` instead | ||
*/ | ||
export const Meta = () => { | ||
throw new Error(dedent ` | ||
The Meta component has been removed in favor of the defineMeta function. | ||
For more details, see: @link https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#meta-component-removed-in-favor-of-definemeta | ||
`); | ||
}; | ||
LegacyMetaComponent as Meta, | ||
/** | ||
@@ -26,8 +28,3 @@ * @deprecated Use `Story` component returned from `defineMeta` instead | ||
*/ | ||
export const Story = () => { | ||
throw new Error(dedent ` | ||
The Story component can not be imported anymore, but must be desctructured from the defineMeta() call. | ||
For more details, see: https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#export-meta-removed-in-favor-of-definemeta | ||
`); | ||
}; | ||
LegacyStoryComponent as Story, | ||
/** | ||
@@ -37,7 +34,4 @@ * @deprecated Use snippets instead | ||
*/ | ||
export const Template = () => { | ||
throw new Error(dedent ` | ||
The Template component has been removed in favor of the snippets syntax. | ||
see: https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#template-component-removed | ||
`); | ||
}; | ||
LegacyTemplateComponent as Template, }; | ||
// TODO: Remove in next major release | ||
export * from './legacy-types.d'; |
import type { Indexer } from '@storybook/types'; | ||
export declare const indexer: Indexer; | ||
export declare const createIndexer: (legacyTemplate: boolean) => Indexer; |
@@ -1,73 +0,35 @@ | ||
import fs from 'node:fs/promises'; | ||
import { combineTags } from '@storybook/csf'; | ||
import { preprocess } from 'svelte/compiler'; | ||
import { getSvelteAST } from '#parser/ast'; | ||
import { extractSvelteASTNodes } from '#parser/extract/svelte/nodes'; | ||
import { extractDefineMetaPropertiesNodes } from '#parser/extract/svelte/define-meta'; | ||
import { extractStoryAttributesNodes } from '#parser/extract/svelte/story/attributes'; | ||
import { getPropertyArrayOfStringsValue, getPropertyStringValue, } from '#parser/analyse/define-meta/properties'; | ||
import { getArrayOfStringsValueFromAttribute } from '#parser/analyse/story/attributes'; | ||
import { getStoryIdentifiers } from '#parser/analyse/story/attributes/identifiers'; | ||
export const indexer = { | ||
import { parseForIndexer } from '#indexer/parser'; | ||
import { GetDefineMetaFirstArgumentError, IndexerParseError, MissingModuleTagError, NoStoryComponentDestructuredError, } from '#utils/error/parser/extract/svelte'; | ||
import { LegacyTemplateNotEnabledError } from '#utils/error/legacy-api/index'; | ||
import { NoDestructuredDefineMetaCallError } from '#utils/error/parser/analyse/define-meta'; | ||
export const createIndexer = (legacyTemplate) => ({ | ||
test: /\.svelte$/, | ||
createIndex: async (filename, { makeTitle }) => { | ||
let [code, { loadSvelteConfig }] = await Promise.all([ | ||
fs.readFile(filename, { encoding: 'utf8' }), | ||
import('@sveltejs/vite-plugin-svelte'), | ||
]); | ||
const svelteConfig = await loadSvelteConfig(); | ||
if (svelteConfig?.preprocess) { | ||
code = (await preprocess(code, svelteConfig.preprocess, { | ||
filename: filename, | ||
})).code; | ||
try { | ||
const { meta, stories } = await parseForIndexer(filename, { legacyTemplate }); | ||
return stories.map((story) => { | ||
return { | ||
type: 'story', | ||
importPath: filename, | ||
exportName: story.exportName, | ||
name: story.name, | ||
title: makeTitle(meta.title), | ||
tags: [...(meta.tags ?? []), ...(story.tags ?? [])], | ||
}; | ||
}); | ||
} | ||
const svelteAST = getSvelteAST({ code, filename }); | ||
const svelteASTNodes = await extractSvelteASTNodes({ | ||
ast: svelteAST, | ||
filename, | ||
}); | ||
const metaPropertiesNodes = extractDefineMetaPropertiesNodes({ | ||
nodes: svelteASTNodes, | ||
filename, | ||
properties: ['id', 'title', 'tags'], | ||
}); | ||
const metaTitle = metaPropertiesNodes.title | ||
? makeTitle(getPropertyStringValue({ | ||
node: metaPropertiesNodes.title, | ||
filename, | ||
})) | ||
: undefined; | ||
const metaTags = metaPropertiesNodes.tags | ||
? getPropertyArrayOfStringsValue({ | ||
node: metaPropertiesNodes.tags, | ||
filename, | ||
}) | ||
: []; | ||
return svelteASTNodes.storyComponents.map(({ component }) => { | ||
const attributeNode = extractStoryAttributesNodes({ | ||
component, | ||
filename, | ||
attributes: ['exportName', 'name', 'tags'], | ||
}); | ||
const { exportName, name } = getStoryIdentifiers({ | ||
component, | ||
nameNode: attributeNode.name, | ||
exportNameNode: attributeNode.exportName, | ||
filename, | ||
}); | ||
const tags = getArrayOfStringsValueFromAttribute({ | ||
node: attributeNode.tags, | ||
filename, | ||
component, | ||
}); | ||
return { | ||
type: 'story', | ||
importPath: filename, | ||
exportName, | ||
name, | ||
title: metaTitle, | ||
tags: combineTags(...metaTags, ...tags), | ||
}; | ||
}); | ||
catch (error) { | ||
if ( | ||
// NOTE: Those errors are hand-picked from what might be thrown in `./parser.ts` | ||
// and are related to using legacy API. | ||
error instanceof MissingModuleTagError || | ||
error instanceof NoDestructuredDefineMetaCallError || | ||
error instanceof NoStoryComponentDestructuredError || | ||
error instanceof GetDefineMetaFirstArgumentError) { | ||
const { filename } = error; | ||
throw new LegacyTemplateNotEnabledError(filename); | ||
} | ||
throw new IndexerParseError(); | ||
} | ||
}, | ||
}; | ||
}); |
@@ -1,2 +0,2 @@ | ||
import type { Identifier } from 'estree'; | ||
import type { ESTreeAST } from '#parser/ast'; | ||
import type { SvelteASTNodes } from '#parser/extract/svelte/nodes'; | ||
@@ -7,3 +7,3 @@ interface Params { | ||
} | ||
export declare function getDefineMetaComponentValue(params: Params): Identifier | undefined; | ||
export declare function getDefineMetaComponentValue(params: Params): ESTreeAST.Identifier | undefined; | ||
export {}; |
@@ -1,2 +0,2 @@ | ||
import type { Identifier } from 'estree'; | ||
import type { ESTreeAST } from '#parser/ast'; | ||
import type { SvelteASTNodes } from '#parser/extract/svelte/nodes'; | ||
@@ -7,3 +7,3 @@ interface Params { | ||
} | ||
export declare function getMetaIdentifier(params: Params): Identifier; | ||
export declare function getMetaIdentifier(params: Params): ESTreeAST.Identifier; | ||
export {}; |
@@ -1,4 +0,4 @@ | ||
import type { Property } from 'estree'; | ||
import type { ESTreeAST } from '#parser/ast'; | ||
interface GetStringOptions { | ||
node: Property; | ||
node: ESTreeAST.Property; | ||
filename: string; | ||
@@ -8,3 +8,3 @@ } | ||
interface GetArrayOfStringOptions { | ||
node: Property; | ||
node: ESTreeAST.Property; | ||
filename: string; | ||
@@ -11,0 +11,0 @@ } |
@@ -1,9 +0,9 @@ | ||
import type { Attribute, Component } from 'svelte/compiler'; | ||
import type { SvelteAST } from '#parser/ast'; | ||
interface Params { | ||
node: Attribute | undefined; | ||
node: SvelteAST.Attribute | undefined; | ||
filename?: string; | ||
component: Component; | ||
component: SvelteAST.Component; | ||
} | ||
export declare function getStringValueFromAttribute(params: Params): string | undefined; | ||
export declare function getStringValueFromAttribute(params: Params): any; | ||
export declare function getArrayOfStringsValueFromAttribute(params: Params): string[]; | ||
export {}; |
@@ -8,5 +8,10 @@ import { AttributeNotArrayError, AttributeNotArrayOfStringsError, AttributeNotStringError, } from '#utils/error/parser/analyse/story'; | ||
const { value } = node; | ||
if (value === true || value.length !== 1) { | ||
if (value === true) { | ||
throw new AttributeNotStringError({ filename, component, attribute: node }); | ||
} | ||
if (!Array.isArray(value) && | ||
value.type === 'ExpressionTag' && | ||
value.expression.type === 'Literal') { | ||
return value.expression.value; | ||
} | ||
if (value[0].type === 'Text') { | ||
@@ -28,6 +33,3 @@ return value[0].data; | ||
const { value } = node; | ||
if (value === true || | ||
value.length !== 1 || | ||
value[0].type !== 'ExpressionTag' || | ||
value[0].expression.type !== 'ArrayExpression') { | ||
if (value === true) { | ||
throw new AttributeNotArrayError({ | ||
@@ -39,2 +41,33 @@ component, | ||
} | ||
// value is SvelteAST.ExpressionTag | ||
if (!Array.isArray(value)) { | ||
if (value.expression.type !== 'ArrayExpression') { | ||
throw new AttributeNotArrayError({ | ||
component, | ||
filename, | ||
attribute: node, | ||
}); | ||
} | ||
let arrayOfStrings = []; | ||
for (const element of value.expression.elements) { | ||
if (element?.type !== 'Literal' || typeof element.value !== 'string') { | ||
throw new AttributeNotArrayOfStringsError({ | ||
filename, | ||
component, | ||
attribute: node, | ||
element, | ||
}); | ||
} | ||
arrayOfStrings.push(element.value); | ||
} | ||
return arrayOfStrings; | ||
} | ||
// value is Array<SvelteAST.ExpressionTag | SvelteAST.Text> - I haven't figured out when it would happen | ||
if (value[0].type !== 'ExpressionTag' || value[0].expression.type !== 'ArrayExpression') { | ||
throw new AttributeNotArrayError({ | ||
component, | ||
filename, | ||
attribute: node, | ||
}); | ||
} | ||
const arrayOfStrings = []; | ||
@@ -41,0 +74,0 @@ for (const element of value[0].expression.elements) { |
@@ -1,2 +0,2 @@ | ||
import type { Attribute, Component } from 'svelte/compiler'; | ||
import type { SvelteAST } from '#parser/ast'; | ||
import type { SvelteASTNodes } from '#parser/extract/svelte/nodes'; | ||
@@ -8,6 +8,6 @@ type StoryIdentifiers = { | ||
interface GetIdentifiersParams { | ||
nameNode?: Attribute | undefined; | ||
exportNameNode?: Attribute | undefined; | ||
nameNode?: SvelteAST.Attribute | undefined; | ||
exportNameNode?: SvelteAST.Attribute | undefined; | ||
filename?: string; | ||
component: Component; | ||
component: SvelteAST.Component; | ||
} | ||
@@ -14,0 +14,0 @@ export declare function getStoryIdentifiers(options: GetIdentifiersParams): StoryIdentifiers; |
@@ -1,2 +0,2 @@ | ||
import { getStringValueFromAttribute } from '../attributes'; | ||
import { getStringValueFromAttribute } from '#parser/analyse/story/attributes'; | ||
import { extractStoryAttributesNodes } from '#parser/extract/svelte/story/attributes'; | ||
@@ -3,0 +3,0 @@ import { isValidVariableName, storyNameToExportName } from '#utils/identifier-utils'; |
@@ -1,6 +0,6 @@ | ||
import type { Component } from 'svelte/compiler'; | ||
import type { SvelteAST } from '#parser/ast'; | ||
import type { extractSvelteASTNodes } from '#parser/extract/svelte/nodes'; | ||
interface Params { | ||
nodes: { | ||
component: Component; | ||
component: SvelteAST.Component; | ||
svelte: Awaited<ReturnType<typeof extractSvelteASTNodes>>; | ||
@@ -7,0 +7,0 @@ }; |
import dedent from 'dedent'; | ||
import { getDefineMetaComponentValue } from '#parser/analyse/define-meta/component-identifier'; | ||
import { extractStoryChildrenSnippetBlock } from '#parser/extract/svelte/story/children'; | ||
import { findSetTemplateSnippetBlock, findStoryAttributeChildrenSnippetBlock, } from '#parser/extract/svelte/snippet-block'; | ||
import { getDefineMetaComponentValue } from '#parser/analyse/define-meta/component-identifier'; | ||
/** | ||
@@ -6,0 +6,0 @@ * Extract the source code of the `<Story />` component children. |
@@ -1,2 +0,3 @@ | ||
import { type Root } from 'svelte/compiler'; | ||
import type * as ESTreeAST from 'estree'; | ||
import { type AST as SvelteAST } from 'svelte/compiler'; | ||
interface GetSvelteASTOptions { | ||
@@ -6,3 +7,32 @@ code: string; | ||
} | ||
export declare function getSvelteAST(options: GetSvelteASTOptions): Root; | ||
export {}; | ||
export declare function getSvelteAST(options: GetSvelteASTOptions): SvelteAST.Root; | ||
/** | ||
* Create Svelte compliant AST node for {@link SvelteAST.Attibute} with optional value. | ||
* By default it will create an shorthand attribute. | ||
*/ | ||
export declare function createASTAttribute(name: string, value?: SvelteAST.Attribute['value']): SvelteAST.Attribute; | ||
/** | ||
* Create Svelte compliant AST node for {@link SvelteAST.ExpressionTag} with optional value. | ||
* By default it will create an shorthand attribute. | ||
*/ | ||
export declare function createASTExpressionTag(expression: SvelteAST.ExpressionTag['expression']): SvelteAST.ExpressionTag; | ||
/** | ||
* Create ESTree compliant AST node for {@link ESTreeAST.Property} | ||
*/ | ||
export declare function createASTProperty(name: string, value: ESTreeAST.Property['value']): ESTreeAST.Property; | ||
/** | ||
* Create ESTree compliant AST node for {@link ESTreeAST.ArrayExpression} with optional array of elements. | ||
* By default it will create an empty array. | ||
*/ | ||
export declare function createASTArrayExpression(elements?: ESTreeAST.ArrayExpression['elements']): ESTreeAST.ArrayExpression; | ||
/** | ||
* Create ESTree compliant AST node for {@link ESTreeAST.ObjectExpression} with optional array of properties. | ||
* By default it will create an empty object. | ||
*/ | ||
export declare function createASTObjectExpression(properties?: ESTreeAST.ObjectExpression['properties']): ESTreeAST.ObjectExpression; | ||
interface ASTScriptOptions { | ||
module?: boolean; | ||
content: SvelteAST.Script['content']; | ||
} | ||
export declare function createASTScript(options: ASTScriptOptions): SvelteAST.Script; | ||
export type { ESTreeAST, SvelteAST }; |
@@ -10,1 +10,72 @@ import { compile } from 'svelte/compiler'; | ||
} | ||
/** | ||
* Create Svelte compliant AST node for {@link SvelteAST.Attibute} with optional value. | ||
* By default it will create an shorthand attribute. | ||
*/ | ||
export function createASTAttribute(name, value = true) { | ||
return { | ||
type: 'Attribute', | ||
name, | ||
value, | ||
}; | ||
} | ||
/** | ||
* Create Svelte compliant AST node for {@link SvelteAST.ExpressionTag} with optional value. | ||
* By default it will create an shorthand attribute. | ||
*/ | ||
export function createASTExpressionTag(expression) { | ||
return { | ||
type: 'ExpressionTag', | ||
expression, | ||
}; | ||
} | ||
/** | ||
* Create ESTree compliant AST node for {@link ESTreeAST.Property} | ||
*/ | ||
export function createASTProperty(name, value) { | ||
return { | ||
type: 'Property', | ||
kind: 'init', | ||
computed: false, | ||
method: false, | ||
shorthand: false, | ||
key: { | ||
type: 'Identifier', | ||
name, | ||
}, | ||
value, | ||
}; | ||
} | ||
/** | ||
* Create ESTree compliant AST node for {@link ESTreeAST.ArrayExpression} with optional array of elements. | ||
* By default it will create an empty array. | ||
*/ | ||
export function createASTArrayExpression(elements = []) { | ||
return { | ||
type: 'ArrayExpression', | ||
elements, | ||
}; | ||
} | ||
/** | ||
* Create ESTree compliant AST node for {@link ESTreeAST.ObjectExpression} with optional array of properties. | ||
* By default it will create an empty object. | ||
*/ | ||
export function createASTObjectExpression(properties = []) { | ||
return { | ||
type: 'ObjectExpression', | ||
properties, | ||
}; | ||
} | ||
export function createASTScript(options) { | ||
const { content, module = false } = options; | ||
const attributes = []; | ||
if (module) { | ||
attributes.push(createASTAttribute('module')); | ||
} | ||
return { | ||
type: 'Script', | ||
context: module ? 'module' : 'default', | ||
attributes, | ||
content, | ||
}; | ||
} |
@@ -1,3 +0,3 @@ | ||
import type { ExportDefaultDeclaration, FunctionDeclaration, Identifier, ImportSpecifier, Program, VariableDeclaration } from 'estree'; | ||
import type { ProgramNode } from 'rollup'; | ||
import type { ESTreeAST } from '#parser/ast'; | ||
/** | ||
@@ -13,3 +13,3 @@ * Important AST nodes from the compiled output of a single `*.stories.svelte` file. | ||
*/ | ||
defineMetaImport: ImportSpecifier; | ||
defineMetaImport: ESTreeAST.ImportSpecifier; | ||
/** | ||
@@ -19,3 +19,3 @@ * Variable declaration: `const { Story } = defineMeta({ })` | ||
*/ | ||
defineMetaVariableDeclaration: VariableDeclaration; | ||
defineMetaVariableDeclaration: ESTreeAST.VariableDeclaration; | ||
/** | ||
@@ -25,3 +25,3 @@ * Store the `export default declaration`, we will need to remove it later. | ||
*/ | ||
exportDefault: ExportDefaultDeclaration; | ||
exportDefault: ESTreeAST.ExportDefaultDeclaration; | ||
/** | ||
@@ -31,10 +31,10 @@ * An identifier for the addon's component `<Story />`. | ||
*/ | ||
storyIdentifier: Identifier; | ||
storyIdentifier: ESTreeAST.Identifier; | ||
/** | ||
* A function declaration for the main Svelte component which is the `*.stories.svelte` file. | ||
*/ | ||
storiesFunctionDeclaration: FunctionDeclaration; | ||
storiesFunctionDeclaration: ESTreeAST.FunctionDeclaration; | ||
} | ||
interface Params { | ||
ast: Program | ProgramNode; | ||
ast: ESTreeAST.Program | ProgramNode; | ||
filename?: string; | ||
@@ -41,0 +41,0 @@ } |
@@ -1,3 +0,3 @@ | ||
import type { CallExpression, ExpressionStatement } from 'estree'; | ||
import type { CompiledASTNodes } from './nodes'; | ||
import type { ESTreeAST } from '#parser/ast'; | ||
interface Params { | ||
@@ -7,7 +7,4 @@ nodes: CompiledASTNodes; | ||
} | ||
type Result = (CallExpression | ExpressionStatement)[]; | ||
/** | ||
* WARN: The content of this function body differs in the production/development mode | ||
*/ | ||
type Result = (ESTreeAST.CallExpression | ESTreeAST.ExpressionStatement)[]; | ||
export declare function extractStoriesNodesFromExportDefaultFn(params: Params): Promise<Result>; | ||
export {}; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* WARN: The content of this function body differs in the production/development mode | ||
*/ | ||
export async function extractStoriesNodesFromExportDefaultFn(params) { | ||
@@ -10,24 +7,4 @@ const { walk } = await import('zimmerframe'); | ||
const visitors = { | ||
ExpressionStatement(node, { state, next }) { | ||
if (process.env.NODE_ENV !== 'development') { | ||
next(); | ||
} | ||
// 🫠 ... some fun with AST | ||
// Good to know: | ||
// I can't split into smaller if-statements, | ||
// because TypeScript wouldn't understand that `next()` gets out of the currently visited node scope - aka `return;` | ||
if (node.expression.type === 'CallExpression' && | ||
node.expression.callee.type === 'CallExpression' && | ||
node.expression.callee.callee.type === 'MemberExpression' && | ||
node.expression.callee.callee.object.type === 'Identifier' && | ||
node.expression.callee.callee.object.name === '$' && | ||
node.expression.callee.arguments[0].type === 'Identifier' && | ||
node.expression.callee.arguments[0].name === storyIdentifier.name) { | ||
state.push(node); | ||
} | ||
}, | ||
CallExpression(node, { state, next }) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
next(); | ||
} | ||
CallExpression(node, context) { | ||
const { state } = context; | ||
if (node.callee.type === 'Identifier' && node.callee.name === storyIdentifier.name) { | ||
@@ -34,0 +11,0 @@ state.push(node); |
@@ -1,2 +0,2 @@ | ||
import type { ObjectExpression } from 'estree'; | ||
import type { ESTreeAST } from '#parser/ast'; | ||
import type { extractStoriesNodesFromExportDefaultFn } from '#parser/extract/compiled/stories'; | ||
@@ -24,3 +24,3 @@ interface Params { | ||
*/ | ||
export declare function getStoryPropsObjectExpression(params: Params): ObjectExpression; | ||
export declare function getStoryPropsObjectExpression(params: Params): ESTreeAST.ObjectExpression; | ||
export {}; |
@@ -1,2 +0,2 @@ | ||
import type { ObjectExpression, Property } from 'estree'; | ||
import type { ESTreeAST } from '#parser/ast'; | ||
import type { SvelteASTNodes } from '#parser/extract/svelte/nodes'; | ||
@@ -11,3 +11,3 @@ import type { CompiledASTNodes } from '#parser/extract/compiled/nodes'; | ||
type Result<Properties extends Array<keyof Meta<Cmp>>> = Partial<{ | ||
[Key in Properties[number]]: Property; | ||
[Key in Properties[number]]: ESTreeAST.Property; | ||
}>; | ||
@@ -24,3 +24,3 @@ /** | ||
*/ | ||
export declare function getDefineMetaFirstArgumentObjectExpression(options: Pick<Options<Array<keyof Meta<Cmp>>>, 'filename' | 'nodes'>): ObjectExpression; | ||
export declare function getDefineMetaFirstArgumentObjectExpression(options: Pick<Options<Array<keyof Meta<Cmp>>>, 'filename' | 'nodes'>): ESTreeAST.ObjectExpression; | ||
export {}; |
@@ -1,10 +0,10 @@ | ||
import type { Comment, Component, Fragment, SnippetBlock } from 'svelte/compiler'; | ||
import type { extractModuleNodes } from './module-nodes'; | ||
import type { extractInstanceNodes } from './instance-nodes'; | ||
import type { SvelteAST } from '#parser/ast'; | ||
interface Result { | ||
storyComponents: Array<{ | ||
/** Leading HTML comment as AST nodes which can be used as description for the story. */ | ||
comment?: Comment; | ||
comment?: SvelteAST.Comment; | ||
/** '<Story>' component AST node. */ | ||
component: Component; | ||
component: SvelteAST.Component; | ||
}>; | ||
@@ -19,6 +19,6 @@ /** | ||
*/ | ||
snippetBlocks: SnippetBlock[]; | ||
snippetBlocks: SvelteAST.SnippetBlock[]; | ||
} | ||
interface Params { | ||
fragment: Fragment; | ||
fragment: SvelteAST.Fragment; | ||
filename?: string; | ||
@@ -25,0 +25,0 @@ instanceNodes: Awaited<ReturnType<typeof extractInstanceNodes>>; |
@@ -1,9 +0,8 @@ | ||
import type { CallExpression } from 'estree'; | ||
import type { Root } from 'svelte/compiler'; | ||
import type { extractModuleNodes } from './module-nodes'; | ||
import type { ESTreeAST, SvelteAST } from '#parser/ast'; | ||
interface Result { | ||
setTemplateCall: CallExpression | undefined; | ||
setTemplateCall: ESTreeAST.CallExpression | undefined; | ||
} | ||
interface Params { | ||
instance: Root['instance']; | ||
instance: SvelteAST.Root['instance']; | ||
moduleNodes: Awaited<ReturnType<typeof extractModuleNodes>>; | ||
@@ -14,7 +13,7 @@ filename?: string; | ||
* Extract Svelte AST nodes via `svelte.compile`, | ||
* and from the instance tag - `<script>` _(without `context="module"`)_. | ||
* and from the instance tag - `<script>` _(without `module`)_. | ||
* They are needed for further code analysis/transformation. | ||
// NOTE: Is optional for the `*.stories.svelte` files to have this tag. | ||
// NOTE: Is optional for the `*.stories.svelte` files to have this tag. | ||
*/ | ||
export declare function extractInstanceNodes(options: Params): Promise<Result>; | ||
export {}; |
/** | ||
* Extract Svelte AST nodes via `svelte.compile`, | ||
* and from the instance tag - `<script>` _(without `context="module"`)_. | ||
* and from the instance tag - `<script>` _(without `module`)_. | ||
* They are needed for further code analysis/transformation. | ||
// NOTE: Is optional for the `*.stories.svelte` files to have this tag. | ||
// NOTE: Is optional for the `*.stories.svelte` files to have this tag. | ||
*/ | ||
@@ -7,0 +7,0 @@ export async function extractInstanceNodes(options) { |
@@ -1,3 +0,2 @@ | ||
import type { Identifier, ImportSpecifier, VariableDeclaration } from 'estree'; | ||
import type { Root } from 'svelte/compiler'; | ||
import type { ESTreeAST, SvelteAST } from '#parser/ast'; | ||
interface Result { | ||
@@ -8,3 +7,3 @@ /** | ||
*/ | ||
defineMetaImport: ImportSpecifier; | ||
defineMetaImport: ESTreeAST.ImportSpecifier; | ||
/** | ||
@@ -14,3 +13,3 @@ * Import specifier for `setTemplate` imported from this addon package. | ||
*/ | ||
setTemplateImport: ImportSpecifier | undefined; | ||
setTemplateImport: ESTreeAST.ImportSpecifier | undefined; | ||
/** | ||
@@ -20,3 +19,3 @@ * Variable declaration: `const { Story } = defineMeta({ })` | ||
*/ | ||
defineMetaVariableDeclaration: VariableDeclaration; | ||
defineMetaVariableDeclaration: ESTreeAST.VariableDeclaration; | ||
/** | ||
@@ -26,6 +25,6 @@ * An identifier for the addon's component `<Story />`. | ||
*/ | ||
storyIdentifier: Identifier; | ||
storyIdentifier: ESTreeAST.Identifier; | ||
} | ||
interface Params { | ||
module: Root['module']; | ||
module: SvelteAST.Root['module']; | ||
filename?: string; | ||
@@ -35,3 +34,3 @@ } | ||
* Extract Svelte AST nodes via `svelte.compile`, | ||
* and from the module tag - `<script context=module>`. | ||
* and from the module tag - `<script module>`. | ||
* They are needed for further code analysis/transformation. | ||
@@ -38,0 +37,0 @@ */ |
@@ -10,3 +10,3 @@ import pkg from '@storybook/addon-svelte-csf/package.json' with { type: 'json' }; | ||
* Extract Svelte AST nodes via `svelte.compile`, | ||
* and from the module tag - `<script context=module>`. | ||
* and from the module tag - `<script module>`. | ||
* They are needed for further code analysis/transformation. | ||
@@ -13,0 +13,0 @@ */ |
@@ -1,5 +0,5 @@ | ||
import type { Root } from 'svelte/compiler'; | ||
import { extractModuleNodes } from './module-nodes'; | ||
import { extractFragmentNodes } from './fragment-nodes'; | ||
import { extractInstanceNodes } from './instance-nodes'; | ||
import type { SvelteAST } from '#parser/ast'; | ||
/** | ||
@@ -11,3 +11,3 @@ * Selected nodes extracted from the Svelte AST via `svelte.compile`, | ||
interface Params { | ||
ast: Root; | ||
ast: SvelteAST.Root; | ||
filename?: string; | ||
@@ -14,0 +14,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import type { Component, SnippetBlock } from 'svelte/compiler'; | ||
import type { SvelteAST } from '#parser/ast'; | ||
import type { SvelteASTNodes } from '#parser/extract/svelte/nodes'; | ||
@@ -12,3 +12,2 @@ /** | ||
* {/snippet} | ||
* | ||
* <Story children={myTemplate} /> | ||
@@ -21,6 +20,6 @@ * ``` | ||
export declare function findStoryAttributeChildrenSnippetBlock(options: { | ||
component: Component; | ||
component: SvelteAST.Component; | ||
nodes: SvelteASTNodes; | ||
filename?: string; | ||
}): SnippetBlock | undefined; | ||
}): any; | ||
/** | ||
@@ -44,2 +43,2 @@ * Find and extract the AST node of snippet block used by `setTemplate` call in the instance module. | ||
filename?: string; | ||
}): SnippetBlock | undefined; | ||
}): SvelteAST.SnippetBlock | undefined; |
@@ -12,3 +12,2 @@ import { extractStoryAttributesNodes } from '#parser/extract/svelte/story/attributes'; | ||
* {/snippet} | ||
* | ||
* <Story children={myTemplate} /> | ||
@@ -30,3 +29,3 @@ * ``` | ||
const { value } = children; | ||
if (value === true || value[0].type === 'Text' || value[0].expression.type !== 'Identifier') { | ||
if (value === true) { | ||
throw new InvalidStoryChildrenAttributeError({ | ||
@@ -38,2 +37,24 @@ component: component, | ||
} | ||
// value is SvelteAST.ExpressionTag | ||
if (!Array.isArray(value)) { | ||
if (value.expression.type !== 'Identifier') { | ||
throw new InvalidStoryChildrenAttributeError({ | ||
component: component, | ||
childrenAttribute: children, | ||
filename, | ||
}); | ||
} | ||
return findSnippetBlockByName({ | ||
name: value.expression.name, | ||
nodes: nodes, | ||
}); | ||
} | ||
// value is Array<SvelteAST.ExpressionTag | SvelteAST.Text> - I haven't figured out when it would happen | ||
if (value[0].type !== 'ExpressionTag') { | ||
throw new InvalidStoryChildrenAttributeError({ | ||
component: component, | ||
childrenAttribute: children, | ||
filename, | ||
}); | ||
} | ||
return findSnippetBlockByName({ | ||
@@ -40,0 +61,0 @@ name: value[0].expression.name, |
@@ -1,8 +0,8 @@ | ||
import type { Attribute, Component } from 'svelte/compiler'; | ||
import type { ComponentProps } from 'svelte'; | ||
import type { EmptyObject } from 'type-fest'; | ||
import type { Cmp, Meta, StoryCmp } from '#types'; | ||
type StoryAttributes = Array<keyof ComponentProps<StoryCmp<EmptyObject, Cmp, Meta<Cmp>>>>; | ||
import type { SvelteAST } from '#parser/ast'; | ||
import type { Cmp } from '#types'; | ||
import type Story from '#runtime/Story.svelte'; | ||
type StoryAttributes = Array<keyof ComponentProps<typeof Story<Cmp>>>; | ||
interface Options<Attributes extends StoryAttributes> { | ||
component: Component; | ||
component: SvelteAST.Component; | ||
filename?: string; | ||
@@ -12,5 +12,5 @@ attributes: Attributes; | ||
type Result<Attributes extends StoryAttributes> = Partial<{ | ||
[Key in Attributes[number]]: Attribute; | ||
[Key in Attributes[number]]: SvelteAST.Attribute; | ||
}>; | ||
export declare function extractStoryAttributesNodes<const Attributes extends StoryAttributes>(options: Options<Attributes>): Result<Attributes>; | ||
export {}; |
@@ -1,3 +0,3 @@ | ||
import type { Component, SnippetBlock } from 'svelte/compiler'; | ||
type Result = SnippetBlock | undefined; | ||
import type { SvelteAST } from '#parser/ast'; | ||
type Result = SvelteAST.SnippetBlock | undefined; | ||
/** | ||
@@ -9,3 +9,3 @@ * Extract the {@link SnippetBlock} of the individual `<Story />` if exists. | ||
*/ | ||
export declare function extractStoryChildrenSnippetBlock(component: Component): Result; | ||
export declare function extractStoryChildrenSnippetBlock(component: SvelteAST.Component): Result; | ||
export {}; |
import type { StorybookConfig } from '@storybook/svelte-vite'; | ||
import type { Options } from '@storybook/types'; | ||
export interface StorybookAddonSvelteCsFOptions extends Options { | ||
/** | ||
* Enable support for legacy templating. | ||
* This option is deprecated, it will be removed in a future major version and should only be used for gradual migration purposes. | ||
* Please migrate to the new snippet-based templating API when possible. | ||
* | ||
* Enabling this can slow down the build-performance because it requires more transformations. | ||
* | ||
* @default false | ||
* @deprecated | ||
*/ | ||
legacyTemplate?: boolean; | ||
} | ||
export declare const viteFinal: StorybookConfig['viteFinal']; | ||
export declare const experimental_indexers: StorybookConfig['experimental_indexers']; |
@@ -1,11 +0,17 @@ | ||
import { plugin } from './compiler/plugin'; | ||
import { indexer } from './indexer/index'; | ||
export const viteFinal = async (config) => { | ||
import { postTransformPlugin, preTransformPlugin } from '#compiler/plugins'; | ||
import { createIndexer } from '#indexer/index'; | ||
export const viteFinal = async (config, options) => { | ||
let { plugins = [], ...restConfig } = config; | ||
const { legacyTemplate = false } = options; | ||
if (legacyTemplate) { | ||
plugins.unshift(await preTransformPlugin()); | ||
} | ||
plugins.push(await postTransformPlugin()); | ||
return { | ||
...config, | ||
plugins: [...(config.plugins ?? []), plugin()], | ||
...restConfig, | ||
plugins, | ||
}; | ||
}; | ||
export const experimental_indexers = (indexers) => { | ||
return [indexer, ...(indexers || [])]; | ||
export const experimental_indexers = (indexers, options) => { | ||
return [createIndexer(options.legacyTemplate ?? false), ...(indexers || [])]; | ||
}; |
@@ -1,21 +0,53 @@ | ||
import type { Args } from '@storybook/types'; | ||
import { type ComponentProps } from 'svelte'; | ||
import type { Cmp, Meta, StoryCmp } from '#types'; | ||
export interface StoriesExtractorContextProps<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>> { | ||
import type Story from '../Story.svelte'; | ||
import type { Cmp } from '../../types'; | ||
export interface StoriesExtractorContextProps<TCmp extends Cmp> { | ||
isExtracting: boolean; | ||
register: (storyCmpProps: ComponentProps<StoryCmp<TOverrideArgs, TCmp, TMeta>>) => void; | ||
register: (storyCmpProps: ComponentProps<typeof Story<TCmp>>) => void; | ||
} | ||
declare function buildContext<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>>(storyCmpProps: StoriesExtractorContextProps<TOverrideArgs, TCmp, TMeta>): { | ||
declare function buildContext<TCmp extends Cmp>(storyCmpProps: StoriesExtractorContextProps<TCmp>): { | ||
readonly isExtracting: boolean; | ||
readonly register: (storyCmpProps: ComponentProps<StoryCmp<TOverrideArgs, TCmp, TMeta>>) => void; | ||
readonly register: (storyCmpProps: (Partial<import("../../types").StoryAnnotations<TCmp>> & { | ||
id?: never; | ||
name?: string; | ||
exportName?: string; | ||
autodocs?: never; | ||
source?: never; | ||
} & (({ | ||
exportName: string; | ||
} | { | ||
name: string; | ||
}) & ({ | ||
children?: import("svelte").Snippet<[]> | undefined; | ||
template?: never; | ||
} | { | ||
children?: never; | ||
template?: import("svelte").Snippet<[NonNullable<import("../../types").StoryAnnotations<TCmp>["args"]>, import("../../types").StoryContext<TCmp>]> | undefined; | ||
}))) & {}) => void; | ||
}; | ||
export type StoriesExtractorContext<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>> = ReturnType<typeof buildContext<TOverrideArgs, TCmp, TMeta>>; | ||
export type StoriesRepository<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>> = { | ||
stories: Map<string, ComponentProps<StoryCmp<TOverrideArgs, TCmp, TMeta>>>; | ||
export type StoriesExtractorContext<TCmp extends Cmp> = ReturnType<typeof buildContext<TCmp>>; | ||
export type StoriesRepository<TCmp extends Cmp> = { | ||
stories: Map<string, ComponentProps<typeof Story<TCmp>>>; | ||
}; | ||
export declare function createStoriesExtractorContext<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>>(repository: StoriesRepository<TOverrideArgs, TCmp, TMeta>): void; | ||
export declare function useStoriesExtractor<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>>(): { | ||
export declare function createStoriesExtractorContext<TCmp extends Cmp>(repository: StoriesRepository<TCmp>): void; | ||
export declare function useStoriesExtractor<TCmp extends Cmp>(): { | ||
readonly isExtracting: boolean; | ||
readonly register: (storyCmpProps: ComponentProps<StoryCmp<TOverrideArgs, TCmp, TMeta>>) => void; | ||
readonly register: (storyCmpProps: (Partial<import("../../types").StoryAnnotations<TCmp>> & { | ||
id?: never; | ||
name?: string; | ||
exportName?: string; | ||
autodocs?: never; | ||
source?: never; | ||
} & (({ | ||
exportName: string; | ||
} | { | ||
name: string; | ||
}) & ({ | ||
children?: import("svelte").Snippet<[]> | undefined; | ||
template?: never; | ||
} | { | ||
children?: never; | ||
template?: import("svelte").Snippet<[NonNullable<import("../../types").StoryAnnotations<TCmp>["args"]>, import("../../types").StoryContext<TCmp>]> | undefined; | ||
}))) & {}) => void; | ||
}; | ||
export {}; |
import { getContext, hasContext, setContext } from 'svelte'; | ||
import { storyNameToExportName } from '#utils/identifier-utils'; | ||
import { storyNameToExportName } from '../../utils/identifier-utils'; | ||
const CONTEXT_KEY = 'storybook-stories-extractor-context'; | ||
@@ -4,0 +4,0 @@ function buildContext(storyCmpProps) { |
@@ -1,21 +0,20 @@ | ||
import type { Cmp, Meta, StoryAnnotations, StoryContext } from '#types'; | ||
import type { Args } from '@storybook/types'; | ||
interface ContextProps<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>> { | ||
import type { Cmp, StoryAnnotations, StoryContext } from '../../types'; | ||
interface ContextProps<TCmp extends Cmp> { | ||
currentStoryExportName: string | undefined; | ||
args: NonNullable<StoryAnnotations<TCmp, TMeta>['args']>; | ||
storyContext: StoryContext<TCmp, TMeta>; | ||
args: NonNullable<StoryAnnotations<TCmp>['args']>; | ||
storyContext: StoryContext<TCmp>; | ||
} | ||
declare function buildContext<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>>(props: ContextProps<TOverrideArgs, TCmp, TMeta>): { | ||
readonly args: any; | ||
readonly storyContext: StoryContext<TCmp_1, TMeta_1>; | ||
declare function buildContext<TCmp extends Cmp>(props: ContextProps<TCmp>): { | ||
readonly args: NonNullable<StoryAnnotations<TCmp>["args"]>; | ||
readonly storyContext: StoryContext<TCmp>; | ||
readonly currentStoryExportName: string | undefined; | ||
set: (props: ContextProps<TOverrideArgs, TCmp, TMeta>) => void; | ||
set: (props: ContextProps<TCmp>) => void; | ||
}; | ||
export type StoryRendererContext<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>> = ReturnType<typeof buildContext<TOverrideArgs, TCmp, TMeta>>; | ||
export declare function useStoryRenderer<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>>(): { | ||
readonly args: any; | ||
readonly storyContext: StoryContext<TCmp_1, TMeta_1>; | ||
export type StoryRendererContext<TCmp extends Cmp = Cmp> = ReturnType<typeof buildContext<TCmp>>; | ||
export declare function useStoryRenderer<TCmp extends Cmp>(): { | ||
readonly args: NonNullable<StoryAnnotations<TCmp>["args"]>; | ||
readonly storyContext: StoryContext<TCmp>; | ||
readonly currentStoryExportName: string | undefined; | ||
set: (props: ContextProps<TOverrideArgs, TCmp, TMeta>) => void; | ||
set: (props: ContextProps<TCmp>) => void; | ||
}; | ||
export {}; |
@@ -28,3 +28,2 @@ import { getContext, hasContext, setContext } from 'svelte'; | ||
currentStoryExportName: undefined, | ||
// @ts-expect-error FIXME: I don't know how to satisfy this one | ||
args: {}, | ||
@@ -31,0 +30,0 @@ // @ts-expect-error FIXME: I don't know how to satisfy this one |
@@ -1,10 +0,57 @@ | ||
import type { Args } from '@storybook/types'; | ||
import type { Cmp, Meta } from '#types'; | ||
declare function buildContext<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>>(): { | ||
readonly template: any; | ||
set: (snippet?: any) => void; | ||
import type { Cmp } from '../../types'; | ||
declare function buildContext<TCmp extends Cmp>(): { | ||
readonly template: ((Partial<import("../../types").StoryAnnotations<TCmp>> & { | ||
id?: never; | ||
name?: string; | ||
exportName?: string; | ||
autodocs?: never; | ||
source?: never; | ||
} & (({ | ||
exportName: string; | ||
} | { | ||
name: string; | ||
}) & ({ | ||
children?: import("svelte").Snippet<[]> | undefined; | ||
template?: never; | ||
} | { | ||
children?: never; | ||
template?: import("svelte").Snippet<[NonNullable<import("../../types").StoryAnnotations<TCmp>["args"]>, import("../../types").StoryContext<TCmp>]> | undefined; | ||
}))) & {})["template"] | undefined; | ||
set: (snippet?: ((Partial<import("../../types").StoryAnnotations<TCmp>> & { | ||
id?: never; | ||
name?: string; | ||
exportName?: string; | ||
autodocs?: never; | ||
source?: never; | ||
} & (({ | ||
exportName: string; | ||
} | { | ||
name: string; | ||
}) & ({ | ||
children?: import("svelte").Snippet<[]> | undefined; | ||
template?: never; | ||
} | { | ||
children?: never; | ||
template?: import("svelte").Snippet<[NonNullable<import("../../types").StoryAnnotations<TCmp>["args"]>, import("../../types").StoryContext<TCmp>]> | undefined; | ||
}))) & {})["template"] | undefined) => void; | ||
}; | ||
type StoriesTemplateContext<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>> = ReturnType<typeof buildContext<TOverrideArgs, TCmp, TMeta>>; | ||
export declare function useStoriesTemplate<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>>(): any; | ||
export declare function setTemplate<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>>(snippet?: StoriesTemplateContext<TOverrideArgs, TCmp, TMeta>['template']): void; | ||
type StoriesTemplateContext<TCmp extends Cmp> = ReturnType<typeof buildContext<TCmp>>; | ||
export declare function useStoriesTemplate<TCmp extends Cmp>(): ((Partial<import("../../types").StoryAnnotations<TCmp>> & { | ||
id?: never; | ||
name?: string; | ||
exportName?: string; | ||
autodocs?: never; | ||
source?: never; | ||
} & (({ | ||
exportName: string; | ||
} | { | ||
name: string; | ||
}) & ({ | ||
children?: import("svelte").Snippet<[]> | undefined; | ||
template?: never; | ||
} | { | ||
children?: never; | ||
template?: import("svelte").Snippet<[NonNullable<import("../../types").StoryAnnotations<TCmp>["args"]>, import("../../types").StoryContext<TCmp>]> | undefined; | ||
}))) & {})["template"] | undefined; | ||
export declare function setTemplate<TCmp extends Cmp>(snippet?: StoriesTemplateContext<TCmp>['template']): void; | ||
export {}; |
import { type Component } from 'svelte'; | ||
import type { StoriesRepository } from '#runtime/contexts/extractor.svelte'; | ||
import type { Cmp, Meta } from '#types'; | ||
@@ -16,16 +15,7 @@ /** | ||
*/ | ||
export declare const createRuntimeStories: (Stories: Component, meta: Meta<Cmp>) => Record<string, import("@storybook/csf").StoryAnnotations<import("@storybook/svelte").SvelteRenderer<import("svelte").SvelteComponent<{ | ||
export declare const createRuntimeStories: (Stories: Component, meta: Meta<Cmp>) => Record<string, import("@storybook/csf").StoryAnnotations<import("@storybook/svelte").SvelteRenderer<import("svelte").SvelteComponent<Record<string, any>, any, any>>, Component<{ | ||
Stories: Component; | ||
exportName: string; | ||
args: NonNullable<StoriesRepository<StoriesRepository, StoriesRepository<StoriesRepository>>["args"]>; | ||
storyContext: StoriesRepository<StoriesRepository, StoriesRepository<StoriesRepository>>; | ||
}, { | ||
[evt: string]: CustomEvent<any>; | ||
}, {}> & { | ||
$$bindings?: "" | undefined; | ||
} & Record<string, any>>, { | ||
Stories: Component; | ||
exportName: string; | ||
args: NonNullable<StoriesRepository<StoriesRepository, StoriesRepository<StoriesRepository>>["args"]>; | ||
storyContext: StoriesRepository<StoriesRepository, StoriesRepository<StoriesRepository>>; | ||
}>>; | ||
args: NonNullable<import("../types").StoryAnnotations<import("../types").Cmp>["args"]>; | ||
storyContext: import("../types").StoryContext<import("../types").Cmp>; | ||
}, {}, "">>>; |
import type { StoryObj } from '@storybook/svelte'; | ||
import type { ComponentProps } from 'svelte'; | ||
import type { EmptyObject } from 'type-fest'; | ||
import type { Cmp, Meta, StoryCmp, StoryContext } from '#types'; | ||
import type Story from './Story.svelte'; | ||
import type { Cmp, StoryContext } from '../types'; | ||
type Params = { | ||
args: ComponentProps<StoryCmp<EmptyObject, Cmp, Meta<Cmp>>>['args']; | ||
storyContext: StoryContext<Cmp, Meta<Cmp>>; | ||
args: ComponentProps<Story<Cmp>>['args']; | ||
storyContext: StoryContext<Cmp>; | ||
}; | ||
@@ -9,0 +9,0 @@ /** |
import { SourceType, SNIPPET_RENDERED } from '@storybook/docs-tools'; | ||
import { addons } from '@storybook/preview-api'; | ||
import get from 'lodash-es/get'; | ||
import { get } from 'es-toolkit/compat'; | ||
const channel = addons.getChannel(); | ||
@@ -5,0 +5,0 @@ /** |
import type { Component } from 'svelte'; | ||
import type { EmptyObject } from 'type-fest'; | ||
import type { Cmp, Meta } from '#types'; | ||
import type { Cmp } from '#types'; | ||
import { type StoriesRepository } from '#runtime/contexts/extractor.svelte'; | ||
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> { | ||
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & { | ||
$$bindings?: Bindings; | ||
} & Exports; | ||
(internal: unknown, props: Props & { | ||
$$events?: Events; | ||
$$slots?: Slots; | ||
}): Exports; | ||
z_$$bindings?: Bindings; | ||
} | ||
declare const StoriesExtractor: $$__sveltets_2_IsomorphicComponent<{ | ||
declare const StoriesExtractor: Component<{ | ||
Stories: Component; | ||
repository: () => StoriesRepository<EmptyObject, Cmp, Meta<Cmp>>; | ||
}, { | ||
[evt: string]: CustomEvent<any>; | ||
}, {}, Record<string, any>, "">; | ||
type StoriesExtractor = InstanceType<typeof StoriesExtractor>; | ||
repository: () => StoriesRepository<Cmp>; | ||
}, {}, "">; | ||
export default StoriesExtractor; |
@@ -1,8 +0,75 @@ | ||
import type { Args } from '@storybook/types'; | ||
import type { Cmp, Meta } from '#types'; | ||
declare class __sveltets_Render<const TOverrideArgs extends Args, const TCmp extends Cmp, TMeta extends Meta<TCmp>> { | ||
props(): any; | ||
events(): {} & { | ||
[evt: string]: CustomEvent<any>; | ||
}; | ||
type TemplateSnippet<T extends Cmp> = Snippet<[ | ||
StoryRendererContext<T>['args'], | ||
StoryRendererContext<T>['storyContext'] | ||
]>; | ||
import type { Snippet } from 'svelte'; | ||
import { type StoryRendererContext } from './contexts/renderer.svelte'; | ||
import type { Cmp, StoryAnnotations } from '../types'; | ||
declare class __sveltets_Render<const TCmp extends Cmp, TChildren extends Snippet = Snippet, TTemplate extends TemplateSnippet<TCmp> = TemplateSnippet<TCmp>> { | ||
props(): Partial<StoryAnnotations<TCmp>> & { | ||
/** | ||
* @deprecated | ||
* Use `exportName` instead. | ||
*/ | ||
id?: never; | ||
/** | ||
* Name of the story. Can be omitted if `exportName` is provided. | ||
*/ | ||
name?: string; | ||
/** | ||
* exportName of the story. | ||
* If not provided, it will be generated from the 'name', by converting it to a valid, PascalCased JS variable name. | ||
* eg. 'My story!' -> 'MyStory' | ||
* | ||
* Use this prop to explicitly set the export name of the story. This is useful if you have multiple stories with the names | ||
* that result in duplicate export names like "My story" and "My story!". | ||
* It's also useful for explicitly defining the export that can be imported in MDX docs. | ||
*/ | ||
exportName?: string; | ||
/** | ||
* @deprecrated | ||
* Use `tags={['autodocs']}` instead. | ||
* @see {@link https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#story-prop-autodocs-has-been-removed} | ||
*/ | ||
autodocs?: never; | ||
/** | ||
* @deprecated | ||
* Use `parameters={{ docs: { source: { code: "..." } } }}` instead. | ||
* @see {@link https://github.com/storybookjs/addon-svelte-csf/blob/next/MIGRATION.md#story-prop-source-has-been-removed} | ||
*/ | ||
source?: never; | ||
} & (({ | ||
/** | ||
* exportName of the story. | ||
* If not provided, it will be generated from the 'name', by converting it to a valid, PascalCased JS variable name. | ||
* eg. 'My story!' -> 'MyStory' | ||
* | ||
* Use this prop to explicitly set the export name of the story. This is useful if you have multiple stories with the names | ||
* that result in duplicate export names like "My story" and "My story!". | ||
* It's also useful for explicitly defining the export that can be imported in MDX docs. | ||
*/ | ||
exportName: string; | ||
} | { | ||
/** | ||
* Name of the story. Can be omitted if `exportName` is provided. | ||
*/ | ||
name: string; | ||
}) & ({ | ||
/** | ||
* The content to render in the story as **static** markup. | ||
* | ||
* NOTE: Can be omitted if a default template is set with [`setTemplate()`](https://github.com/storybookjs/addon-svelte-csf/blob/main/README.md#default-snippet) | ||
*/ | ||
children?: TChildren | undefined; | ||
template?: never; | ||
} | { | ||
children?: never; | ||
/** | ||
* The content to render in the story with a snippet taking `args` and `storyContext` as parameters | ||
* | ||
* NOTE: Can be omitted if a default template is set with [`setTemplate()`](https://github.com/storybookjs/addon-svelte-csf/blob/main/README.md#default-snippet) | ||
*/ | ||
template?: TTemplate | undefined; | ||
})); | ||
events(): {}; | ||
slots(): {}; | ||
@@ -13,12 +80,10 @@ bindings(): ""; | ||
interface $$IsomorphicComponent { | ||
new <const TOverrideArgs extends Args, const TCmp extends Cmp, TMeta extends Meta<TCmp>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TOverrideArgs, TCmp, TMeta>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TOverrideArgs, TCmp, TMeta>['props']>, ReturnType<__sveltets_Render<TOverrideArgs, TCmp, TMeta>['events']>, ReturnType<__sveltets_Render<TOverrideArgs, TCmp, TMeta>['slots']>> & { | ||
$$bindings?: ReturnType<__sveltets_Render<TOverrideArgs, TCmp, TMeta>['bindings']>; | ||
} & ReturnType<__sveltets_Render<TOverrideArgs, TCmp, TMeta>['exports']>; | ||
<const TOverrideArgs extends Args, const TCmp extends Cmp, TMeta extends Meta<TCmp>>(internal: unknown, props: ReturnType<__sveltets_Render<TOverrideArgs, TCmp, TMeta>['props']> & { | ||
$$events?: ReturnType<__sveltets_Render<TOverrideArgs, TCmp, TMeta>['events']>; | ||
}): ReturnType<__sveltets_Render<TOverrideArgs, TCmp, TMeta>['exports']>; | ||
new <const TCmp extends Cmp, TChildren extends Snippet = Snippet, TTemplate extends TemplateSnippet<TCmp> = TemplateSnippet<TCmp>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TCmp, TChildren, TTemplate>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TCmp, TChildren, TTemplate>['props']>, ReturnType<__sveltets_Render<TCmp, TChildren, TTemplate>['events']>, ReturnType<__sveltets_Render<TCmp, TChildren, TTemplate>['slots']>> & { | ||
$$bindings?: ReturnType<__sveltets_Render<TCmp, TChildren, TTemplate>['bindings']>; | ||
} & ReturnType<__sveltets_Render<TCmp, TChildren, TTemplate>['exports']>; | ||
<const TCmp extends Cmp, TChildren extends Snippet = Snippet, TTemplate extends TemplateSnippet<TCmp> = TemplateSnippet<TCmp>>(internal: unknown, props: ReturnType<__sveltets_Render<TCmp, TChildren, TTemplate>['props']> & {}): ReturnType<__sveltets_Render<TCmp, TChildren, TTemplate>['exports']>; | ||
z_$$bindings?: ReturnType<__sveltets_Render<any, any, any>['bindings']>; | ||
} | ||
declare const Story: $$IsomorphicComponent; | ||
type Story<const TOverrideArgs extends Args, const TCmp extends Cmp, TMeta extends Meta<TCmp>> = InstanceType<typeof Story<TOverrideArgs, TCmp, TMeta>>; | ||
type Story<const TCmp extends Cmp, TChildren extends Snippet = Snippet, TTemplate extends TemplateSnippet<TCmp> = TemplateSnippet<TCmp>> = InstanceType<typeof Story<TCmp, TChildren, TTemplate>>; | ||
export default Story; |
import type { Component } from 'svelte'; | ||
import type { Cmp, Meta, StoryAnnotations, StoryContext } from '#types'; | ||
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> { | ||
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & { | ||
$$bindings?: Bindings; | ||
} & Exports; | ||
(internal: unknown, props: Props & { | ||
$$events?: Events; | ||
$$slots?: Slots; | ||
}): Exports; | ||
z_$$bindings?: Bindings; | ||
} | ||
declare const StoryRenderer: $$__sveltets_2_IsomorphicComponent<{ | ||
import type { Cmp, StoryAnnotations, StoryContext } from '../types'; | ||
declare const StoryRenderer: Component<{ | ||
Stories: Component; | ||
exportName: string; | ||
args: NonNullable<StoryAnnotations<Cmp, Meta<Cmp>>["args"]>; | ||
storyContext: StoryContext<Cmp, Meta<Cmp>>; | ||
}, { | ||
[evt: string]: CustomEvent<any>; | ||
}, {}, Record<string, any>, "">; | ||
type StoryRenderer = InstanceType<typeof StoryRenderer>; | ||
args: NonNullable<StoryAnnotations<Cmp>["args"]>; | ||
storyContext: StoryContext<Cmp>; | ||
}, {}, "">; | ||
export default StoryRenderer; |
@@ -1,7 +0,5 @@ | ||
import type { Args, ComponentAnnotations as BaseComponentAnnotations, StoryAnnotations as BaseStoryAnnotations, StoryContext as BaseStoryContext, WebRenderer } from '@storybook/types'; | ||
import type { Component, ComponentProps, Snippet } from 'svelte'; | ||
import type { Primitive, SetOptional, Simplify } from 'type-fest'; | ||
import type Story from './runtime/Story.svelte'; | ||
import type { ComponentAnnotations as BaseComponentAnnotations, StoryAnnotations as BaseStoryAnnotations, StoryContext as BaseStoryContext, WebRenderer } from '@storybook/types'; | ||
import type { Component, ComponentProps } from 'svelte'; | ||
import type { Simplify } from 'type-fest'; | ||
export type Cmp = Component<any>; | ||
export type CmpOrArgs = Cmp | Args; | ||
/** | ||
@@ -13,19 +11,13 @@ * Metadata to configure the stories for a component. | ||
export type Meta<TCmp extends Cmp> = ComponentAnnotations<TCmp>; | ||
export type ComponentAnnotations<TCmpOrArgs extends CmpOrArgs> = BaseComponentAnnotations<SvelteRenderer<TCmpOrArgs>, InferArgs<TCmpOrArgs>>; | ||
export interface SvelteRenderer<TCmpOrArgs extends CmpOrArgs> extends WebRenderer { | ||
component: TCmpOrArgs extends Cmp ? TCmpOrArgs : Component<TCmpOrArgs>; | ||
storyResult: SvelteStoryResult<TCmpOrArgs>; | ||
export type ComponentAnnotations<TCmp extends Cmp> = BaseComponentAnnotations<SvelteRenderer<TCmp>, ComponentProps<TCmp>>; | ||
export interface SvelteRenderer<TCmp extends Cmp> extends WebRenderer { | ||
component: TCmp; | ||
storyResult: SvelteStoryResult<TCmp>; | ||
} | ||
export interface SvelteStoryResult<TCmpOrArgs extends CmpOrArgs> { | ||
Component?: TCmpOrArgs extends Cmp ? TCmpOrArgs : Component<TCmpOrArgs>; | ||
props?: TCmpOrArgs extends Cmp ? ComponentProps<TCmpOrArgs> : TCmpOrArgs; | ||
decorator?: TCmpOrArgs extends Cmp ? TCmpOrArgs : Component<TCmpOrArgs>; | ||
export interface SvelteStoryResult<TCmp extends Cmp> { | ||
Component?: TCmp; | ||
props?: ComponentProps<TCmp>; | ||
decorator?: TCmp; | ||
} | ||
export type MapSnippetsToAcceptPrimitives<Props extends Args> = { | ||
[ArgKey in keyof Props]: Props[ArgKey] extends Snippet ? Snippet | Primitive : Props[ArgKey]; | ||
}; | ||
type InferArgs<TCmpOrArgs extends CmpOrArgs> = MapSnippetsToAcceptPrimitives<TCmpOrArgs extends Cmp ? ComponentProps<TCmpOrArgs> : TCmpOrArgs>; | ||
export type StoryContext<TCmp extends Cmp, TMeta extends Meta<TCmp>> = BaseStoryContext<SvelteRenderer<TCmp>, Simplify<TCmp extends Cmp ? ComponentProps<TCmp> : TCmp>>; | ||
export type StoryCmp<TOverrideArgs extends Args, TCmp extends Cmp, TMeta extends Meta<TCmp>> = typeof Story<TOverrideArgs, TCmp, TMeta>; | ||
export type StoryAnnotations<TCmp extends Cmp, TMeta extends Meta<TCmp>> = BaseStoryAnnotations<SvelteRenderer<TCmp>, InferArgs<TCmp>, Simplify<SetOptional<InferArgs<TCmp>, keyof InferArgs<TCmp>>>>; | ||
export {}; | ||
export type StoryContext<TCmp extends Cmp> = BaseStoryContext<SvelteRenderer<TCmp>, Simplify<TCmp>>; | ||
export type StoryAnnotations<TCmp extends Cmp> = BaseStoryAnnotations<SvelteRenderer<TCmp>, ComponentProps<TCmp>, Partial<ComponentProps<TCmp>>>; |
import url from 'node:url'; | ||
import type { Component } from 'svelte/compiler'; | ||
import type { SvelteAST } from '#parser/ast'; | ||
/** | ||
@@ -17,2 +17,3 @@ * Adopted from: {@link https://github.com/storybookjs/storybook/blob/next/code/lib/core-events/src/errors/storybook-error.ts} | ||
readonly compiler: "COMPILER"; | ||
readonly legacyAPI: "LEGACY_API"; | ||
}; | ||
@@ -47,2 +48,7 @@ /** | ||
readonly fromStorybook: true; | ||
/** | ||
* Any custom message to override the default error message. | ||
* Vite overrides the `Error.message` property, so we support that. | ||
*/ | ||
private customMessage?; | ||
get fullErrorCode(): `SB_SVELTE_CSF_${this["category"]}_${string}`; | ||
@@ -58,2 +64,7 @@ /** | ||
/** | ||
* Allows anyone to set Error.message after creation, mimicking the native Error behavior. | ||
* Vite does this sometimes. | ||
*/ | ||
set message(message: string); | ||
/** | ||
* `*.stories.svelte` file path where the error has occurred. | ||
@@ -65,3 +76,3 @@ */ | ||
*/ | ||
readonly component?: Component; | ||
readonly component?: SvelteAST.Component; | ||
constructor({ filename, component: component, }: { | ||
@@ -71,5 +82,5 @@ filename?: StorybookSvelteCSFError['filename']; | ||
}); | ||
protected get storyNameFromAttribute(): string; | ||
protected get storyNameFromAttribute(): any; | ||
get filepathURL(): url.URL | "<path not specified>"; | ||
get quickStoryRawCodeIdentifier(): string; | ||
} |
@@ -17,2 +17,3 @@ import url from 'node:url'; | ||
compiler: 'COMPILER', | ||
legacyAPI: 'LEGACY_API', | ||
}; | ||
@@ -34,2 +35,7 @@ /** | ||
fromStorybook = true; | ||
/** | ||
* Any custom message to override the default error message. | ||
* Vite overrides the `Error.message` property, so we support that. | ||
*/ | ||
customMessage; | ||
get fullErrorCode() { | ||
@@ -50,2 +56,5 @@ const paddedCode = String(this.code).padStart(4, '0'); | ||
get message() { | ||
if (this.customMessage) { | ||
return this.customMessage; | ||
} | ||
let page; | ||
@@ -64,2 +73,9 @@ if (this.documentation === true) { | ||
/** | ||
* Allows anyone to set Error.message after creation, mimicking the native Error behavior. | ||
* Vite does this sometimes. | ||
*/ | ||
set message(message) { | ||
this.customMessage = message; | ||
} | ||
/** | ||
* `*.stories.svelte` file path where the error has occurred. | ||
@@ -80,19 +96,27 @@ */ | ||
get storyNameFromAttribute() { | ||
if (this.component) { | ||
for (const attribute of this.component?.attributes) { | ||
if (attribute.type === 'Attribute' && | ||
attribute.name === 'name' && | ||
attribute.value !== true) { | ||
if (attribute.value[0].type === 'Text') { | ||
return attribute.value[0].data; | ||
} | ||
if (attribute.value[0].type === 'ExpressionTag' && | ||
attribute.value[0].expression.type === 'Literal' && | ||
typeof attribute.value[0].expression.value === 'string') { | ||
return attribute.value[0].expression.value; | ||
} | ||
} | ||
if (!this.component) { | ||
return '<UnnamedComponent>'; | ||
} | ||
const { attributes } = this.component; | ||
for (const attribute of attributes) { | ||
if (attribute.type !== 'Attribute') { | ||
// NOTE: Nothing to do with this case - invalid tbh | ||
continue; | ||
} | ||
if (attribute.value === true) { | ||
// NOTE: Nothing to do with this case - invalid tbh | ||
continue; | ||
} | ||
// value is SvelteAST.ExpressionTag | ||
if (!Array.isArray(attribute.value)) { | ||
return attribute.value.expression.value; | ||
} | ||
if (attribute.value[0].type === 'Text') { | ||
return attribute.value[0].data; | ||
} | ||
if (attribute.value[0].expression.type === 'Literal' && | ||
typeof attribute.value[0].expression.value === 'string') { | ||
return attribute.value[0].expression.value; | ||
} | ||
} | ||
return '<unspecified Story name>'; | ||
} | ||
@@ -99,0 +123,0 @@ get filepathURL() { |
import { StorybookSvelteCSFError } from '#utils/error'; | ||
import type { ArrayExpression, Property, VariableDeclarator } from 'estree'; | ||
import type * as ESTreeAST from 'estree'; | ||
export declare class InvalidComponentValueError extends StorybookSvelteCSFError { | ||
@@ -7,3 +7,3 @@ readonly category: any; | ||
documentation: boolean; | ||
componentProperty: Property; | ||
componentProperty: ESTreeAST.Property; | ||
constructor({ filename, componentProperty, }: { | ||
@@ -19,3 +19,3 @@ filename: StorybookSvelteCSFError['filename']; | ||
documentation: boolean; | ||
defineMetaVariableDeclarator: VariableDeclarator; | ||
defineMetaVariableDeclarator: ESTreeAST.VariableDeclarator; | ||
constructor({ filename, defineMetaVariableDeclarator, }: { | ||
@@ -38,3 +38,3 @@ filename: StorybookSvelteCSFError['filename']; | ||
documentation: boolean; | ||
readonly property: Property; | ||
readonly property: ESTreeAST.Property; | ||
constructor({ filename, property, }: { | ||
@@ -50,3 +50,3 @@ filename: StorybookSvelteCSFError['filename']; | ||
documentation: boolean; | ||
readonly property: Property; | ||
readonly property: ESTreeAST.Property; | ||
constructor({ filename, property, }: { | ||
@@ -62,4 +62,4 @@ filename: StorybookSvelteCSFError['filename']; | ||
documentation: boolean; | ||
readonly property: Property; | ||
readonly element: ArrayExpression['elements'][number]; | ||
readonly property: ESTreeAST.Property; | ||
readonly element: ESTreeAST.ArrayExpression['elements'][number]; | ||
constructor({ filename, property, element, }: { | ||
@@ -66,0 +66,0 @@ filename: StorybookSvelteCSFError['filename']; |
@@ -1,5 +0,4 @@ | ||
import type { Attribute } from 'svelte/compiler'; | ||
import type { getStoryIdentifiers } from '#parser/analyse/story/attributes/identifiers'; | ||
import type { ESTreeAST, SvelteAST } from '#parser/ast'; | ||
import { StorybookSvelteCSFError } from '#utils/error'; | ||
import type { ArrayExpression } from 'estree'; | ||
import type { getStoryIdentifiers } from '#parser/analyse/story/attributes/identifiers'; | ||
export declare class AttributeNotStringError extends StorybookSvelteCSFError { | ||
@@ -9,3 +8,3 @@ readonly category: any; | ||
documentation: boolean; | ||
attribute: Attribute; | ||
attribute: SvelteAST.Attribute; | ||
constructor({ filename, attribute, component, }: { | ||
@@ -22,3 +21,3 @@ filename: StorybookSvelteCSFError['filename']; | ||
documentation: boolean; | ||
attribute: Attribute; | ||
attribute: SvelteAST.Attribute; | ||
constructor({ filename, attribute, component, }: { | ||
@@ -29,3 +28,3 @@ filename: StorybookSvelteCSFError['filename']; | ||
}); | ||
get valueType(): string | number | bigint | boolean | RegExp | null | undefined; | ||
get valueType(): any; | ||
template(): string; | ||
@@ -37,4 +36,4 @@ } | ||
documentation: boolean; | ||
attribute: Attribute; | ||
element: ArrayExpression['elements'][number]; | ||
attribute: SvelteAST.Attribute; | ||
element: ESTreeAST.ArrayExpression['elements'][number]; | ||
constructor({ filename, attribute, component, element, }: { | ||
@@ -46,3 +45,3 @@ filename: StorybookSvelteCSFError['filename']; | ||
}); | ||
get valueType(): string | number | bigint | boolean | RegExp | null | undefined; | ||
get valueType(): any; | ||
template(): string; | ||
@@ -49,0 +48,0 @@ } |
@@ -30,6 +30,11 @@ import dedent from 'dedent'; | ||
get valueType() { | ||
const { value } = this.attribute; | ||
const { attribute } = this; | ||
const { value } = attribute; | ||
if (value === true) { | ||
return true; | ||
} | ||
// value is SvelteAST.ExpressionTag | ||
if (!Array.isArray(value)) { | ||
return value.expression.value; | ||
} | ||
if (value[0].type === 'Text') { | ||
@@ -61,6 +66,10 @@ return value[0].data; | ||
get valueType() { | ||
const { value } = this.attribute; | ||
const { attribute } = this; | ||
const { value } = attribute; | ||
if (value === true) { | ||
return true; | ||
} | ||
if (!Array.isArray(value)) { | ||
return value.expression.value; | ||
} | ||
if (value[0].type === 'Text') { | ||
@@ -67,0 +76,0 @@ return value[0].data; |
@@ -1,2 +0,2 @@ | ||
import type { Attribute } from 'svelte/compiler'; | ||
import type { SvelteAST } from '#parser/ast'; | ||
import type { SvelteASTNodes } from '#parser/extract/svelte/nodes'; | ||
@@ -58,3 +58,3 @@ import { StorybookSvelteCSFError } from '#utils/error'; | ||
documentation: boolean; | ||
childrenAttribute: Attribute; | ||
childrenAttribute: SvelteAST.Attribute; | ||
constructor({ filename, component, childrenAttribute, }: { | ||
@@ -78,1 +78,8 @@ filename?: StorybookSvelteCSFError['filename']; | ||
} | ||
export declare class IndexerParseError extends StorybookSvelteCSFError { | ||
readonly category: any; | ||
readonly code = 9; | ||
documentation: boolean; | ||
constructor(); | ||
template(): string; | ||
} |
import dedent from 'dedent'; | ||
import { StorybookSvelteCSFError } from '#utils/error'; | ||
const BASE_INITIAL_SNIPPET = dedent ` | ||
<script context="module"> | ||
<script module> | ||
import { defineMeta } from "@storybook/addon-svelte-csf"; | ||
@@ -20,3 +20,3 @@ | ||
The file '${this.filepathURL}' | ||
does not have a module context (<script context="module"> ... </script>). | ||
does not have a module context (<script module> ... </script>). | ||
@@ -158,1 +158,15 @@ defineMeta(...) should be called inside a module script tag, like so: | ||
} | ||
export class IndexerParseError extends StorybookSvelteCSFError { | ||
category = StorybookSvelteCSFError.CATEGORY.parserExtractSvelte; | ||
code = 9; | ||
documentation = true; | ||
constructor() { | ||
super({}); | ||
} | ||
template() { | ||
return dedent ` | ||
Storybook stories indexer parser threw an unrecognized error. | ||
If you see this error, please report it on the issue tracker on GitHub. | ||
`; | ||
} | ||
} |
{ | ||
"name": "@storybook/addon-svelte-csf", | ||
"version": "5.0.0--canary.190.0ab0039.0", | ||
"version": "5.0.0--canary.228.5081d3b.0", | ||
"description": "Allows to write stories in Svelte syntax", | ||
@@ -17,2 +17,5 @@ "keywords": [ | ||
"imports": { | ||
"#tests/*": { | ||
"development": "./tests/*.ts" | ||
}, | ||
"#*": { | ||
@@ -66,5 +69,6 @@ "development": "./src/*.ts", | ||
"dedent": "^1.5.3", | ||
"es-toolkit": "^1.26.1", | ||
"esrap": "^1.2.2", | ||
"lodash-es": "^4.17.21", | ||
"magic-string": "^0.30.10", | ||
"magic-string": "^0.30.12", | ||
"svelte-ast-print": "^0.4.0", | ||
"zimmerframe": "^1.1.2" | ||
@@ -74,23 +78,23 @@ }, | ||
"@auto-it/released": "^11.1.6", | ||
"@storybook/addon-actions": "^8.2.2", | ||
"@storybook/addon-essentials": "^8.2.2", | ||
"@storybook/addon-interactions": "^8.2.2", | ||
"@storybook/client-logger": "^8.2.2", | ||
"@storybook/addon-actions": "^8.0.0", | ||
"@storybook/addon-essentials": "^8.0.0", | ||
"@storybook/addon-interactions": "^8.0.0", | ||
"@storybook/client-logger": "^8.0.0", | ||
"@storybook/eslint-config-storybook": "^4.0.0", | ||
"@storybook/preview-api": "^8.2.2", | ||
"@storybook/svelte": "^8.2.2", | ||
"@storybook/svelte-vite": "^8.2.2", | ||
"@storybook/test": "^8.2.2", | ||
"@sveltejs/package": "^2.3.2", | ||
"@sveltejs/vite-plugin-svelte": "4.0.0-next.3", | ||
"@storybook/preview-api": "^8.0.0", | ||
"@storybook/svelte": "^8.0.0", | ||
"@storybook/svelte-vite": "^8.0.0", | ||
"@storybook/test": "^8.0.0", | ||
"@sveltejs/package": "^2.3.7", | ||
"@sveltejs/vite-plugin-svelte": "4.0.0", | ||
"@tsconfig/svelte": "^5.0.4", | ||
"@types/estree": "^1.0.5", | ||
"@types/estree": "^1.0.6", | ||
"@types/node": "^20.14.9", | ||
"@vitest/ui": "^1.6.0", | ||
"auto": "^11.1.6", | ||
"chromatic": "^11.5.4", | ||
"chromatic": "^11.16.1", | ||
"concurrently": "^8.2.2", | ||
"eslint": "^7.32.0", | ||
"eslint-plugin-storybook": "^0.8.0", | ||
"jsdom": "^24.1.0", | ||
"eslint-plugin-storybook": "^0.11.0", | ||
"happy-dom": "^15.11.0", | ||
"prettier": "^3.3.2", | ||
@@ -100,9 +104,9 @@ "prettier-plugin-svelte": "^3.2.5", | ||
"rollup": "^4.18.0", | ||
"storybook": "^8.2.2", | ||
"svelte": "5.0.0-next.155", | ||
"svelte-check": "^3.8.4", | ||
"storybook": "^8.0.0", | ||
"svelte": "^5.0.0", | ||
"svelte-check": "^4.0.5", | ||
"tslib": "^2.6.3", | ||
"type-fest": "^4.20.1", | ||
"typescript": "^5.5.2", | ||
"typescript-svelte-plugin": "^0.3.39", | ||
"typescript-svelte-plugin": "^0.3.42", | ||
"vite": "^5.3.2", | ||
@@ -115,7 +119,7 @@ "vite-plugin-inspect": "^0.8.4", | ||
"@storybook/svelte": "^8.0.0", | ||
"@sveltejs/vite-plugin-svelte": "^4.0.0-next.0 || ^4.0.0", | ||
"svelte": "^5.0.0-next.117 || ^5.0.0", | ||
"@sveltejs/vite-plugin-svelte": "^4.0.0", | ||
"svelte": "^5.0.0", | ||
"vite": "^5.0.0" | ||
}, | ||
"packageManager": "pnpm@9.1.3+sha512.7c2ea089e1a6af306409c4fc8c4f0897bdac32b772016196c469d9428f1fe2d5a21daf8ad6512762654ac645b5d9136bb210ec9a00afa8dbc4677843ba362ecd", | ||
"packageManager": "pnpm@9.12.3+sha512.cce0f9de9c5a7c95bef944169cc5dfe8741abfb145078c0d508b868056848a87c81e626246cb60967cbd7fd29a6c062ef73ff840d96b3c86c40ac92cf4a813ee", | ||
"publishConfig": { | ||
@@ -122,0 +126,0 @@ "access": "public" |
@@ -61,3 +61,3 @@ # Svelte CSF | ||
```svelte | ||
<script context="module"> | ||
<script module> | ||
// 👆 notice the module context, defineMeta does not work in a regular <script> tag - instance | ||
@@ -168,3 +168,3 @@ import { defineMeta } from '@storybook/addon-svelte-csf'; | ||
```svelte | ||
<script context="module"> | ||
<script module> | ||
import { defineMeta, setTemplate } from '@storybook/addon-svelte-csf'; | ||
@@ -238,3 +238,3 @@ // 👆 import the function | ||
```svelte | ||
<script context="module" lang="ts"> | ||
<script module lang="ts"> | ||
import { defineMeta, type Args, type StoryContext } from '@storybook/addon-svelte-csf'; | ||
@@ -263,2 +263,27 @@ // 👆 👆 import those type helpers from this addon --> | ||
### Legacy API | ||
Version 5 of the addon changes the API from v4 in key areas, as described above. However a feature flag has been introduced to maintain support for the `<Template>`-based legacy API as it was prior to v5. | ||
To enable supoprt for the legacy API, make the following change to your main Storybook config: | ||
```diff | ||
export default { | ||
addons: [ | ||
- '@storybook/addon-svelte-csf', | ||
+ { | ||
+ name: '@storybook/addon-svelte-csf', | ||
+ options: { | ||
+ legacyTemplate: true | ||
+ }, | ||
... | ||
], | ||
... | ||
} | ||
``` | ||
This can make the overall experience slower, because it adds more transformation steps on top of the existing ones. It should only be used temporarily while migrating to the new API. It's highly likely that the legacy support will be dropped in future major versions of the addon. | ||
The legacy support is not bullet-proof, and it might not work in all scenarios that previously worked. If you're experiencing issues or getting errors after upgrading to v5, try migrating the problematic stories files to the modern API. | ||
## Version compatibility | ||
@@ -265,0 +290,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
241640
135
5698
340
10
14
+ Addedes-toolkit@^1.26.1
+ Addedsvelte-ast-print@^0.4.0
+ Addedes-toolkit@1.27.0(transitive)
+ Addedsvelte-ast-print@0.4.2(transitive)
- Removedlodash-es@^4.17.21
- Removedlodash-es@4.17.21(transitive)
Updatedmagic-string@^0.30.12