Socket
Socket
Sign inDemoInstall

@storybook/addon-svelte-csf

Package Overview
Dependencies
438
Maintainers
11
Versions
195
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 5.0.0--canary.181.030a862.0 to 5.0.0--canary.181.0a3e376.0

dist/compiler/transform/appendix/create-export-default.d.ts

12

dist/compiler/plugin.js

@@ -13,3 +13,4 @@ /**

import { preprocess } from 'svelte/compiler';
import { createAppendix } from './transform/compiled/create-appendix.js';
import { createAppendix } from './transform/create-appendix.js';
import { removeExportDefault } from './transform/remove-export-default.js';
import { insertDefineMetaJSDocCommentAsDescription } from './transform/define-meta/description.js';

@@ -70,4 +71,4 @@ import { destructureMetaFromDefineMeta } from './transform/define-meta/destructure-meta.js';

// Hence the reason why reversing both arrays with stories _(svelte and compiled)_.
const svelteStories = svelteNodes.storyComponents.toReversed();
const compiledStories = extractedCompiledStoriesNodes.toReversed();
const svelteStories = [...svelteNodes.storyComponents].reverse();
const compiledStories = [...extractedCompiledStoriesNodes].reverse();
for (const [index, compiled] of Object.entries(compiledStories)) {

@@ -93,2 +94,7 @@ insertStoryHTMLCommentAsDescription({

});
removeExportDefault({
code,
nodes: compiledNodes,
filename,
});
await createAppendix({

@@ -95,0 +101,0 @@ componentName,

import type MagicString from 'magic-string';
import type { SvelteASTNodes } from '../../../utils/parser/extract/svelte/nodes.js';
import type { CompiledASTNodes } from '../../../utils/parser/extract/compiled/nodes.js';
import type { SvelteASTNodes } from '../../../parser/extract/svelte/nodes.js';
import type { CompiledASTNodes } from '../../../parser/extract/compiled/nodes.js';
interface Params {

@@ -5,0 +5,0 @@ code: MagicString;

import type MagicString from 'magic-string';
import type { CompiledASTNodes } from '../../../utils/parser/extract/compiled/nodes.js';
import type { CompiledASTNodes } from '../../../parser/extract/compiled/nodes.js';
interface Params {

@@ -4,0 +4,0 @@ code: MagicString;

@@ -7,5 +7,2 @@ import { logger } from '@storybook/client-logger';

const { svelte, compiled } = nodes;
if (!svelte) {
throw new Error('svelte was undefined!' + filename);
}
const { component, comment } = svelte;

@@ -12,0 +9,0 @@ if (!comment) {

@@ -7,5 +7,7 @@ import fs from 'node:fs/promises';

import { extractMetaPropertiesNodes } from '../parser/extract/meta-properties.js';
import { getMetaIdValue, getMetaTagsValue, getMetaTitleValue, } from '../parser/analyse/meta-properties.js';
import { extractStoryAttributesNodes } from '../parser/extract/svelte/Story-attributes.js';
import { getNameFromStoryAttribute, getTagsFromStoryAttribute, } from '../parser/analyse/Story-attributes.js';
import { extractStoryAttributesNodes } from '../parser/extract/svelte/Story/attributes.js';
import { getMetaIdValue, getMetaTagsValue, getMetaTitleValue, } from '../parser/analyse/meta/properties.js';
import { getNameFromStoryAttribute } from '../parser/analyse/Story/attributes/name.js';
import { getTagsFromStoryAttribute } from '../parser/analyse/Story/attributes/tags.js';
import { storyNameToExportName } from '../utils/identifiers.js';
export const indexer = {

@@ -26,16 +28,12 @@ test: /\.svelte$/,

const nodes = await extractSvelteASTNodes({ ast: svelteAST, filename });
const [metaPropertiesNodes, storiesAttributesNodes] = await Promise.all([
extractMetaPropertiesNodes({
nodes,
filename,
properties: ['id', 'title', 'tags'],
}),
Promise.all(nodes.storyComponents.map(({ component }) => {
return extractStoryAttributesNodes({
component: component,
filename,
attributes: ['name', 'tags'],
});
})),
]);
const metaPropertiesNodes = extractMetaPropertiesNodes({
nodes,
filename,
properties: ['id', 'title', 'tags'],
});
const storiesAttributesNodes = nodes.storyComponents.map(({ component }) => extractStoryAttributesNodes({
component,
filename,
attributes: ['name', 'tags'],
}));
const metaTitle = metaPropertiesNodes.title

@@ -51,3 +49,3 @@ ? makeTitle(getMetaTitleValue({ node: metaPropertiesNodes.title, filename }))

return storiesAttributesNodes.map((attributeNode) => {
const exportName = getNameFromStoryAttribute({
const name = getNameFromStoryAttribute({
node: attributeNode.name,

@@ -59,8 +57,6 @@ filename,

importPath: filename,
exportName,
// TODO: Ask if this is important to set. If yes, then from what? Story attribute? That's `exportName`.
// name: ...
exportName: storyNameToExportName(name),
name,
title: metaTitle,
tags: combineTags(...metaTags, ...getTagsFromStoryAttribute({ node: attributeNode.tags, filename })),
__id: metaId,
};

@@ -67,0 +63,0 @@ });

@@ -1,2 +0,2 @@

import type { FunctionDeclaration, Identifier, ImportSpecifier, Program, VariableDeclaration } from 'estree';
import type { ExportDefaultDeclaration, FunctionDeclaration, Identifier, ImportSpecifier, Program, VariableDeclaration } from 'estree';
export interface CompiledASTNodes {

@@ -14,2 +14,7 @@ /**

/**
* Store the `export default declaration`, we will need to remove it later.
* Why? Storybook expects `export default meta`, instead of what `@sveltejs/vite-plugin-svelte` will produce.
*/
exportDefault: ExportDefaultDeclaration;
/**
* An identifier for the addon's component `<Story />`.

@@ -20,3 +25,3 @@ * It could be destructured with rename - e.g. `const { Story: S } = defineMeta({ ... })`

/**
*
* A function declaration for the main Svelte component which is the `*.stories.svelte` file.
*/

