UNPKG

@storybook/codemod

Version:

A collection of codemod scripts written with JSCodeshift

134 lines (129 loc) 4.88 kB
import CJS_COMPAT_NODE_URL_9smq7eu765a from 'node:url'; import CJS_COMPAT_NODE_PATH_9smq7eu765a from 'node:path'; import CJS_COMPAT_NODE_MODULE_9smq7eu765a from "node:module"; var __filename = CJS_COMPAT_NODE_URL_9smq7eu765a.fileURLToPath(import.meta.url); var __dirname = CJS_COMPAT_NODE_PATH_9smq7eu765a.dirname(__filename); var require = CJS_COMPAT_NODE_MODULE_9smq7eu765a.createRequire(import.meta.url); // ------------------------------------------------------------ // end of CJS compatibility banner, injected by Storybook's esbuild configuration // ------------------------------------------------------------ import { __name } from "./chunk-HVEWKEW6.js"; // src/transforms/upgrade-deprecated-types.ts import { core as babel, types as t } from "storybook/internal/babel"; import { loadCsf, printCsf } from "storybook/internal/csf-tools"; import { logger } from "storybook/internal/node-logger"; import prettier from "prettier"; var deprecatedTypes = [ "ComponentStory", "ComponentStoryFn", "ComponentStoryObj", "ComponentMeta", "Story" ]; function migrateType(oldType) { if (oldType === "Story" || oldType === "ComponentStory") { return "StoryFn"; } return oldType.replace("Component", ""); } __name(migrateType, "migrateType"); async function transform(info, api, options) { const csf = loadCsf(info.source, { makeTitle: /* @__PURE__ */ __name((title) => title, "makeTitle") }); const fileNode = csf._ast; const file = new babel.File( { filename: info.path }, { code: info.source, ast: fileNode } ); upgradeDeprecatedTypes(file); let output = printCsf(csf).code; try { output = await prettier.format(output, { ...await prettier.resolveConfig(info.path), filepath: info.path }); } catch (e) { logger.log(`Failed applying prettier to ${info.path}.`); } return output; } __name(transform, "transform"); var parser = "tsx"; function upgradeDeprecatedTypes(file) { const importedNamespaces = /* @__PURE__ */ new Set(); const typeReferencesToUpdate = /* @__PURE__ */ new Set(); const existingImports = []; file.path.traverse({ ImportDeclaration: /* @__PURE__ */ __name((path) => { existingImports.push( ...path.get("specifiers").map((specifier) => ({ name: specifier.node.local.name, isAlias: !(specifier.isImportSpecifier() && t.isIdentifier(specifier.node.imported) && specifier.node.local.name === specifier.node.imported.name), path: specifier })) ); const source = path.node.source.value; if (!source.startsWith("@storybook")) { return; } path.get("specifiers").forEach((specifier) => { if (specifier.isImportNamespaceSpecifier()) { importedNamespaces.add(specifier.node.local.name); } if (!specifier.isImportSpecifier()) { return; } const imported = specifier.get("imported"); if (!imported.isIdentifier()) { return; } if (deprecatedTypes.includes(imported.node.name)) { if (imported.node.name === specifier.node.local.name) { typeReferencesToUpdate.add(specifier.node.local.name); } const newType = migrateType(imported.node.name); if (!existingImports.some((it) => it.name === newType)) { imported.replaceWith(t.identifier(newType)); existingImports.push({ name: newType, isAlias: false, path: specifier }); } else { const existingImport = existingImports.find((it) => it.name === newType && it.isAlias); if (existingImport) { throw existingImport.path.buildCodeFrameError( "This codemod does not support local imports that are called the same as a storybook import.\nRename this local import and try again." ); } else { specifier.remove(); } } } }); }, "ImportDeclaration") }); file.path.traverse({ TSTypeReference: /* @__PURE__ */ __name((path) => { const typeName = path.get("typeName"); if (typeName.isIdentifier()) { if (typeReferencesToUpdate.has(typeName.node.name)) { typeName.replaceWith(t.identifier(migrateType(typeName.node.name))); } } else if (typeName.isTSQualifiedName()) { const namespace = typeName.get("left"); if (namespace.isIdentifier()) { if (importedNamespaces.has(namespace.node.name)) { const right = typeName.get("right"); if (deprecatedTypes.includes(right.node.name)) { right.replaceWith(t.identifier(migrateType(right.node.name))); } } } } }, "TSTypeReference") }); } __name(upgradeDeprecatedTypes, "upgradeDeprecatedTypes"); export { transform, parser, upgradeDeprecatedTypes };