@storybook/addon-svelte-csf
Version:
Allows to write stories in Svelte syntax
73 lines (72 loc) • 2.97 kB
JavaScript
import pkg from '@storybook/addon-svelte-csf/package.json' with { type: 'json' };
import { DefaultOrNamespaceImportUsedError, MissingDefineMetaImportError, MissingDefineMetaVariableDeclarationError, MissingModuleTagError, NoStoryComponentDestructuredError, } from '../../../utils/error/parser/extract/svelte.js';
const AST_NODES_NAMES = {
defineMeta: 'defineMeta',
Story: 'Story',
};
/**
* Extract Svelte AST nodes via `svelte.compile`,
* and from the module tag - `<script module>`.
* They are needed for further code analysis/transformation.
*/
export async function extractModuleNodes(options) {
const { module, filename } = options;
if (!module) {
throw new MissingModuleTagError(filename);
}
const { walk } = await import('zimmerframe');
const state = {};
const visitors = {
ImportDeclaration(node, { state, visit }) {
const { source, specifiers } = node;
if (source.value === pkg.name) {
for (const specifier of specifiers) {
if (specifier.type !== 'ImportSpecifier') {
throw new DefaultOrNamespaceImportUsedError(filename);
}
visit(specifier, state);
}
}
},
ImportSpecifier(node) {
if ('name' in node.imported && node.imported.name === AST_NODES_NAMES.defineMeta) {
state.defineMetaImport = node;
}
},
VariableDeclaration(node, { state }) {
const { declarations } = node;
const declaration = declarations[0];
const { id, init } = declaration;
if (id.type === 'ObjectPattern' &&
init?.type === 'CallExpression' &&
init.callee.type === 'Identifier' &&
init.callee.name === state.defineMetaImport?.local.name) {
state.defineMetaVariableDeclaration = node;
for (const property of id.properties) {
if (property.type === 'Property' &&
property.key.type === 'Identifier' &&
property.key.name === AST_NODES_NAMES.Story &&
property.value.type === 'Identifier') {
state.storyIdentifier = property.value;
}
}
}
},
};
walk(module.content, state, visitors);
const { defineMetaImport, defineMetaVariableDeclaration, storyIdentifier } = state;
if (!defineMetaImport) {
throw new MissingDefineMetaImportError(filename);
}
if (!defineMetaVariableDeclaration) {
throw new MissingDefineMetaVariableDeclarationError(filename);
}
if (!storyIdentifier) {
throw new NoStoryComponentDestructuredError({ filename, defineMetaImport });
}
return {
defineMetaImport,
defineMetaVariableDeclaration,
storyIdentifier,
};
}