@storybook/codemod 10.1.0-alpha.10 → 10.1.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_node-chunks/chunk-LOEXTO7E.js +97 -0
- package/dist/index.js +23 -48
- package/dist/transforms/csf-2-to-3.js +90 -171
- package/dist/transforms/find-implicit-spies.js +55 -89
- package/dist/transforms/upgrade-deprecated-types.js +7 -8
- package/dist/transforms/upgrade-hierarchy-separators.js +14 -26
- package/package.json +3 -3
- package/dist/_node-chunks/chunk-YPRP2XJX.js +0 -17
- package/dist/_node-chunks/chunk-YU667ZTN.js +0 -133
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import CJS_COMPAT_NODE_URL_e0f36cf893t from 'node:url';
|
|
2
|
+
import CJS_COMPAT_NODE_PATH_e0f36cf893t from 'node:path';
|
|
3
|
+
import CJS_COMPAT_NODE_MODULE_e0f36cf893t from "node:module";
|
|
4
|
+
|
|
5
|
+
var __filename = CJS_COMPAT_NODE_URL_e0f36cf893t.fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = CJS_COMPAT_NODE_PATH_e0f36cf893t.dirname(__filename);
|
|
7
|
+
var require = CJS_COMPAT_NODE_MODULE_e0f36cf893t.createRequire(import.meta.url);
|
|
8
|
+
|
|
9
|
+
// ------------------------------------------------------------
|
|
10
|
+
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
|
|
11
|
+
// ------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
// src/transforms/upgrade-deprecated-types.ts
|
|
14
|
+
import { core as babel, types as t } from "storybook/internal/babel";
|
|
15
|
+
import { loadCsf, printCsf } from "storybook/internal/csf-tools";
|
|
16
|
+
import { logger } from "storybook/internal/node-logger";
|
|
17
|
+
import prettier from "prettier";
|
|
18
|
+
var deprecatedTypes = [
|
|
19
|
+
"ComponentStory",
|
|
20
|
+
"ComponentStoryFn",
|
|
21
|
+
"ComponentStoryObj",
|
|
22
|
+
"ComponentMeta",
|
|
23
|
+
"Story"
|
|
24
|
+
];
|
|
25
|
+
function migrateType(oldType) {
|
|
26
|
+
return oldType === "Story" || oldType === "ComponentStory" ? "StoryFn" : oldType.replace("Component", "");
|
|
27
|
+
}
|
|
28
|
+
async function transform(info, api, options) {
|
|
29
|
+
let csf = loadCsf(info.source, { makeTitle: (title) => title }), fileNode = csf._ast, file = new babel.File(
|
|
30
|
+
{ filename: info.path },
|
|
31
|
+
{ code: info.source, ast: fileNode }
|
|
32
|
+
);
|
|
33
|
+
upgradeDeprecatedTypes(file);
|
|
34
|
+
let output = printCsf(csf).code;
|
|
35
|
+
try {
|
|
36
|
+
output = await prettier.format(output, {
|
|
37
|
+
...await prettier.resolveConfig(info.path),
|
|
38
|
+
filepath: info.path
|
|
39
|
+
});
|
|
40
|
+
} catch {
|
|
41
|
+
logger.log(`Failed applying prettier to ${info.path}.`);
|
|
42
|
+
}
|
|
43
|
+
return output;
|
|
44
|
+
}
|
|
45
|
+
var parser = "tsx";
|
|
46
|
+
function upgradeDeprecatedTypes(file) {
|
|
47
|
+
let importedNamespaces = /* @__PURE__ */ new Set(), typeReferencesToUpdate = /* @__PURE__ */ new Set(), existingImports = [];
|
|
48
|
+
file.path.traverse({
|
|
49
|
+
ImportDeclaration: (path) => {
|
|
50
|
+
existingImports.push(
|
|
51
|
+
...path.get("specifiers").map((specifier) => ({
|
|
52
|
+
name: specifier.node.local.name,
|
|
53
|
+
isAlias: !(specifier.isImportSpecifier() && t.isIdentifier(specifier.node.imported) && specifier.node.local.name === specifier.node.imported.name),
|
|
54
|
+
path: specifier
|
|
55
|
+
}))
|
|
56
|
+
), path.node.source.value.startsWith("@storybook") && path.get("specifiers").forEach((specifier) => {
|
|
57
|
+
if (specifier.isImportNamespaceSpecifier() && importedNamespaces.add(specifier.node.local.name), !specifier.isImportSpecifier())
|
|
58
|
+
return;
|
|
59
|
+
let imported = specifier.get("imported");
|
|
60
|
+
if (imported.isIdentifier() && deprecatedTypes.includes(imported.node.name)) {
|
|
61
|
+
imported.node.name === specifier.node.local.name && typeReferencesToUpdate.add(specifier.node.local.name);
|
|
62
|
+
let newType = migrateType(imported.node.name);
|
|
63
|
+
if (!existingImports.some((it) => it.name === newType))
|
|
64
|
+
imported.replaceWith(t.identifier(newType)), existingImports.push({ name: newType, isAlias: !1, path: specifier });
|
|
65
|
+
else {
|
|
66
|
+
let existingImport = existingImports.find((it) => it.name === newType && it.isAlias);
|
|
67
|
+
if (existingImport)
|
|
68
|
+
throw existingImport.path.buildCodeFrameError(
|
|
69
|
+
`This codemod does not support local imports that are called the same as a storybook import.
|
|
70
|
+
Rename this local import and try again.`
|
|
71
|
+
);
|
|
72
|
+
specifier.remove();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}), file.path.traverse({
|
|
78
|
+
TSTypeReference: (path) => {
|
|
79
|
+
let typeName = path.get("typeName");
|
|
80
|
+
if (typeName.isIdentifier())
|
|
81
|
+
typeReferencesToUpdate.has(typeName.node.name) && typeName.replaceWith(t.identifier(migrateType(typeName.node.name)));
|
|
82
|
+
else if (typeName.isTSQualifiedName()) {
|
|
83
|
+
let namespace = typeName.get("left");
|
|
84
|
+
if (namespace.isIdentifier() && importedNamespaces.has(namespace.node.name)) {
|
|
85
|
+
let right = typeName.get("right");
|
|
86
|
+
deprecatedTypes.includes(right.node.name) && right.replaceWith(t.identifier(migrateType(right.node.name)));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export {
|
|
94
|
+
transform,
|
|
95
|
+
parser,
|
|
96
|
+
upgradeDeprecatedTypes
|
|
97
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import CJS_COMPAT_NODE_URL_e0f36cf893t from 'node:url';
|
|
2
|
+
import CJS_COMPAT_NODE_PATH_e0f36cf893t from 'node:path';
|
|
3
|
+
import CJS_COMPAT_NODE_MODULE_e0f36cf893t from "node:module";
|
|
4
4
|
|
|
5
|
-
var __filename =
|
|
6
|
-
var __dirname =
|
|
7
|
-
var require =
|
|
5
|
+
var __filename = CJS_COMPAT_NODE_URL_e0f36cf893t.fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = CJS_COMPAT_NODE_PATH_e0f36cf893t.dirname(__filename);
|
|
7
|
+
var require = CJS_COMPAT_NODE_MODULE_e0f36cf893t.createRequire(import.meta.url);
|
|
8
8
|
|
|
9
9
|
// ------------------------------------------------------------
|
|
10
10
|
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
|
|
11
11
|
// ------------------------------------------------------------
|
|
12
|
-
import {
|
|
13
|
-
__name
|
|
14
|
-
} from "./_node-chunks/chunk-YPRP2XJX.js";
|
|
15
12
|
|
|
16
13
|
// src/index.ts
|
|
17
14
|
import { readdirSync } from "node:fs";
|
|
@@ -24,31 +21,24 @@ import { glob as tinyglobby } from "tinyglobby";
|
|
|
24
21
|
// src/lib/utils.ts
|
|
25
22
|
import { camelCase, upperFirst } from "es-toolkit/string";
|
|
26
23
|
function jscodeshiftToPrettierParser(parser) {
|
|
27
|
-
|
|
24
|
+
let parserMap = {
|
|
28
25
|
babylon: "babel",
|
|
29
26
|
flow: "flow",
|
|
30
27
|
ts: "typescript",
|
|
31
28
|
tsx: "typescript"
|
|
32
29
|
};
|
|
33
|
-
|
|
34
|
-
return "babel";
|
|
35
|
-
}
|
|
36
|
-
return parserMap[parser] || "babel";
|
|
30
|
+
return parser && parserMap[parser] || "babel";
|
|
37
31
|
}
|
|
38
|
-
__name(jscodeshiftToPrettierParser, "jscodeshiftToPrettierParser");
|
|
39
32
|
|
|
40
33
|
// src/index.ts
|
|
41
34
|
var TRANSFORM_DIR = join(resolvePackageDir("@storybook/codemod"), "dist", "transforms");
|
|
42
35
|
function listCodemods() {
|
|
43
36
|
return readdirSync(TRANSFORM_DIR).filter((fname) => fname.endsWith(".js")).map((fname) => fname.slice(0, -3));
|
|
44
37
|
}
|
|
45
|
-
__name(listCodemods, "listCodemods");
|
|
46
38
|
async function renameFile(file, from, to, { logger }) {
|
|
47
|
-
|
|
48
|
-
logger.log(`Rename: ${file} ${newFile}`);
|
|
49
|
-
return renameAsync(file, newFile);
|
|
39
|
+
let newFile = file.replace(from, to);
|
|
40
|
+
return logger.log(`Rename: ${file} ${newFile}`), renameAsync(file, newFile);
|
|
50
41
|
}
|
|
51
|
-
__name(renameFile, "renameFile");
|
|
52
42
|
async function runCodemod(codemod, {
|
|
53
43
|
glob,
|
|
54
44
|
logger,
|
|
@@ -56,36 +46,23 @@ async function runCodemod(codemod, {
|
|
|
56
46
|
rename,
|
|
57
47
|
parser
|
|
58
48
|
}) {
|
|
59
|
-
|
|
60
|
-
if (!codemods.includes(codemod)) {
|
|
49
|
+
if (!listCodemods().includes(codemod))
|
|
61
50
|
throw new Error(`Unknown codemod ${codemod}. Run --list for options.`);
|
|
62
|
-
}
|
|
63
51
|
let renameParts = null;
|
|
64
|
-
if (rename)
|
|
65
|
-
|
|
66
|
-
if (renameParts.length !== 2) {
|
|
67
|
-
throw new Error(`Codemod rename: expected format "from:to", got "${rename}"`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
52
|
+
if (rename && (renameParts = rename.split(":"), renameParts.length !== 2))
|
|
53
|
+
throw new Error(`Codemod rename: expected format "from:to", got "${rename}"`);
|
|
70
54
|
let inferredParser = parser;
|
|
71
55
|
if (!parser) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (knownParser !== "babel") {
|
|
75
|
-
inferredParser = extension;
|
|
76
|
-
}
|
|
56
|
+
let extension = extname(glob).slice(1);
|
|
57
|
+
jscodeshiftToPrettierParser(extension) !== "babel" && (inferredParser = extension);
|
|
77
58
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const commaSeparatedExtensions = Array.from(extensions).join(",");
|
|
81
|
-
logger.log(`=> Applying ${codemod}: ${files.length} files`);
|
|
82
|
-
if (files.length === 0) {
|
|
59
|
+
let files = await tinyglobby([glob, "!**/node_modules", "!**/dist"]), extensions = new Set(files.map((file) => extname(file).slice(1))), commaSeparatedExtensions = Array.from(extensions).join(",");
|
|
60
|
+
if (logger.log(`=> Applying ${codemod}: ${files.length} files`), files.length === 0) {
|
|
83
61
|
logger.log(`=> No matching files for glob: ${glob}`);
|
|
84
62
|
return;
|
|
85
63
|
}
|
|
86
64
|
if (!dryRun && files.length > 0) {
|
|
87
|
-
|
|
88
|
-
const result = spawnSync(
|
|
65
|
+
let parserArgs = inferredParser ? ["--parser", inferredParser] : [], result = spawnSync(
|
|
89
66
|
"node",
|
|
90
67
|
[
|
|
91
68
|
join(resolvePackageDir("jscodeshift"), "bin", "jscodeshift"),
|
|
@@ -102,27 +79,25 @@ async function runCodemod(codemod, {
|
|
|
102
79
|
],
|
|
103
80
|
{
|
|
104
81
|
stdio: "inherit",
|
|
105
|
-
shell:
|
|
82
|
+
shell: !0
|
|
106
83
|
}
|
|
107
84
|
);
|
|
108
|
-
if (codemod === "mdx-to-csf" && result.status === 1)
|
|
85
|
+
if (codemod === "mdx-to-csf" && result.status === 1)
|
|
109
86
|
logger.log(
|
|
110
87
|
"The codemod was not able to transform the files mentioned above. We have renamed the files to .mdx.broken. Please check the files and rename them back to .mdx after you have either manually transformed them to mdx + csf or fixed the issues so that the codemod can transform them."
|
|
111
88
|
);
|
|
112
|
-
|
|
89
|
+
else if (result.status === 1) {
|
|
113
90
|
logger.log("Skipped renaming because of errors.");
|
|
114
91
|
return;
|
|
115
92
|
}
|
|
116
93
|
}
|
|
117
94
|
if (renameParts) {
|
|
118
|
-
|
|
119
|
-
logger.log(`=> Renaming ${rename}: ${files.length} files`)
|
|
120
|
-
await Promise.all(
|
|
95
|
+
let [from, to] = renameParts;
|
|
96
|
+
logger.log(`=> Renaming ${rename}: ${files.length} files`), await Promise.all(
|
|
121
97
|
files.map((file) => renameFile(file, new RegExp(`${from}$`), to, { logger }))
|
|
122
98
|
);
|
|
123
99
|
}
|
|
124
100
|
}
|
|
125
|
-
__name(runCodemod, "runCodemod");
|
|
126
101
|
export {
|
|
127
102
|
listCodemods,
|
|
128
103
|
runCodemod
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import CJS_COMPAT_NODE_URL_e0f36cf893t from 'node:url';
|
|
2
|
+
import CJS_COMPAT_NODE_PATH_e0f36cf893t from 'node:path';
|
|
3
|
+
import CJS_COMPAT_NODE_MODULE_e0f36cf893t from "node:module";
|
|
4
4
|
|
|
5
|
-
var __filename =
|
|
6
|
-
var __dirname =
|
|
7
|
-
var require =
|
|
5
|
+
var __filename = CJS_COMPAT_NODE_URL_e0f36cf893t.fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = CJS_COMPAT_NODE_PATH_e0f36cf893t.dirname(__filename);
|
|
7
|
+
var require = CJS_COMPAT_NODE_MODULE_e0f36cf893t.createRequire(import.meta.url);
|
|
8
8
|
|
|
9
9
|
// ------------------------------------------------------------
|
|
10
10
|
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
|
|
11
11
|
// ------------------------------------------------------------
|
|
12
12
|
import {
|
|
13
13
|
upgradeDeprecatedTypes
|
|
14
|
-
} from "../_node-chunks/chunk-
|
|
15
|
-
import {
|
|
16
|
-
__name
|
|
17
|
-
} from "../_node-chunks/chunk-YPRP2XJX.js";
|
|
14
|
+
} from "../_node-chunks/chunk-LOEXTO7E.js";
|
|
18
15
|
|
|
19
16
|
// src/transforms/csf-2-to-3.ts
|
|
20
17
|
import { core as babel, types as t } from "storybook/internal/babel";
|
|
@@ -22,82 +19,56 @@ import { loadCsf, printCsf } from "storybook/internal/csf-tools";
|
|
|
22
19
|
import { logger } from "storybook/internal/node-logger";
|
|
23
20
|
import prettier from "prettier";
|
|
24
21
|
import invariant from "tiny-invariant";
|
|
25
|
-
var { isIdentifier, isTSTypeAnnotation, isTSTypeReference } = t
|
|
26
|
-
var renameAnnotation = /* @__PURE__ */ __name((annotation) => {
|
|
27
|
-
return annotation === "storyName" ? "name" : annotation;
|
|
28
|
-
}, "renameAnnotation");
|
|
29
|
-
var getTemplateBindVariable = /* @__PURE__ */ __name((init) => t.isCallExpression(init) && t.isMemberExpression(init.callee) && t.isIdentifier(init.callee.object) && t.isIdentifier(init.callee.property) && init.callee.property.name === "bind" && (init.arguments.length === 0 || init.arguments.length === 1 && t.isObjectExpression(init.arguments[0]) && init.arguments[0].properties.length === 0) ? init.callee.object.name : null, "getTemplateBindVariable");
|
|
30
|
-
var isStoryAnnotation = /* @__PURE__ */ __name((stmt, objectExports) => t.isExpressionStatement(stmt) && t.isAssignmentExpression(stmt.expression) && t.isMemberExpression(stmt.expression.left) && t.isIdentifier(stmt.expression.left.object) && objectExports[stmt.expression.left.object.name], "isStoryAnnotation");
|
|
31
|
-
var getNewExport = /* @__PURE__ */ __name((stmt, objectExports) => {
|
|
22
|
+
var { isIdentifier, isTSTypeAnnotation, isTSTypeReference } = t, renameAnnotation = (annotation) => annotation === "storyName" ? "name" : annotation, getTemplateBindVariable = (init) => t.isCallExpression(init) && t.isMemberExpression(init.callee) && t.isIdentifier(init.callee.object) && t.isIdentifier(init.callee.property) && init.callee.property.name === "bind" && (init.arguments.length === 0 || init.arguments.length === 1 && t.isObjectExpression(init.arguments[0]) && init.arguments[0].properties.length === 0) ? init.callee.object.name : null, isStoryAnnotation = (stmt, objectExports) => t.isExpressionStatement(stmt) && t.isAssignmentExpression(stmt.expression) && t.isMemberExpression(stmt.expression.left) && t.isIdentifier(stmt.expression.left.object) && objectExports[stmt.expression.left.object.name], getNewExport = (stmt, objectExports) => {
|
|
32
23
|
if (t.isExportNamedDeclaration(stmt) && t.isVariableDeclaration(stmt.declaration) && stmt.declaration.declarations.length === 1) {
|
|
33
|
-
|
|
34
|
-
if (t.isVariableDeclarator(decl) && t.isIdentifier(decl.id))
|
|
24
|
+
let decl = stmt.declaration.declarations[0];
|
|
25
|
+
if (t.isVariableDeclarator(decl) && t.isIdentifier(decl.id))
|
|
35
26
|
return objectExports[decl.id.name];
|
|
36
|
-
}
|
|
37
27
|
}
|
|
38
28
|
return null;
|
|
39
|
-
},
|
|
40
|
-
var isReactGlobalRenderFn = /* @__PURE__ */ __name((csf, storyFn) => {
|
|
29
|
+
}, isReactGlobalRenderFn = (csf, storyFn) => {
|
|
41
30
|
if (csf._meta?.component && t.isArrowFunctionExpression(storyFn) && storyFn.params.length === 1 && t.isJSXElement(storyFn.body)) {
|
|
42
|
-
|
|
31
|
+
let { openingElement } = storyFn.body;
|
|
43
32
|
if (openingElement.selfClosing && t.isJSXIdentifier(openingElement.name) && openingElement.attributes.length === 1) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
33
|
+
let attr = openingElement.attributes[0], param = storyFn.params[0];
|
|
34
|
+
if (t.isJSXSpreadAttribute(attr) && t.isIdentifier(attr.argument) && t.isIdentifier(param) && param.name === attr.argument.name && csf._meta.component === openingElement.name.name)
|
|
35
|
+
return !0;
|
|
49
36
|
}
|
|
50
37
|
}
|
|
51
|
-
return
|
|
52
|
-
},
|
|
53
|
-
var isSimpleCSFStory = /* @__PURE__ */ __name((init, annotations) => annotations.length === 0 && t.isArrowFunctionExpression(init) && init.params.length === 0, "isSimpleCSFStory");
|
|
38
|
+
return !1;
|
|
39
|
+
}, isSimpleCSFStory = (init, annotations) => annotations.length === 0 && t.isArrowFunctionExpression(init) && init.params.length === 0;
|
|
54
40
|
function removeUnusedTemplates(csf) {
|
|
55
41
|
Object.entries(csf._templates).forEach(([template, templateExpression]) => {
|
|
56
|
-
|
|
57
|
-
babel.traverse(csf._ast, {
|
|
58
|
-
Identifier:
|
|
59
|
-
|
|
60
|
-
references.push(path);
|
|
61
|
-
}
|
|
62
|
-
}, "Identifier")
|
|
63
|
-
});
|
|
64
|
-
if (references.length === 1) {
|
|
65
|
-
const reference = references[0];
|
|
66
|
-
if (reference.parentPath?.isVariableDeclarator() && reference.parentPath.node.init === templateExpression) {
|
|
67
|
-
reference.parentPath.remove();
|
|
42
|
+
let references = [];
|
|
43
|
+
if (babel.traverse(csf._ast, {
|
|
44
|
+
Identifier: (path) => {
|
|
45
|
+
path.node.name === template && references.push(path);
|
|
68
46
|
}
|
|
47
|
+
}), references.length === 1) {
|
|
48
|
+
let reference = references[0];
|
|
49
|
+
reference.parentPath?.isVariableDeclarator() && reference.parentPath.node.init === templateExpression && reference.parentPath.remove();
|
|
69
50
|
}
|
|
70
51
|
});
|
|
71
52
|
}
|
|
72
|
-
__name(removeUnusedTemplates, "removeUnusedTemplates");
|
|
73
53
|
async function transform(info, api, options) {
|
|
74
|
-
|
|
75
|
-
return userTitle || "FIXME";
|
|
76
|
-
}, "makeTitle");
|
|
77
|
-
const csf = loadCsf(info.source, { makeTitle });
|
|
54
|
+
let makeTitle = (userTitle) => userTitle || "FIXME", csf = loadCsf(info.source, { makeTitle });
|
|
78
55
|
try {
|
|
79
56
|
csf.parse();
|
|
80
57
|
} catch (err) {
|
|
81
|
-
logger.log(`Error ${err}, skipping`);
|
|
82
|
-
return info.source;
|
|
58
|
+
return logger.log(`Error ${err}, skipping`), info.source;
|
|
83
59
|
}
|
|
84
|
-
|
|
60
|
+
let file = new babel.File(
|
|
85
61
|
{ filename: info.path },
|
|
86
62
|
{ code: info.source, ast: csf._ast }
|
|
87
|
-
);
|
|
88
|
-
const importHelper = new StorybookImportHelper(file, info);
|
|
89
|
-
const objectExports = {};
|
|
63
|
+
), importHelper = new StorybookImportHelper(file, info), objectExports = {};
|
|
90
64
|
Object.entries(csf._storyExports).forEach(([key, decl]) => {
|
|
91
|
-
|
|
92
|
-
return t.objectProperty(t.identifier(renameAnnotation(annotation)), val);
|
|
93
|
-
});
|
|
65
|
+
let annotations = Object.entries(csf._storyAnnotations[key]).map(([annotation, val]) => t.objectProperty(t.identifier(renameAnnotation(annotation)), val));
|
|
94
66
|
if (t.isVariableDeclarator(decl)) {
|
|
95
|
-
|
|
67
|
+
let { init, id } = decl;
|
|
96
68
|
invariant(init, "Inital value should be declared");
|
|
97
|
-
|
|
98
|
-
if (!t.isArrowFunctionExpression(init) && !template)
|
|
69
|
+
let template = getTemplateBindVariable(init);
|
|
70
|
+
if (!t.isArrowFunctionExpression(init) && !template)
|
|
99
71
|
return;
|
|
100
|
-
}
|
|
101
72
|
if (isSimpleCSFStory(init, annotations)) {
|
|
102
73
|
objectExports[key] = t.exportNamedDeclaration(
|
|
103
74
|
t.variableDeclaration("const", [
|
|
@@ -106,8 +77,7 @@ async function transform(info, api, options) {
|
|
|
106
77
|
);
|
|
107
78
|
return;
|
|
108
79
|
}
|
|
109
|
-
|
|
110
|
-
const renderAnnotation = isReactGlobalRenderFn(
|
|
80
|
+
let storyFn = template ? t.identifier(template) : init, renderAnnotation = isReactGlobalRenderFn(
|
|
111
81
|
csf,
|
|
112
82
|
template ? csf._templates[template] : storyFn
|
|
113
83
|
) ? [] : [t.objectProperty(t.identifier("render"), storyFn)];
|
|
@@ -120,77 +90,43 @@ async function transform(info, api, options) {
|
|
|
120
90
|
])
|
|
121
91
|
);
|
|
122
92
|
}
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (isStoryAnnotation(statement, objectExports)) {
|
|
93
|
+
}), csf._ast.program.body = csf._ast.program.body.reduce((acc, stmt) => {
|
|
94
|
+
let statement = stmt;
|
|
95
|
+
if (isStoryAnnotation(statement, objectExports))
|
|
127
96
|
return acc;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
acc.push(newExport);
|
|
132
|
-
return acc;
|
|
133
|
-
}
|
|
134
|
-
acc.push(statement);
|
|
135
|
-
return acc;
|
|
136
|
-
}, []);
|
|
137
|
-
upgradeDeprecatedTypes(file);
|
|
138
|
-
importHelper.removeDeprecatedStoryImport();
|
|
139
|
-
removeUnusedTemplates(csf);
|
|
97
|
+
let newExport = getNewExport(statement, objectExports);
|
|
98
|
+
return newExport ? (acc.push(newExport), acc) : (acc.push(statement), acc);
|
|
99
|
+
}, []), upgradeDeprecatedTypes(file), importHelper.removeDeprecatedStoryImport(), removeUnusedTemplates(csf);
|
|
140
100
|
let output = printCsf(csf).code;
|
|
141
101
|
try {
|
|
142
102
|
output = await prettier.format(output, {
|
|
143
103
|
...await prettier.resolveConfig(info.path),
|
|
144
104
|
filepath: info.path
|
|
145
105
|
});
|
|
146
|
-
} catch
|
|
106
|
+
} catch {
|
|
147
107
|
logger.log(`Failed applying prettier to ${info.path}.`);
|
|
148
108
|
}
|
|
149
109
|
return output;
|
|
150
110
|
}
|
|
151
|
-
__name(transform, "transform");
|
|
152
111
|
var StorybookImportHelper = class {
|
|
153
112
|
constructor(file, info) {
|
|
154
|
-
this.getAllSbImportDeclarations =
|
|
155
|
-
|
|
156
|
-
file.path.traverse({
|
|
157
|
-
ImportDeclaration:
|
|
158
|
-
|
|
159
|
-
if (source.startsWith("@storybook/csf") || !source.startsWith("@storybook"))
|
|
113
|
+
this.getAllSbImportDeclarations = (file) => {
|
|
114
|
+
let found = [];
|
|
115
|
+
return file.path.traverse({
|
|
116
|
+
ImportDeclaration: (path) => {
|
|
117
|
+
let source = path.node.source.value;
|
|
118
|
+
if (source.startsWith("@storybook/csf") || !source.startsWith("@storybook"))
|
|
160
119
|
return;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (specifier.isImportNamespaceSpecifier()) {
|
|
120
|
+
path.get("specifiers").some((specifier) => {
|
|
121
|
+
if (specifier.isImportNamespaceSpecifier())
|
|
164
122
|
throw new Error(
|
|
165
123
|
`This codemod does not support namespace imports for a ${path.node.source.value} package.
|
|
166
124
|
Replace the namespace import with named imports and try again.`
|
|
167
125
|
);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const imported = specifier.get("imported");
|
|
173
|
-
if (Array.isArray(imported)) {
|
|
174
|
-
return imported.some((importedSpecifier) => {
|
|
175
|
-
if (!importedSpecifier.isIdentifier()) {
|
|
176
|
-
return false;
|
|
177
|
-
}
|
|
178
|
-
return [
|
|
179
|
-
"Story",
|
|
180
|
-
"StoryFn",
|
|
181
|
-
"StoryObj",
|
|
182
|
-
"Meta",
|
|
183
|
-
"ComponentStory",
|
|
184
|
-
"ComponentStoryFn",
|
|
185
|
-
"ComponentStoryObj",
|
|
186
|
-
"ComponentMeta"
|
|
187
|
-
].includes(importedSpecifier.node.name);
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
if (!imported.isIdentifier()) {
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
return [
|
|
126
|
+
if (!specifier.isImportSpecifier())
|
|
127
|
+
return !1;
|
|
128
|
+
let imported = specifier.get("imported");
|
|
129
|
+
return Array.isArray(imported) ? imported.some((importedSpecifier) => importedSpecifier.isIdentifier() ? [
|
|
194
130
|
"Story",
|
|
195
131
|
"StoryFn",
|
|
196
132
|
"StoryObj",
|
|
@@ -199,59 +135,46 @@ Replace the namespace import with named imports and try again.`
|
|
|
199
135
|
"ComponentStoryFn",
|
|
200
136
|
"ComponentStoryObj",
|
|
201
137
|
"ComponentMeta"
|
|
202
|
-
].includes(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
if (sbImport == null) {
|
|
214
|
-
return void 0;
|
|
215
|
-
}
|
|
216
|
-
const specifiers = sbImport.get("specifiers");
|
|
217
|
-
const importSpecifier = specifiers.find((specifier) => {
|
|
218
|
-
if (!specifier.isImportSpecifier()) {
|
|
219
|
-
return false;
|
|
220
|
-
}
|
|
221
|
-
const imported = specifier.get("imported");
|
|
222
|
-
if (!imported.isIdentifier()) {
|
|
223
|
-
return false;
|
|
224
|
-
}
|
|
225
|
-
return imported.node.name === type;
|
|
226
|
-
});
|
|
227
|
-
if (importSpecifier) {
|
|
228
|
-
return importSpecifier.node.local.name;
|
|
229
|
-
}
|
|
230
|
-
specifiers[0].insertBefore(t.importSpecifier(t.identifier(type), t.identifier(type)));
|
|
231
|
-
return type;
|
|
232
|
-
}, "getOrAddImport");
|
|
233
|
-
this.removeDeprecatedStoryImport = /* @__PURE__ */ __name(() => {
|
|
234
|
-
const specifiers = this.sbImportDeclarations.flatMap((it) => it.get("specifiers"));
|
|
235
|
-
const storyImports = specifiers.filter((specifier) => {
|
|
236
|
-
if (!specifier.isImportSpecifier()) {
|
|
237
|
-
return false;
|
|
238
|
-
}
|
|
239
|
-
const imported = specifier.get("imported");
|
|
240
|
-
if (!imported.isIdentifier()) {
|
|
241
|
-
return false;
|
|
138
|
+
].includes(importedSpecifier.node.name) : !1) : imported.isIdentifier() ? [
|
|
139
|
+
"Story",
|
|
140
|
+
"StoryFn",
|
|
141
|
+
"StoryObj",
|
|
142
|
+
"Meta",
|
|
143
|
+
"ComponentStory",
|
|
144
|
+
"ComponentStoryFn",
|
|
145
|
+
"ComponentStoryObj",
|
|
146
|
+
"ComponentMeta"
|
|
147
|
+
].includes(imported.node.name) : !1;
|
|
148
|
+
}) && found.push(path);
|
|
242
149
|
}
|
|
243
|
-
|
|
150
|
+
}), found;
|
|
151
|
+
};
|
|
152
|
+
this.getOrAddImport = (type) => {
|
|
153
|
+
let sbImport = this.sbImportDeclarations.find((path) => path.node.importKind === "type") ?? this.sbImportDeclarations[0];
|
|
154
|
+
if (sbImport == null)
|
|
155
|
+
return;
|
|
156
|
+
let specifiers = sbImport.get("specifiers"), importSpecifier = specifiers.find((specifier) => {
|
|
157
|
+
if (!specifier.isImportSpecifier())
|
|
158
|
+
return !1;
|
|
159
|
+
let imported = specifier.get("imported");
|
|
160
|
+
return imported.isIdentifier() ? imported.node.name === type : !1;
|
|
244
161
|
});
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
this.
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
162
|
+
return importSpecifier ? importSpecifier.node.local.name : (specifiers[0].insertBefore(t.importSpecifier(t.identifier(type), t.identifier(type))), type);
|
|
163
|
+
};
|
|
164
|
+
this.removeDeprecatedStoryImport = () => {
|
|
165
|
+
this.sbImportDeclarations.flatMap((it) => it.get("specifiers")).filter((specifier) => {
|
|
166
|
+
if (!specifier.isImportSpecifier())
|
|
167
|
+
return !1;
|
|
168
|
+
let imported = specifier.get("imported");
|
|
169
|
+
return imported.isIdentifier() ? imported.node.name === "Story" : !1;
|
|
170
|
+
}).forEach((path) => path.remove());
|
|
171
|
+
};
|
|
172
|
+
this.getAllLocalImports = () => this.sbImportDeclarations.flatMap((it) => it.get("specifiers")).map((it) => it.node.local.name);
|
|
173
|
+
this.updateTypeTo = (id, type) => {
|
|
251
174
|
if (isIdentifier(id) && isTSTypeAnnotation(id.typeAnnotation) && isTSTypeReference(id.typeAnnotation.typeAnnotation) && isIdentifier(id.typeAnnotation.typeAnnotation.typeName)) {
|
|
252
|
-
|
|
175
|
+
let { name } = id.typeAnnotation.typeAnnotation.typeName;
|
|
253
176
|
if (this.getAllLocalImports().includes(name)) {
|
|
254
|
-
|
|
177
|
+
let localTypeImport = this.getOrAddImport(type);
|
|
255
178
|
return {
|
|
256
179
|
...id,
|
|
257
180
|
typeAnnotation: t.tsTypeAnnotation(
|
|
@@ -264,14 +187,10 @@ Replace the namespace import with named imports and try again.`
|
|
|
264
187
|
}
|
|
265
188
|
}
|
|
266
189
|
return id;
|
|
267
|
-
}
|
|
190
|
+
};
|
|
268
191
|
this.sbImportDeclarations = this.getAllSbImportDeclarations(file);
|
|
269
192
|
}
|
|
270
|
-
|
|
271
|
-
__name(this, "StorybookImportHelper");
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
|
-
var parser = "tsx";
|
|
193
|
+
}, parser = "tsx";
|
|
275
194
|
export {
|
|
276
195
|
transform as default,
|
|
277
196
|
parser
|
|
@@ -1,144 +1,110 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import CJS_COMPAT_NODE_URL_e0f36cf893t from 'node:url';
|
|
2
|
+
import CJS_COMPAT_NODE_PATH_e0f36cf893t from 'node:path';
|
|
3
|
+
import CJS_COMPAT_NODE_MODULE_e0f36cf893t from "node:module";
|
|
4
4
|
|
|
5
|
-
var __filename =
|
|
6
|
-
var __dirname =
|
|
7
|
-
var require =
|
|
5
|
+
var __filename = CJS_COMPAT_NODE_URL_e0f36cf893t.fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = CJS_COMPAT_NODE_PATH_e0f36cf893t.dirname(__filename);
|
|
7
|
+
var require = CJS_COMPAT_NODE_MODULE_e0f36cf893t.createRequire(import.meta.url);
|
|
8
8
|
|
|
9
9
|
// ------------------------------------------------------------
|
|
10
10
|
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
|
|
11
11
|
// ------------------------------------------------------------
|
|
12
|
-
import {
|
|
13
|
-
__name
|
|
14
|
-
} from "../_node-chunks/chunk-YPRP2XJX.js";
|
|
15
12
|
|
|
16
13
|
// src/transforms/find-implicit-spies.ts
|
|
17
14
|
import { core as babel, types as t } from "storybook/internal/babel";
|
|
18
15
|
import { loadCsf } from "storybook/internal/csf-tools";
|
|
19
16
|
function findImplicitSpies(path, file, keys) {
|
|
20
17
|
path.traverse({
|
|
21
|
-
Identifier:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
}, "Identifier")
|
|
18
|
+
Identifier: (identifier) => {
|
|
19
|
+
!keys.includes(identifier.node.name) && /^on[A-Z].*/.test(identifier.node.name) && console.warn(identifier.buildCodeFrameError(`${file} Possible implicit spy found`).message);
|
|
20
|
+
}
|
|
26
21
|
});
|
|
27
22
|
}
|
|
28
|
-
__name(findImplicitSpies, "findImplicitSpies");
|
|
29
23
|
function getAnnotationKeys(file, storyName, annotationName) {
|
|
30
|
-
|
|
31
|
-
file.path.traverse({
|
|
24
|
+
let argKeys = [];
|
|
25
|
+
return file.path.traverse({
|
|
32
26
|
// CSF2 play function Story.args =
|
|
33
|
-
AssignmentExpression:
|
|
34
|
-
|
|
35
|
-
if (!left.isMemberExpression())
|
|
27
|
+
AssignmentExpression: (path) => {
|
|
28
|
+
let left = path.get("left");
|
|
29
|
+
if (!left.isMemberExpression())
|
|
36
30
|
return;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (!(object.isIdentifier() && object.node.name === storyName)) {
|
|
31
|
+
let object = left.get("object");
|
|
32
|
+
if (!(object.isIdentifier() && object.node.name === storyName))
|
|
40
33
|
return;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
)
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
}, "AssignmentExpression"),
|
|
34
|
+
let property = left.get("property"), right = path.get("right");
|
|
35
|
+
property.isIdentifier() && property.node.name === annotationName && right.isObjectExpression() && argKeys.push(
|
|
36
|
+
...right.node.properties.flatMap(
|
|
37
|
+
(value) => t.isObjectProperty(value) && t.isIdentifier(value.key) ? [value.key.name] : []
|
|
38
|
+
)
|
|
39
|
+
);
|
|
40
|
+
},
|
|
52
41
|
// CSF3 const Story = {args: () => {} };
|
|
53
|
-
VariableDeclarator:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (!(id.isIdentifier() && id.node.name === storyName) || !init.isObjectExpression()) {
|
|
42
|
+
VariableDeclarator: (path) => {
|
|
43
|
+
let id = path.get("id"), init = path.get("init");
|
|
44
|
+
if (!(id.isIdentifier() && id.node.name === storyName) || !init.isObjectExpression())
|
|
57
45
|
return;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const argKey = it.get("key");
|
|
46
|
+
let args = init.get("properties").flatMap((it) => it.isObjectProperty() ? [it] : []).find((it) => {
|
|
47
|
+
let argKey = it.get("key");
|
|
61
48
|
return argKey.isIdentifier() && argKey.node.name === annotationName;
|
|
62
49
|
});
|
|
63
|
-
if (!args)
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const argsValue = args.get("value");
|
|
67
|
-
if (!argsValue || !argsValue.isObjectExpression()) {
|
|
50
|
+
if (!args)
|
|
68
51
|
return;
|
|
69
|
-
|
|
70
|
-
argKeys.push(
|
|
52
|
+
let argsValue = args.get("value");
|
|
53
|
+
!argsValue || !argsValue.isObjectExpression() || argKeys.push(
|
|
71
54
|
...argsValue.node.properties.flatMap(
|
|
72
55
|
(value) => t.isObjectProperty(value) && t.isIdentifier(value.key) ? [value.key.name] : []
|
|
73
56
|
)
|
|
74
57
|
);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
return argKeys;
|
|
58
|
+
}
|
|
59
|
+
}), argKeys;
|
|
78
60
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
(value) => t.isObjectProperty(value) && t.isIdentifier(value.key) ? [value.key.name] : []
|
|
83
|
-
) : [];
|
|
84
|
-
}, "getObjectExpressionKeys");
|
|
61
|
+
var getObjectExpressionKeys = (node) => t.isObjectExpression(node) ? node.properties.flatMap(
|
|
62
|
+
(value) => t.isObjectProperty(value) && t.isIdentifier(value.key) ? [value.key.name] : []
|
|
63
|
+
) : [];
|
|
85
64
|
async function transform(info) {
|
|
86
|
-
|
|
87
|
-
const fileNode = csf._ast;
|
|
88
|
-
const file = new babel.File(
|
|
65
|
+
let csf = loadCsf(info.source, { makeTitle: (title) => title }), fileNode = csf._ast, file = new babel.File(
|
|
89
66
|
{ filename: info.path },
|
|
90
67
|
{ code: info.source, ast: fileNode }
|
|
91
68
|
);
|
|
92
69
|
csf.parse();
|
|
93
|
-
|
|
70
|
+
let metaKeys = [
|
|
94
71
|
...getObjectExpressionKeys(csf._metaAnnotations.args),
|
|
95
72
|
...getObjectExpressionKeys(csf._metaAnnotations.argTypes)
|
|
96
73
|
];
|
|
97
74
|
Object.values(csf.stories).forEach(({ name }) => {
|
|
98
|
-
if (!name)
|
|
75
|
+
if (!name)
|
|
99
76
|
return;
|
|
100
|
-
|
|
101
|
-
const allKeys = [
|
|
77
|
+
let allKeys = [
|
|
102
78
|
...metaKeys,
|
|
103
79
|
...getAnnotationKeys(file, name, "args"),
|
|
104
80
|
...getAnnotationKeys(file, name, "argTypes")
|
|
105
81
|
];
|
|
106
82
|
file.path.traverse({
|
|
107
83
|
// CSF2 play function Story.play =
|
|
108
|
-
AssignmentExpression:
|
|
109
|
-
|
|
110
|
-
if (!left.isMemberExpression())
|
|
84
|
+
AssignmentExpression: (path) => {
|
|
85
|
+
let left = path.get("left");
|
|
86
|
+
if (!left.isMemberExpression())
|
|
111
87
|
return;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (!(object.isIdentifier() && object.node.name === name)) {
|
|
88
|
+
let object = left.get("object");
|
|
89
|
+
if (!(object.isIdentifier() && object.node.name === name))
|
|
115
90
|
return;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
findImplicitSpies(path, info.path, allKeys);
|
|
120
|
-
}
|
|
121
|
-
}, "AssignmentExpression"),
|
|
91
|
+
let property = left.get("property");
|
|
92
|
+
property.isIdentifier() && property.node.name === "play" && findImplicitSpies(path, info.path, allKeys);
|
|
93
|
+
},
|
|
122
94
|
// CSF3 play function: const Story = {play: () => {} };
|
|
123
|
-
VariableDeclarator:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (!(id.isIdentifier() && id.node.name === name) || !init.isObjectExpression()) {
|
|
95
|
+
VariableDeclarator: (path) => {
|
|
96
|
+
let id = path.get("id"), init = path.get("init");
|
|
97
|
+
if (!(id.isIdentifier() && id.node.name === name) || !init.isObjectExpression())
|
|
127
98
|
return;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const argKey = it.get("key");
|
|
99
|
+
let play = init.get("properties").flatMap((it) => it.isObjectProperty() ? [it] : []).find((it) => {
|
|
100
|
+
let argKey = it.get("key");
|
|
131
101
|
return argKey.isIdentifier() && argKey.node.name === "play";
|
|
132
102
|
});
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
}, "VariableDeclarator")
|
|
103
|
+
play && findImplicitSpies(play, info.path, allKeys);
|
|
104
|
+
}
|
|
137
105
|
});
|
|
138
106
|
});
|
|
139
|
-
return;
|
|
140
107
|
}
|
|
141
|
-
__name(transform, "transform");
|
|
142
108
|
var parser = "tsx";
|
|
143
109
|
export {
|
|
144
110
|
transform as default,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import CJS_COMPAT_NODE_URL_e0f36cf893t from 'node:url';
|
|
2
|
+
import CJS_COMPAT_NODE_PATH_e0f36cf893t from 'node:path';
|
|
3
|
+
import CJS_COMPAT_NODE_MODULE_e0f36cf893t from "node:module";
|
|
4
4
|
|
|
5
|
-
var __filename =
|
|
6
|
-
var __dirname =
|
|
7
|
-
var require =
|
|
5
|
+
var __filename = CJS_COMPAT_NODE_URL_e0f36cf893t.fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = CJS_COMPAT_NODE_PATH_e0f36cf893t.dirname(__filename);
|
|
7
|
+
var require = CJS_COMPAT_NODE_MODULE_e0f36cf893t.createRequire(import.meta.url);
|
|
8
8
|
|
|
9
9
|
// ------------------------------------------------------------
|
|
10
10
|
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
|
|
@@ -13,8 +13,7 @@ import {
|
|
|
13
13
|
parser,
|
|
14
14
|
transform,
|
|
15
15
|
upgradeDeprecatedTypes
|
|
16
|
-
} from "../_node-chunks/chunk-
|
|
17
|
-
import "../_node-chunks/chunk-YPRP2XJX.js";
|
|
16
|
+
} from "../_node-chunks/chunk-LOEXTO7E.js";
|
|
18
17
|
export {
|
|
19
18
|
transform as default,
|
|
20
19
|
parser,
|
|
@@ -1,44 +1,32 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import CJS_COMPAT_NODE_URL_e0f36cf893t from 'node:url';
|
|
2
|
+
import CJS_COMPAT_NODE_PATH_e0f36cf893t from 'node:path';
|
|
3
|
+
import CJS_COMPAT_NODE_MODULE_e0f36cf893t from "node:module";
|
|
4
4
|
|
|
5
|
-
var __filename =
|
|
6
|
-
var __dirname =
|
|
7
|
-
var require =
|
|
5
|
+
var __filename = CJS_COMPAT_NODE_URL_e0f36cf893t.fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = CJS_COMPAT_NODE_PATH_e0f36cf893t.dirname(__filename);
|
|
7
|
+
var require = CJS_COMPAT_NODE_MODULE_e0f36cf893t.createRequire(import.meta.url);
|
|
8
8
|
|
|
9
9
|
// ------------------------------------------------------------
|
|
10
10
|
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
|
|
11
11
|
// ------------------------------------------------------------
|
|
12
|
-
import {
|
|
13
|
-
__name
|
|
14
|
-
} from "../_node-chunks/chunk-YPRP2XJX.js";
|
|
15
12
|
|
|
16
13
|
// src/transforms/upgrade-hierarchy-separators.js
|
|
17
14
|
function upgradeSeparator(path) {
|
|
18
15
|
return path.replace(/[|.]/g, "/");
|
|
19
16
|
}
|
|
20
|
-
__name(upgradeSeparator, "upgradeSeparator");
|
|
21
17
|
function transformer(file, api, options) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
root.find(j.CallExpression).filter((call) => call.node.callee.name === "storiesOf").filter(
|
|
18
|
+
let j = api.jscodeshift, root = j(file.source);
|
|
19
|
+
return root.find(j.CallExpression).filter((call) => call.node.callee.name === "storiesOf").filter(
|
|
25
20
|
(call) => call.node.arguments.length > 0 && ["Literal", "StringLiteral"].includes(call.node.arguments[0].type)
|
|
26
21
|
).forEach((call) => {
|
|
27
|
-
|
|
22
|
+
let arg0 = call.node.arguments[0];
|
|
28
23
|
arg0.value = upgradeSeparator(arg0.value);
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
p.value.value = upgradeSeparator(p.value.value);
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
return root.toSource({ quote: "single" });
|
|
24
|
+
}), root.find(j.ExportDefaultDeclaration).filter((def) => def.node.declaration.properties.map((p) => p.key.name).includes("title")).forEach((def) => {
|
|
25
|
+
def.node.declaration && def.node.declaration.properties && def.node.declaration.properties.forEach((p) => {
|
|
26
|
+
p.key.name === "title" && (p.value.value = upgradeSeparator(p.value.value));
|
|
27
|
+
});
|
|
28
|
+
}), root.toSource({ quote: "single" });
|
|
40
29
|
}
|
|
41
|
-
__name(transformer, "transformer");
|
|
42
30
|
export {
|
|
43
31
|
transformer as default
|
|
44
32
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybook/codemod",
|
|
3
|
-
"version": "10.1.0-alpha.
|
|
3
|
+
"version": "10.1.0-alpha.11",
|
|
4
4
|
"description": "A collection of codemod scripts written with JSCodeshift",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storybook"
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"es-toolkit": "^1.36.0",
|
|
50
50
|
"jscodeshift": "^0.15.1",
|
|
51
51
|
"prettier": "^3.5.3",
|
|
52
|
-
"storybook": "10.1.0-alpha.
|
|
52
|
+
"storybook": "10.1.0-alpha.11",
|
|
53
53
|
"tiny-invariant": "^1.3.1",
|
|
54
54
|
"tinyglobby": "^0.2.13"
|
|
55
55
|
},
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"publishConfig": {
|
|
63
63
|
"access": "public"
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae1l"
|
|
66
66
|
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import CJS_COMPAT_NODE_URL_u4jf23wcd5 from 'node:url';
|
|
2
|
-
import CJS_COMPAT_NODE_PATH_u4jf23wcd5 from 'node:path';
|
|
3
|
-
import CJS_COMPAT_NODE_MODULE_u4jf23wcd5 from "node:module";
|
|
4
|
-
|
|
5
|
-
var __filename = CJS_COMPAT_NODE_URL_u4jf23wcd5.fileURLToPath(import.meta.url);
|
|
6
|
-
var __dirname = CJS_COMPAT_NODE_PATH_u4jf23wcd5.dirname(__filename);
|
|
7
|
-
var require = CJS_COMPAT_NODE_MODULE_u4jf23wcd5.createRequire(import.meta.url);
|
|
8
|
-
|
|
9
|
-
// ------------------------------------------------------------
|
|
10
|
-
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
|
|
11
|
-
// ------------------------------------------------------------
|
|
12
|
-
var __defProp = Object.defineProperty;
|
|
13
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
14
|
-
|
|
15
|
-
export {
|
|
16
|
-
__name
|
|
17
|
-
};
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import CJS_COMPAT_NODE_URL_u4jf23wcd5 from 'node:url';
|
|
2
|
-
import CJS_COMPAT_NODE_PATH_u4jf23wcd5 from 'node:path';
|
|
3
|
-
import CJS_COMPAT_NODE_MODULE_u4jf23wcd5 from "node:module";
|
|
4
|
-
|
|
5
|
-
var __filename = CJS_COMPAT_NODE_URL_u4jf23wcd5.fileURLToPath(import.meta.url);
|
|
6
|
-
var __dirname = CJS_COMPAT_NODE_PATH_u4jf23wcd5.dirname(__filename);
|
|
7
|
-
var require = CJS_COMPAT_NODE_MODULE_u4jf23wcd5.createRequire(import.meta.url);
|
|
8
|
-
|
|
9
|
-
// ------------------------------------------------------------
|
|
10
|
-
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
|
|
11
|
-
// ------------------------------------------------------------
|
|
12
|
-
import {
|
|
13
|
-
__name
|
|
14
|
-
} from "./chunk-YPRP2XJX.js";
|
|
15
|
-
|
|
16
|
-
// src/transforms/upgrade-deprecated-types.ts
|
|
17
|
-
import { core as babel, types as t } from "storybook/internal/babel";
|
|
18
|
-
import { loadCsf, printCsf } from "storybook/internal/csf-tools";
|
|
19
|
-
import { logger } from "storybook/internal/node-logger";
|
|
20
|
-
import prettier from "prettier";
|
|
21
|
-
var deprecatedTypes = [
|
|
22
|
-
"ComponentStory",
|
|
23
|
-
"ComponentStoryFn",
|
|
24
|
-
"ComponentStoryObj",
|
|
25
|
-
"ComponentMeta",
|
|
26
|
-
"Story"
|
|
27
|
-
];
|
|
28
|
-
function migrateType(oldType) {
|
|
29
|
-
if (oldType === "Story" || oldType === "ComponentStory") {
|
|
30
|
-
return "StoryFn";
|
|
31
|
-
}
|
|
32
|
-
return oldType.replace("Component", "");
|
|
33
|
-
}
|
|
34
|
-
__name(migrateType, "migrateType");
|
|
35
|
-
async function transform(info, api, options) {
|
|
36
|
-
const csf = loadCsf(info.source, { makeTitle: /* @__PURE__ */ __name((title) => title, "makeTitle") });
|
|
37
|
-
const fileNode = csf._ast;
|
|
38
|
-
const file = new babel.File(
|
|
39
|
-
{ filename: info.path },
|
|
40
|
-
{ code: info.source, ast: fileNode }
|
|
41
|
-
);
|
|
42
|
-
upgradeDeprecatedTypes(file);
|
|
43
|
-
let output = printCsf(csf).code;
|
|
44
|
-
try {
|
|
45
|
-
output = await prettier.format(output, {
|
|
46
|
-
...await prettier.resolveConfig(info.path),
|
|
47
|
-
filepath: info.path
|
|
48
|
-
});
|
|
49
|
-
} catch (e) {
|
|
50
|
-
logger.log(`Failed applying prettier to ${info.path}.`);
|
|
51
|
-
}
|
|
52
|
-
return output;
|
|
53
|
-
}
|
|
54
|
-
__name(transform, "transform");
|
|
55
|
-
var parser = "tsx";
|
|
56
|
-
function upgradeDeprecatedTypes(file) {
|
|
57
|
-
const importedNamespaces = /* @__PURE__ */ new Set();
|
|
58
|
-
const typeReferencesToUpdate = /* @__PURE__ */ new Set();
|
|
59
|
-
const existingImports = [];
|
|
60
|
-
file.path.traverse({
|
|
61
|
-
ImportDeclaration: /* @__PURE__ */ __name((path) => {
|
|
62
|
-
existingImports.push(
|
|
63
|
-
...path.get("specifiers").map((specifier) => ({
|
|
64
|
-
name: specifier.node.local.name,
|
|
65
|
-
isAlias: !(specifier.isImportSpecifier() && t.isIdentifier(specifier.node.imported) && specifier.node.local.name === specifier.node.imported.name),
|
|
66
|
-
path: specifier
|
|
67
|
-
}))
|
|
68
|
-
);
|
|
69
|
-
const source = path.node.source.value;
|
|
70
|
-
if (!source.startsWith("@storybook")) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
path.get("specifiers").forEach((specifier) => {
|
|
74
|
-
if (specifier.isImportNamespaceSpecifier()) {
|
|
75
|
-
importedNamespaces.add(specifier.node.local.name);
|
|
76
|
-
}
|
|
77
|
-
if (!specifier.isImportSpecifier()) {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
const imported = specifier.get("imported");
|
|
81
|
-
if (!imported.isIdentifier()) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (deprecatedTypes.includes(imported.node.name)) {
|
|
85
|
-
if (imported.node.name === specifier.node.local.name) {
|
|
86
|
-
typeReferencesToUpdate.add(specifier.node.local.name);
|
|
87
|
-
}
|
|
88
|
-
const newType = migrateType(imported.node.name);
|
|
89
|
-
if (!existingImports.some((it) => it.name === newType)) {
|
|
90
|
-
imported.replaceWith(t.identifier(newType));
|
|
91
|
-
existingImports.push({ name: newType, isAlias: false, path: specifier });
|
|
92
|
-
} else {
|
|
93
|
-
const existingImport = existingImports.find((it) => it.name === newType && it.isAlias);
|
|
94
|
-
if (existingImport) {
|
|
95
|
-
throw existingImport.path.buildCodeFrameError(
|
|
96
|
-
"This codemod does not support local imports that are called the same as a storybook import.\nRename this local import and try again."
|
|
97
|
-
);
|
|
98
|
-
} else {
|
|
99
|
-
specifier.remove();
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
}, "ImportDeclaration")
|
|
105
|
-
});
|
|
106
|
-
file.path.traverse({
|
|
107
|
-
TSTypeReference: /* @__PURE__ */ __name((path) => {
|
|
108
|
-
const typeName = path.get("typeName");
|
|
109
|
-
if (typeName.isIdentifier()) {
|
|
110
|
-
if (typeReferencesToUpdate.has(typeName.node.name)) {
|
|
111
|
-
typeName.replaceWith(t.identifier(migrateType(typeName.node.name)));
|
|
112
|
-
}
|
|
113
|
-
} else if (typeName.isTSQualifiedName()) {
|
|
114
|
-
const namespace = typeName.get("left");
|
|
115
|
-
if (namespace.isIdentifier()) {
|
|
116
|
-
if (importedNamespaces.has(namespace.node.name)) {
|
|
117
|
-
const right = typeName.get("right");
|
|
118
|
-
if (deprecatedTypes.includes(right.node.name)) {
|
|
119
|
-
right.replaceWith(t.identifier(migrateType(right.node.name)));
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}, "TSTypeReference")
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
__name(upgradeDeprecatedTypes, "upgradeDeprecatedTypes");
|
|
128
|
-
|
|
129
|
-
export {
|
|
130
|
-
transform,
|
|
131
|
-
parser,
|
|
132
|
-
upgradeDeprecatedTypes
|
|
133
|
-
};
|