@@ -23,0 +28,0 @@ storiesFunctionDeclaration: FunctionDeclaration;

@@ -51,20 +51,18 @@ import pkg from '@storybook/addon-svelte-csf/package.json' with { type: 'json' };

ExportDefaultDeclaration(node, { state }) {
// NOTE: This may be confusing.
// In the dev mode the export default is different (Identifier to FunctionDeclaration)
if (process.env['NODE_ENV'] !== 'development') {
if (node.declaration.type !== 'FunctionDeclaration') {
throw new Error(`Expected FunctionDeclaration as the default export in the compiled code for stories file: ${filename}`);
}
state.exportDefault = node;
// WARN: This may be confusing.
// In the `NODE_ENV="production"` the export default is different.
// Identifier to a FunctionDeclaration.
if (process.env.NODE_ENV === 'production' &&
node.declaration.type === 'FunctionDeclaration' &&
isStoriesComponentFn(node.declaration)) {
state.storiesFunctionDeclaration = node.declaration;
}
},
FunctionDeclaration(node, { state, stop }) {
if (process.env['NODE_ENV'] === 'development') {
if (node.id.name.endsWith('stories')) {
// NOTE:
// Is an `export default function <Component>_stories` - we want this one.
// We will remove the `export default` later
state.storiesFunctionDeclaration = node;
stop();
}
FunctionDeclaration(node, { state }) {
// WARN: This may be confusing.
// In the `NODE_ENV="development"` the export default is different.
// A `FunctionDeclaration`
if (isStoriesComponentFn(node)) {
state.storiesFunctionDeclaration = node;
}

@@ -74,14 +72,17 @@ },

walk(ast, state, visitors);
const { defineMetaImport, defineMetaVariableDeclaration, storyIdentifier, storiesFunctionDeclaration, } = state;
const { defineMetaImport, defineMetaVariableDeclaration, exportDefault, storyIdentifier, storiesFunctionDeclaration, } = state;
if (!defineMetaImport) {
throw new Error(`Could not find '${AST_NODES_NAMES.defineMeta}' imported from the "${pkg.name}" in the stories file: ${filename}`);
throw new Error(`Could not find '${AST_NODES_NAMES.defineMeta}' imported from the "${pkg.name}" in the compiled output of stories file: ${filename}`);
}
if (!defineMetaVariableDeclaration) {
throw new Error(`Could not find '${defineMetaImport.local.name}({ ... })' call in the module tag ('<script context="module">') of the stories file: ${filename}`);
throw new Error(`Could not find '${defineMetaImport.local.name}({ ... })' in the compiled output of the stories file: ${filename}`);
}
if (!exportDefault) {
throw new Error(`Could not find 'export default' in the compiled output of the stories file: ${filename}`);
}
if (!storyIdentifier) {
throw new Error(`No story identifier found.`);
throw new Error(`Could not find 'Story' identifier in the compiled output of the stories file: ${filename}`);
}
if (!storiesFunctionDeclaration) {
throw new Error(`No stories function declaration found.`);
throw new Error(`Could not find the stories component '*.stories.svelte' function in the compiled output of the stories file: ${filename}`);
}

@@ -91,2 +92,3 @@ return {

defineMetaVariableDeclaration,
exportDefault,
storyIdentifier,

@@ -96,1 +98,6 @@ storiesFunctionDeclaration,

}
/**
*:The main component function of those stories file _(`*.stories.svelte`)_ will always end up with `_stories`.
* @see {@link "file://./../../../utils/get-component-name.ts"}
*/
const isStoriesComponentFn = (fnDeclaration) => fnDeclaration.id?.name.endsWith('_stories');

@@ -7,4 +7,4 @@ import type { Meta } from '@storybook/svelte';

nodes: SvelteASTNodes | CompiledASTNodes;
filename: string;
properties: Properties;
filename?: string;
}

@@ -14,3 +14,3 @@ type Result<Properties extends Array<keyof Meta>> = Partial<{

}>;
export declare function extractMetaPropertiesNodes<const Properties extends Array<keyof Meta>>(options: Options<Properties>): Promise<Result<Properties>>;
export declare function extractMetaPropertiesNodes<const Properties extends Array<keyof Meta>>(options: Options<Properties>): Result<Properties>;
export {};

@@ -1,16 +0,13 @@

export async function extractMetaPropertiesNodes(options) {
const { walk } = await import('zimmerframe');
export function extractMetaPropertiesNodes(options) {
const { properties } = options;
const objectExpression = getFirstArgumentObjectExpression(options);
const state = {};
const visitors = {
Property(node, { state }) {
if (node.key.type === 'Identifier' &&
properties.includes(node.key.name)) {
state[node.key.name] = node;
}
},
};
walk(objectExpression, state, visitors);
return state;
const results = {};
for (const property of objectExpression.properties) {
if (property.type === 'Property' &&
property.key.type === 'Identifier' &&
properties.includes(property.key.name)) {
results[property.key.name] = property;
}
}
return results;
}

@@ -17,0 +14,0 @@ function getFirstArgumentObjectExpression(options) {

/// <reference types="svelte" />
import type { Comment, Component, Fragment } from 'svelte/compiler';
import type { extractModuleNodes } from './module-nodes.js';
interface SvelteASTNodesFragment {
/**
*/
interface Result {
storyComponents: Array<{

@@ -22,3 +20,3 @@ comment?: Comment;

*/
export declare function extractFragmentNodes(params: Params): Promise<SvelteASTNodesFragment>;
export declare function extractFragmentNodes(params: Params): Promise<Result>;
export {};
/// <reference types="svelte" />
import type { Identifier, ImportSpecifier, VariableDeclaration } from 'estree';
import type { Script } from 'svelte/compiler';
interface SvelteASTNodesModule {
import type { Root } from 'svelte/compiler';
interface Result {
/**

@@ -21,4 +21,4 @@ * Import specifier for `defineMeta` imported from this addon package.

}
interface ExtractModuleNodesOptions {
module: Script;
interface Params {
module: Root['module'];
filename?: string;

@@ -31,3 +31,3 @@ }

*/
export declare function extractModuleNodes(options: ExtractModuleNodesOptions): Promise<SvelteASTNodesModule>;
export declare function extractModuleNodes(options: Params): Promise<Result>;
export {};

@@ -13,2 +13,7 @@ import pkg from '@storybook/addon-svelte-csf/package.json' with { type: 'json' };

const { module, filename } = options;
// TODO: Perhaps we can use some better way to insert error messages?
// String interpolations doesn't feel right if we want to provide a whole example (code snippet).
if (!module) {
throw new Error(`Couldn't find a module tag. Add (<script context="module">) to the stories file: ${filename}`);
}
const { walk } = await import('zimmerframe');

@@ -15,0 +20,0 @@ const state = {};

@@ -10,3 +10,3 @@ /// <reference types="svelte" />

export type SvelteASTNodes = Awaited<ReturnType<typeof extractModuleNodes>> & Awaited<ReturnType<typeof extractFragmentNodes>>;
interface ExtractSvelteASTNodesOptions {
interface Params {
ast: Root;

@@ -18,3 +18,3 @@ filename?: string;

*/
export declare function extractSvelteASTNodes(options: ExtractSvelteASTNodesOptions): Promise<SvelteASTNodes>;
export declare function extractSvelteASTNodes(params: Params): Promise<SvelteASTNodes>;
export {};

@@ -6,10 +6,5 @@ import { extractModuleNodes } from './module-nodes.js';

*/
export async function extractSvelteASTNodes(options) {
const { ast, filename } = options;
export async function extractSvelteASTNodes(params) {
const { ast, filename } = params;
const { module, fragment } = ast;
// TODO: Perhaps we can use some better way to insert error messages?
// String interpolations doesn't feel right if we want to provide a whole example (code snippet).
if (!module) {
throw new Error(`Couldn't find a module tag. Add (<script context="module">) to the stories file: ${filename}`);
}
const moduleNodes = await extractModuleNodes({ module, filename });

@@ -16,0 +11,0 @@ const fragmentNodes = await extractFragmentNodes({

@@ -1,57 +0,29 @@

import { describe, expect, it } from 'vitest';
import { describe, it } from 'vitest';
import { extractSvelteASTNodes } from './nodes.js';
import { getSvelteAST } from '../../../parser/ast.js';
describe(extractSvelteASTNodes.name, () => {
it('fails when module tag not found', () => {
it('works with a simple example', ({ expect }) => {
const ast = getSvelteAST({
source: `<script></script>`,
});
expect(extractSvelteASTNodes({ ast })).rejects.toThrow();
});
it("fails when 'defineMeta' not imported", () => {
const ast = getSvelteAST({
source: `<script context="module"></script>`,
});
expect(extractSvelteASTNodes({ ast })).rejects.toThrow();
});
it("fails when 'defineMeta' not used", () => {
const ast = getSvelteAST({
source: `
<script context="module">
import { defineMeta } from "@storybook/addon-svelte-csf";
import { defineMeta } from "@storybook/addon-svelte-csf"
import Button from "./Button.svelte";
const { Story, meta } = defineMeta({
component: Button,
});
</script>
<Story name="Default" />
<Story name="Playground">
{#snippet children(args)}
<Button {...args} />
{/snippet}
</Story>
`,
});
expect(extractSvelteASTNodes({ ast })).rejects.toThrow();
});
it("fails when 'Story' not destructured", () => {
const ast = getSvelteAST({
source: `
<script context="module">
import { defineMeta } from "@storybook/addon-svelte-csf"
defineMeta();
</script>`,
});
expect(extractSvelteASTNodes({ ast })).rejects.toThrow();
});
it('works when it has valid required snippet', () => {
const ast = getSvelteAST({
source: `
<script context="module">
import { defineMeta } from "@storybook/addon-svelte-csf"
const { Story } = defineMeta();
</script>`,
});
expect(extractSvelteASTNodes({ ast })).resolves.not.toThrow();
});
it('works on renamed identifiers', () => {
const ast = getSvelteAST({
source: `
<script context="module">
import { defineMeta as dm } from "@storybook/addon-svelte-csf"
const { Story: S, meta: m } = dm();
</script>`,
});
expect(extractSvelteASTNodes({ ast })).resolves.not.toThrow();
});
});
{
"name": "@storybook/addon-svelte-csf",
"version": "5.0.0--canary.181.030a862.0",
"version": "5.0.0--canary.181.0a3e376.0",
"description": "Allows to write stories in Svelte syntax",

@@ -16,2 +16,3 @@ "keywords": [

"type": "module",
"packageManager": "pnpm@9.1.3+sha512.7c2ea089e1a6af306409c4fc8c4f0897bdac32b772016196c469d9428f1fe2d5a21daf8ad6512762654ac645b5d9136bb210ec9a00afa8dbc4677843ba362ecd",
"exports": {

@@ -27,2 +28,6 @@ ".": {

},
"./internal/create-runtime-stories": {
"types": "./dist/runtime/create-runtime-stories.d.ts",
"default": "./dist/runtime/create-runtime-stories.js"
},
"./package.json": "./package.json"

@@ -35,3 +40,3 @@ },

"scripts": {
"clean": "rimraf ./dist",
"clean": "rimraf ./dist ./node_modules/.cache ./storybook-static ./svelte-kit ./.vite-inspect",
"build": "svelte-package --input ./src --types",

@@ -74,2 +79,3 @@ "prepublish": "pnpm run clean && pnpm run build",

"@types/node": "^20.12.12",
"@vitest/ui": "^1.6.0",
"auto": "^11.1.1",

@@ -76,0 +82,0 @@ "chromatic": "^6.19.9",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc