@nx/storybook 16.10.0 → 17.0.0-beta.2
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/migrations.json +0 -171
- package/package.json +6 -7
- package/src/executors/build-storybook/build-storybook.impl.d.ts +1 -2
- package/src/executors/build-storybook/build-storybook.impl.js +13 -47
- package/src/executors/build-storybook/schema.json +0 -13
- package/src/executors/storybook/storybook.impl.d.ts +1 -2
- package/src/executors/storybook/storybook.impl.js +18 -45
- package/src/generators/configuration/configuration.js +1 -1
- package/src/generators/configuration/lib/util-functions.d.ts +6 -7
- package/src/generators/configuration/lib/util-functions.js +3 -11
- package/src/generators/configuration/schema.d.ts +2 -2
- package/src/generators/init/init.js +5 -12
- package/src/generators/init/schema.d.ts +2 -2
- package/src/generators/migrate-7/schema.d.ts +0 -2
- package/src/utils/models.d.ts +1 -4
- package/src/utils/utilities.js +3 -2
- package/src/executors/utils.d.ts +0 -6
- package/src/executors/utils.js +0 -132
- package/src/migrations/update-13-4-6/set-project-build-config.d.ts +0 -2
- package/src/migrations/update-13-4-6/set-project-build-config.js +0 -56
- package/src/migrations/update-14-0-0/migrate-defaults-5-to-6/migrate-defaults-5-to-6.d.ts +0 -6
- package/src/migrations/update-14-0-0/migrate-defaults-5-to-6/migrate-defaults-5-to-6.js +0 -117
- package/src/migrations/update-14-0-0/migrate-stories-to-6-2/migrate-stories-to-6-2.d.ts +0 -8
- package/src/migrations/update-14-0-0/migrate-stories-to-6-2/migrate-stories-to-6-2.js +0 -316
- package/src/migrations/update-14-0-0/migrate-to-storybook-6.d.ts +0 -2
- package/src/migrations/update-14-0-0/migrate-to-storybook-6.js +0 -9
- package/src/migrations/update-14-1-8/change-storybook-targets-generator.d.ts +0 -4
- package/src/migrations/update-14-1-8/change-storybook-targets-generator.js +0 -104
- package/src/migrations/update-14-1-8/change-storybook-targets.d.ts +0 -2
- package/src/migrations/update-14-1-8/change-storybook-targets.js +0 -7
- package/src/utils/test-configs/.storybook/main.js +0 -8
- package/src/utils/test-configs/.storybook/tsconfig.json +0 -19
package/src/executors/utils.js
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// TODO(katerina): Remove Nx17 - DELETE whole file
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.builderIsWebpackButNotWebpack5 = exports.runStorybookSetupCheck = exports.getStorybookFrameworkPath = void 0;
|
|
5
|
-
const devkit_1 = require("@nx/devkit");
|
|
6
|
-
const js_1 = require("@nx/js");
|
|
7
|
-
const fs_1 = require("fs");
|
|
8
|
-
const path_1 = require("path");
|
|
9
|
-
const semver_1 = require("semver");
|
|
10
|
-
const ts = require("typescript");
|
|
11
|
-
function getStorybookFrameworkPath(uiFramework) {
|
|
12
|
-
const serverOptionsPaths = {
|
|
13
|
-
'@storybook/react': '@storybook/react/dist/cjs/server/options',
|
|
14
|
-
'@storybook/html': '@storybook/html/dist/cjs/server/options',
|
|
15
|
-
'@storybook/vue': '@storybook/vue/dist/cjs/server/options',
|
|
16
|
-
'@storybook/vue3': '@storybook/vue3/dist/cjs/server/options',
|
|
17
|
-
'@storybook/web-components': '@storybook/web-components/dist/cjs/server/options',
|
|
18
|
-
'@storybook/svelte': '@storybook/svelte/dist/cjs/server/options',
|
|
19
|
-
};
|
|
20
|
-
if (isStorybookV62onwards(uiFramework)) {
|
|
21
|
-
return serverOptionsPaths[uiFramework];
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
return `${uiFramework}/dist/server/options`;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
exports.getStorybookFrameworkPath = getStorybookFrameworkPath;
|
|
28
|
-
function isStorybookV62onwards(uiFramework) {
|
|
29
|
-
try {
|
|
30
|
-
const storybookPackageVersion = require((0, path_1.join)(uiFramework, 'package.json')).version;
|
|
31
|
-
return (0, semver_1.gte)(storybookPackageVersion, '6.2.0-rc.4');
|
|
32
|
-
}
|
|
33
|
-
catch (e) {
|
|
34
|
-
try {
|
|
35
|
-
const storybookPackageVersion = require((0, path_1.join)('@storybook/core-server', 'package.json')).version;
|
|
36
|
-
return (0, semver_1.gte)(storybookPackageVersion, '6.2.0-rc.4');
|
|
37
|
-
}
|
|
38
|
-
catch (e) {
|
|
39
|
-
throw new Error(`Error: ${e}
|
|
40
|
-
|
|
41
|
-
It looks like you don\'t have Storybook installed.
|
|
42
|
-
Please run the @nx/storybook:configuration generator,
|
|
43
|
-
or run "npm/yarn" again to install your dependencies.`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
function runStorybookSetupCheck(options) {
|
|
48
|
-
webpackFinalPropertyCheck(options);
|
|
49
|
-
reactWebpack5Check(options);
|
|
50
|
-
}
|
|
51
|
-
exports.runStorybookSetupCheck = runStorybookSetupCheck;
|
|
52
|
-
function reactWebpack5Check(options) {
|
|
53
|
-
if (options.uiFramework === '@storybook/react') {
|
|
54
|
-
const source = mainJsTsFileContent(options.configDir);
|
|
55
|
-
const rootSource = mainJsTsFileContent('.storybook');
|
|
56
|
-
// check whether the current Storybook configuration has the webpack 5 builder enabled
|
|
57
|
-
if (builderIsWebpackButNotWebpack5(source) &&
|
|
58
|
-
builderIsWebpackButNotWebpack5(rootSource)) {
|
|
59
|
-
devkit_1.logger.warn(`
|
|
60
|
-
It looks like you use Webpack 5 but your Storybook setup is not configured to leverage that
|
|
61
|
-
and thus falls back to Webpack 4.
|
|
62
|
-
Make sure you upgrade your Storybook config to use Webpack 5.
|
|
63
|
-
|
|
64
|
-
- https://gist.github.com/shilman/8856ea1786dcd247139b47b270912324#upgrade
|
|
65
|
-
|
|
66
|
-
`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
function mainJsTsFileContent(configFolder) {
|
|
71
|
-
let storybookConfigFilePath = (0, devkit_1.joinPathFragments)(configFolder, 'main.js');
|
|
72
|
-
if (!(0, fs_1.existsSync)(storybookConfigFilePath)) {
|
|
73
|
-
storybookConfigFilePath = (0, devkit_1.joinPathFragments)(configFolder, 'main.ts');
|
|
74
|
-
}
|
|
75
|
-
if (!(0, fs_1.existsSync)(storybookConfigFilePath)) {
|
|
76
|
-
// looks like there's no main config file, so skip
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
const storybookConfig = (0, fs_1.readFileSync)(storybookConfigFilePath, {
|
|
80
|
-
encoding: 'utf8',
|
|
81
|
-
});
|
|
82
|
-
return ts.createSourceFile(storybookConfigFilePath, storybookConfig, ts.ScriptTarget.Latest, true);
|
|
83
|
-
}
|
|
84
|
-
function webpackFinalPropertyCheck(options) {
|
|
85
|
-
let placesToCheck = [
|
|
86
|
-
{
|
|
87
|
-
path: (0, devkit_1.joinPathFragments)('.storybook', 'webpack.config.js'),
|
|
88
|
-
result: false,
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
path: (0, devkit_1.joinPathFragments)(options.configDir, 'webpack.config.js'),
|
|
92
|
-
result: false,
|
|
93
|
-
},
|
|
94
|
-
];
|
|
95
|
-
placesToCheck = placesToCheck
|
|
96
|
-
.map((entry) => {
|
|
97
|
-
return {
|
|
98
|
-
...entry,
|
|
99
|
-
result: (0, fs_1.existsSync)(entry.path),
|
|
100
|
-
};
|
|
101
|
-
})
|
|
102
|
-
.filter((x) => x.result === true);
|
|
103
|
-
if (placesToCheck.length > 0) {
|
|
104
|
-
devkit_1.logger.warn(`
|
|
105
|
-
You have a webpack.config.js files in your Storybook configuration:
|
|
106
|
-
${placesToCheck.map((x) => `- "${x.path}"`).join('\n ')}
|
|
107
|
-
|
|
108
|
-
Consider switching to the "webpackFinal" property declared in "main.js" (or "main.ts") instead.
|
|
109
|
-
${options.uiFramework === '@storybook/react'
|
|
110
|
-
? 'https://nx.dev/storybook/migrate-webpack-final-react'
|
|
111
|
-
: 'https://nx.dev/storybook/migrate-webpack-final-angular'}
|
|
112
|
-
`);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
function builderIsWebpackButNotWebpack5(storybookConfig) {
|
|
116
|
-
const importArray = (0, js_1.findNodes)(storybookConfig, [
|
|
117
|
-
ts.SyntaxKind.PropertyAssignment,
|
|
118
|
-
]);
|
|
119
|
-
let builderIsWebpackNot5 = false;
|
|
120
|
-
importArray.forEach((parent) => {
|
|
121
|
-
const identifier = (0, js_1.findNodes)(parent, ts.SyntaxKind.Identifier);
|
|
122
|
-
const sbBuilder = (0, js_1.findNodes)(parent, ts.SyntaxKind.StringLiteral);
|
|
123
|
-
const builderText = sbBuilder?.[0]?.getText() ?? '';
|
|
124
|
-
if (identifier?.[0]?.getText() === 'builder' &&
|
|
125
|
-
builderText.includes('webpack') &&
|
|
126
|
-
!builderText.includes('webpack5')) {
|
|
127
|
-
builderIsWebpackNot5 = true;
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
return builderIsWebpackNot5;
|
|
131
|
-
}
|
|
132
|
-
exports.builderIsWebpackButNotWebpack5 = builderIsWebpackButNotWebpack5;
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const devkit_1 = require("@nx/devkit");
|
|
4
|
-
const utilities_1 = require("../../utils/utilities");
|
|
5
|
-
async function setProjectBuildConfig(tree) {
|
|
6
|
-
let changesMade = false;
|
|
7
|
-
const projects = (0, devkit_1.getProjects)(tree);
|
|
8
|
-
[...projects.entries()].forEach(([projectName, projectConfiguration]) => {
|
|
9
|
-
if (!projectConfiguration.targets) {
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
const { storybookBuildTarget, storybookTarget, ngBuildTarget } = (0, utilities_1.findStorybookAndBuildTargetsAndCompiler)(projectConfiguration.targets);
|
|
13
|
-
if (projectName &&
|
|
14
|
-
storybookTarget &&
|
|
15
|
-
projectConfiguration?.targets?.[storybookTarget]?.options?.uiFramework ===
|
|
16
|
-
'@storybook/angular') {
|
|
17
|
-
if (ngBuildTarget) {
|
|
18
|
-
if (!projectConfiguration.targets[storybookTarget].options
|
|
19
|
-
.projectBuildConfig) {
|
|
20
|
-
projectConfiguration.targets[storybookTarget].options.projectBuildConfig = projectName;
|
|
21
|
-
changesMade = true;
|
|
22
|
-
}
|
|
23
|
-
if (storybookBuildTarget &&
|
|
24
|
-
!projectConfiguration.targets[storybookBuildTarget].options
|
|
25
|
-
.projectBuildConfig) {
|
|
26
|
-
projectConfiguration.targets[storybookBuildTarget].options.projectBuildConfig = projectName;
|
|
27
|
-
changesMade = true;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
if (storybookBuildTarget) {
|
|
32
|
-
if (!projectConfiguration.targets[storybookTarget].options
|
|
33
|
-
.projectBuildConfig) {
|
|
34
|
-
projectConfiguration.targets[storybookTarget].options.projectBuildConfig = `${projectName}:${storybookBuildTarget}`;
|
|
35
|
-
changesMade = true;
|
|
36
|
-
}
|
|
37
|
-
if (!projectConfiguration.targets[storybookBuildTarget].options
|
|
38
|
-
.projectBuildConfig) {
|
|
39
|
-
projectConfiguration.targets[storybookBuildTarget].options.projectBuildConfig = `${projectName}:${storybookBuildTarget}`;
|
|
40
|
-
changesMade = true;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
devkit_1.logger.warn(`Could not find a build target for ${projectName}.`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
if (changesMade) {
|
|
48
|
-
(0, devkit_1.updateProjectConfiguration)(tree, projectName, projectConfiguration);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
if (changesMade) {
|
|
53
|
-
await (0, devkit_1.formatFiles)(tree);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
exports.default = setProjectBuildConfig;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { GeneratorCallback, Tree } from '@nx/devkit';
|
|
2
|
-
import { StorybookConfigureSchema } from '../../../generators/configuration/schema';
|
|
3
|
-
export declare function migrateDefaultsGenerator(tree: Tree): GeneratorCallback;
|
|
4
|
-
export declare function migrateAllStorybookInstances(tree: Tree): void;
|
|
5
|
-
export declare function migrateStorybookInstance(tree: Tree, projectName: string, uiFramework: StorybookConfigureSchema['uiFramework'], configFolder?: string): void;
|
|
6
|
-
export declare function moveDirectory(tree: Tree, from: string, to: string): void;
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.moveDirectory = exports.migrateStorybookInstance = exports.migrateAllStorybookInstances = exports.migrateDefaultsGenerator = void 0;
|
|
4
|
-
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
const semver_1 = require("semver");
|
|
6
|
-
const semver_2 = require("@nx/devkit/src/utils/semver");
|
|
7
|
-
const versions_1 = require("../../../utils/versions");
|
|
8
|
-
const util_functions_1 = require("../../../generators/configuration/lib/util-functions");
|
|
9
|
-
const utilities_1 = require("../../../utils/utilities");
|
|
10
|
-
function migrateDefaultsGenerator(tree) {
|
|
11
|
-
migrateAllStorybookInstances(tree);
|
|
12
|
-
return upgradeStorybookPackagesInPackageJson(tree);
|
|
13
|
-
}
|
|
14
|
-
exports.migrateDefaultsGenerator = migrateDefaultsGenerator;
|
|
15
|
-
function migrateAllStorybookInstances(tree) {
|
|
16
|
-
devkit_1.logger.debug('adding .storybook folder to project');
|
|
17
|
-
const projects = (0, devkit_1.getProjects)(tree);
|
|
18
|
-
const projectsThatHaveStorybookConfiguration = [...projects.entries()]
|
|
19
|
-
.filter(([_, projectConfig]) => projectConfig?.targets?.storybook &&
|
|
20
|
-
projectConfig?.targets?.storybook?.executor !==
|
|
21
|
-
'@nrwl/react-native:storybook')
|
|
22
|
-
.map(([projectName, projectConfig]) => {
|
|
23
|
-
return {
|
|
24
|
-
name: projectName,
|
|
25
|
-
uiFramework: projectConfig?.targets?.storybook?.options?.uiFramework,
|
|
26
|
-
configFolder: projectConfig?.targets?.storybook?.options?.config?.configFolder ??
|
|
27
|
-
'',
|
|
28
|
-
};
|
|
29
|
-
});
|
|
30
|
-
for (const projectWithStorybook of projectsThatHaveStorybookConfiguration) {
|
|
31
|
-
migrateStorybookInstance(tree, projectWithStorybook.name, projectWithStorybook.uiFramework, projectWithStorybook.configFolder);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
exports.migrateAllStorybookInstances = migrateAllStorybookInstances;
|
|
35
|
-
function migrateStorybookInstance(tree, projectName, uiFramework, configFolder) {
|
|
36
|
-
migrateProjectLevelStorybookInstance(tree, projectName, uiFramework, configFolder);
|
|
37
|
-
}
|
|
38
|
-
exports.migrateStorybookInstance = migrateStorybookInstance;
|
|
39
|
-
function maybeUpdateVersion(tree) {
|
|
40
|
-
let needsInstall = false;
|
|
41
|
-
(0, devkit_1.updateJson)(tree, 'package.json', (json) => {
|
|
42
|
-
const ignoredStorybookPackages = [
|
|
43
|
-
'@storybook/builder-vite',
|
|
44
|
-
'@storybook/jest',
|
|
45
|
-
'@storybook/react-native',
|
|
46
|
-
'@storybook/storybook-deployer',
|
|
47
|
-
'@storybook/test-runner',
|
|
48
|
-
'@storybook/testing-library',
|
|
49
|
-
'@storybook/testing-angular',
|
|
50
|
-
'@storybook/testing-react',
|
|
51
|
-
'@storybook/testing-vue',
|
|
52
|
-
'@storybook/testing-vue3',
|
|
53
|
-
'@storybook/addon-notes',
|
|
54
|
-
'@storybook/addon-postcss',
|
|
55
|
-
];
|
|
56
|
-
json.dependencies = json.dependencies || {};
|
|
57
|
-
json.devDependencies = json.devDependencies || {};
|
|
58
|
-
const allStorybookPackagesInDependencies = Object.keys(json.dependencies).filter((packageName) => packageName.startsWith('@storybook/') &&
|
|
59
|
-
!ignoredStorybookPackages.includes(packageName));
|
|
60
|
-
const allStorybookPackagesInDevDependencies = Object.keys(json.devDependencies).filter((packageName) => packageName.startsWith('@storybook/') &&
|
|
61
|
-
!ignoredStorybookPackages.includes(packageName));
|
|
62
|
-
const storybookPackages = [
|
|
63
|
-
...allStorybookPackagesInDependencies,
|
|
64
|
-
...allStorybookPackagesInDevDependencies,
|
|
65
|
-
];
|
|
66
|
-
storybookPackages.forEach((storybookPackageName) => {
|
|
67
|
-
if (json.dependencies[storybookPackageName]) {
|
|
68
|
-
const version = (0, semver_2.checkAndCleanWithSemver)(storybookPackageName, json.dependencies[storybookPackageName]);
|
|
69
|
-
if ((0, semver_1.lte)(version, '6.0.0')) {
|
|
70
|
-
json.dependencies[storybookPackageName] = versions_1.storybookVersion;
|
|
71
|
-
needsInstall = true;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
if (json.devDependencies[storybookPackageName]) {
|
|
75
|
-
const version = (0, semver_2.checkAndCleanWithSemver)(storybookPackageName, json.devDependencies[storybookPackageName]);
|
|
76
|
-
if ((0, semver_1.lte)(version, '6.0.0')) {
|
|
77
|
-
json.devDependencies[storybookPackageName] = versions_1.storybookVersion;
|
|
78
|
-
needsInstall = true;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
return json;
|
|
83
|
-
});
|
|
84
|
-
if (needsInstall) {
|
|
85
|
-
return () => (0, devkit_1.installPackagesTask)(tree);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
function upgradeStorybookPackagesInPackageJson(tree) {
|
|
89
|
-
/**
|
|
90
|
-
* Should upgrade all @storybook/* packages in package.json
|
|
91
|
-
*/
|
|
92
|
-
return maybeUpdateVersion(tree);
|
|
93
|
-
}
|
|
94
|
-
function moveOldFiles(tree, configFolderDir) {
|
|
95
|
-
moveDirectory(tree, configFolderDir, configFolderDir.replace('.storybook', '.old_storybook'));
|
|
96
|
-
}
|
|
97
|
-
function migrateProjectLevelStorybookInstance(tree, projectName, uiFramework, configFolder) {
|
|
98
|
-
const old_folder_exists_already = tree.exists(configFolder?.replace('.storybook', '.old_storybook'));
|
|
99
|
-
const new_config_exists_already = tree.exists(`${configFolder}/main.js`);
|
|
100
|
-
if (old_folder_exists_already || new_config_exists_already) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
moveOldFiles(tree, configFolder);
|
|
104
|
-
if (tree.exists(configFolder)) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
const { projectType, targets, root } = (0, devkit_1.readProjectConfiguration)(tree, projectName);
|
|
108
|
-
const { nextBuildTarget, compiler } = (0, utilities_1.findStorybookAndBuildTargetsAndCompiler)(targets);
|
|
109
|
-
const mainDir = !!nextBuildTarget && projectType === 'application' ? 'components' : 'src';
|
|
110
|
-
(0, util_functions_1.createProjectStorybookDir)(tree, projectName, uiFramework, false, false, root, projectType, false, false, mainDir, !!nextBuildTarget, compiler === 'swc');
|
|
111
|
-
}
|
|
112
|
-
function moveDirectory(tree, from, to) {
|
|
113
|
-
(0, devkit_1.visitNotIgnoredFiles)(tree, from, (file) => {
|
|
114
|
-
tree.rename(file, file.replace(from, to));
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
exports.moveDirectory = moveDirectory;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Tree } from '@nx/devkit';
|
|
2
|
-
export declare function migrateStoriesTo62Generator(tree: Tree): Promise<void>;
|
|
3
|
-
export declare function findAllAngularProjectsWithStorybookConfiguration(tree: Tree): {
|
|
4
|
-
name: string;
|
|
5
|
-
configFolder: string;
|
|
6
|
-
projectRoot: string;
|
|
7
|
-
projectSrc: string;
|
|
8
|
-
}[];
|
|
@@ -1,316 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.findAllAngularProjectsWithStorybookConfiguration = exports.migrateStoriesTo62Generator = void 0;
|
|
4
|
-
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
const fileutils_1 = require("@nx/workspace/src/utilities/fileutils");
|
|
6
|
-
const js_1 = require("@nx/js");
|
|
7
|
-
const path_1 = require("path");
|
|
8
|
-
const typescript_1 = require("typescript");
|
|
9
|
-
const utilities_1 = require("../../../utils/utilities");
|
|
10
|
-
const ts = require("typescript");
|
|
11
|
-
async function migrateStoriesTo62Generator(tree) {
|
|
12
|
-
let allComponentsWithStories = [];
|
|
13
|
-
const result = findAllAngularProjectsWithStorybookConfiguration(tree);
|
|
14
|
-
result?.forEach((angularProjectWithStorybook) => {
|
|
15
|
-
const componentResult = findAllComponentsWithStoriesForSpecificProject(tree, angularProjectWithStorybook.projectRoot);
|
|
16
|
-
allComponentsWithStories = [
|
|
17
|
-
...allComponentsWithStories,
|
|
18
|
-
...componentResult,
|
|
19
|
-
];
|
|
20
|
-
});
|
|
21
|
-
allComponentsWithStories?.forEach((componentInfo) => {
|
|
22
|
-
changeSyntaxOfStory(tree, componentInfo.componentStoryPath);
|
|
23
|
-
});
|
|
24
|
-
await (0, devkit_1.formatFiles)(tree);
|
|
25
|
-
}
|
|
26
|
-
exports.migrateStoriesTo62Generator = migrateStoriesTo62Generator;
|
|
27
|
-
function findAllAngularProjectsWithStorybookConfiguration(tree) {
|
|
28
|
-
const projects = (0, devkit_1.getProjects)(tree);
|
|
29
|
-
const projectsThatHaveStorybookConfiguration = [...projects.entries()]
|
|
30
|
-
?.filter(([_, projectConfig]) => projectConfig?.targets?.storybook?.options?.uiFramework ===
|
|
31
|
-
'@storybook/angular')
|
|
32
|
-
?.map(([projectName, projectConfig]) => {
|
|
33
|
-
return {
|
|
34
|
-
name: projectName,
|
|
35
|
-
configFolder: projectConfig.targets.storybook?.options?.config?.configFolder,
|
|
36
|
-
projectRoot: projectConfig.root,
|
|
37
|
-
projectSrc: projectConfig.sourceRoot,
|
|
38
|
-
};
|
|
39
|
-
});
|
|
40
|
-
return projectsThatHaveStorybookConfiguration;
|
|
41
|
-
}
|
|
42
|
-
exports.findAllAngularProjectsWithStorybookConfiguration = findAllAngularProjectsWithStorybookConfiguration;
|
|
43
|
-
function findAllComponentsWithStoriesForSpecificProject(tree, projectPath) {
|
|
44
|
-
let moduleFilePaths = [];
|
|
45
|
-
(0, devkit_1.visitNotIgnoredFiles)(tree, projectPath, (filePath) => {
|
|
46
|
-
if (filePath?.endsWith('.module.ts')) {
|
|
47
|
-
moduleFilePaths.push(filePath);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
let componentFileInfos = [];
|
|
51
|
-
moduleFilePaths?.map((moduleFilePath) => {
|
|
52
|
-
const file = (0, utilities_1.getTsSourceFile)(tree, moduleFilePath);
|
|
53
|
-
const ngModuleDecorators = (0, js_1.findNodes)(file, ts.SyntaxKind.Decorator);
|
|
54
|
-
if (ngModuleDecorators.length === 0) {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
const ngModuleDecorator = ngModuleDecorators[0];
|
|
58
|
-
const ngModuleNode = ngModuleDecorator?.getChildren()?.find((node) => {
|
|
59
|
-
return node?.getText()?.startsWith('NgModule');
|
|
60
|
-
});
|
|
61
|
-
const ngModulePropertiesObject = ngModuleNode
|
|
62
|
-
?.getChildren()
|
|
63
|
-
?.find((node) => {
|
|
64
|
-
return node.kind === typescript_1.SyntaxKind.SyntaxList;
|
|
65
|
-
});
|
|
66
|
-
const ngModuleProperties = ngModulePropertiesObject
|
|
67
|
-
?.getChildren()[0]
|
|
68
|
-
?.getChildren()
|
|
69
|
-
?.find((node) => {
|
|
70
|
-
return node?.getText()?.includes('declarations');
|
|
71
|
-
});
|
|
72
|
-
const declarationsPropertyAssignment = ngModuleProperties
|
|
73
|
-
?.getChildren()
|
|
74
|
-
?.find((node) => {
|
|
75
|
-
return node?.getText()?.startsWith('declarations');
|
|
76
|
-
});
|
|
77
|
-
if (!declarationsPropertyAssignment) {
|
|
78
|
-
devkit_1.logger.warn((0, devkit_1.stripIndents) `No components declared in ${moduleFilePath}.`);
|
|
79
|
-
}
|
|
80
|
-
let declarationArray = declarationsPropertyAssignment
|
|
81
|
-
?.getChildren()
|
|
82
|
-
?.find((node) => node.kind === typescript_1.SyntaxKind.ArrayLiteralExpression);
|
|
83
|
-
if (!declarationArray) {
|
|
84
|
-
// Attempt to follow a variable instead of the literal
|
|
85
|
-
const declarationVariable = declarationsPropertyAssignment
|
|
86
|
-
?.getChildren()
|
|
87
|
-
?.filter((node) => node.kind === typescript_1.SyntaxKind.Identifier)[1];
|
|
88
|
-
const variableName = declarationVariable?.getText();
|
|
89
|
-
const variableDeclaration = (0, js_1.findNodes)(file, typescript_1.SyntaxKind.VariableDeclaration)?.find((variableDeclaration) => {
|
|
90
|
-
const identifier = variableDeclaration
|
|
91
|
-
?.getChildren()
|
|
92
|
-
?.find((node) => node.kind === typescript_1.SyntaxKind.Identifier);
|
|
93
|
-
return identifier?.getText() === variableName;
|
|
94
|
-
});
|
|
95
|
-
if (variableDeclaration) {
|
|
96
|
-
declarationArray = variableDeclaration
|
|
97
|
-
?.getChildren()
|
|
98
|
-
?.find((node) => node.kind === typescript_1.SyntaxKind.ArrayLiteralExpression);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
const declaredComponents = declarationArray
|
|
102
|
-
?.getChildren()
|
|
103
|
-
?.find((node) => node.kind === typescript_1.SyntaxKind.SyntaxList)
|
|
104
|
-
?.getChildren()
|
|
105
|
-
?.filter((node) => node.kind === typescript_1.SyntaxKind.Identifier)
|
|
106
|
-
?.map((node) => node?.getText())
|
|
107
|
-
?.filter((name) => name?.endsWith('Component'));
|
|
108
|
-
const imports = file.statements?.filter((statement) => statement.kind === typescript_1.SyntaxKind.ImportDeclaration);
|
|
109
|
-
const modulePath = moduleFilePath.slice(0, moduleFilePath?.lastIndexOf('/'));
|
|
110
|
-
let componentInfo = declaredComponents?.map((componentName) => {
|
|
111
|
-
try {
|
|
112
|
-
const importStatement = imports?.find((statement) => {
|
|
113
|
-
const namedImports = statement
|
|
114
|
-
?.getChildren()
|
|
115
|
-
?.find((node) => node.kind === typescript_1.SyntaxKind.ImportClause)
|
|
116
|
-
?.getChildren()
|
|
117
|
-
?.find((node) => node.kind === typescript_1.SyntaxKind.NamedImports);
|
|
118
|
-
if (namedImports === undefined)
|
|
119
|
-
return false;
|
|
120
|
-
const importedIdentifiers = namedImports
|
|
121
|
-
?.getChildren()
|
|
122
|
-
?.find((node) => node.kind === typescript_1.SyntaxKind.SyntaxList)
|
|
123
|
-
?.getChildren()
|
|
124
|
-
?.filter((node) => node.kind === typescript_1.SyntaxKind.ImportSpecifier)
|
|
125
|
-
?.map((node) => node?.getText());
|
|
126
|
-
return importedIdentifiers?.includes(componentName);
|
|
127
|
-
});
|
|
128
|
-
const fullPath = importStatement
|
|
129
|
-
?.getChildren()
|
|
130
|
-
?.find((node) => node.kind === typescript_1.SyntaxKind.StringLiteral)
|
|
131
|
-
?.getText()
|
|
132
|
-
?.slice(1, -1);
|
|
133
|
-
// if it is a directory, search recursively for the component
|
|
134
|
-
let fullCmpImportPath = moduleFilePath?.slice(0, moduleFilePath?.lastIndexOf('/'));
|
|
135
|
-
if (fullCmpImportPath?.startsWith('/')) {
|
|
136
|
-
fullCmpImportPath = fullCmpImportPath?.slice(1, fullCmpImportPath.length);
|
|
137
|
-
}
|
|
138
|
-
let componentImportPath = (0, path_1.join)((0, path_1.normalize)(fullCmpImportPath), fullPath);
|
|
139
|
-
let path = null;
|
|
140
|
-
let componentFileName = null;
|
|
141
|
-
let componentStoryPath = null;
|
|
142
|
-
let storyExists = false;
|
|
143
|
-
let componentExists = false;
|
|
144
|
-
/**
|
|
145
|
-
* Here we want to remove the <component-name>.component
|
|
146
|
-
* part of the path, to just keep the
|
|
147
|
-
* apps/<project-name>/src/app/<component-name>
|
|
148
|
-
* or
|
|
149
|
-
* libs/<project-name>/src/lib/<component-name>
|
|
150
|
-
* part of the path
|
|
151
|
-
*/
|
|
152
|
-
componentImportPath = componentImportPath.slice(0, componentImportPath.lastIndexOf('/'));
|
|
153
|
-
(0, devkit_1.visitNotIgnoredFiles)(tree, componentImportPath, (componentFilePath) => {
|
|
154
|
-
if (componentFilePath?.endsWith('.ts')) {
|
|
155
|
-
const content = tree.read(componentFilePath).toString('utf-8');
|
|
156
|
-
if (content?.indexOf(`class ${componentName}`) > -1) {
|
|
157
|
-
componentExists = true;
|
|
158
|
-
path = componentFilePath;
|
|
159
|
-
componentFileName =
|
|
160
|
-
componentFilePath?.slice(componentFilePath?.lastIndexOf('/') + 1, componentFilePath?.lastIndexOf('.')) + '.ts';
|
|
161
|
-
}
|
|
162
|
-
if (componentFilePath?.endsWith('.stories.ts')) {
|
|
163
|
-
componentStoryPath = componentFilePath;
|
|
164
|
-
storyExists = true;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
if (!storyExists || !componentExists) {
|
|
169
|
-
path = null;
|
|
170
|
-
componentFileName = null;
|
|
171
|
-
componentStoryPath = null;
|
|
172
|
-
}
|
|
173
|
-
if (path !== null) {
|
|
174
|
-
return {
|
|
175
|
-
componentName: componentName,
|
|
176
|
-
componentPath: path,
|
|
177
|
-
componentFileName,
|
|
178
|
-
componentStoryPath: componentStoryPath,
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
const path = fullPath?.slice(0, fullPath?.lastIndexOf('/'));
|
|
183
|
-
const componentFileName = fullPath?.slice(fullPath?.lastIndexOf('/') + 1) + '.ts';
|
|
184
|
-
componentStoryPath = fullPath + '.stories.ts';
|
|
185
|
-
if ((0, fileutils_1.fileExists)(componentStoryPath)) {
|
|
186
|
-
return {
|
|
187
|
-
componentName: componentName,
|
|
188
|
-
componentPath: path + componentFileName,
|
|
189
|
-
componentFileName,
|
|
190
|
-
componentStoryPath: componentStoryPath,
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
return undefined;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
catch (e) {
|
|
199
|
-
devkit_1.logger.warn(`Could not find file for ${componentName}. Error: ${e}`);
|
|
200
|
-
return undefined;
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
if (componentInfo) {
|
|
204
|
-
componentInfo = componentInfo?.filter((info) => info !== undefined);
|
|
205
|
-
componentFileInfos = [...componentFileInfos, ...componentInfo];
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
return componentFileInfos;
|
|
209
|
-
}
|
|
210
|
-
async function changeSyntaxOfStory(tree, storyFilePath) {
|
|
211
|
-
const file = (0, utilities_1.getTsSourceFile)(tree, storyFilePath);
|
|
212
|
-
const appFileContent = tree.read(storyFilePath, 'utf-8');
|
|
213
|
-
let newContents = appFileContent;
|
|
214
|
-
const storiesVariableDeclaration = (0, js_1.findNodes)(file, [
|
|
215
|
-
ts.SyntaxKind.VariableDeclaration,
|
|
216
|
-
]);
|
|
217
|
-
const storiesExportDefault = (0, js_1.findNodes)(file, [
|
|
218
|
-
ts.SyntaxKind.ExportAssignment,
|
|
219
|
-
]);
|
|
220
|
-
const defaultExportNode = storiesExportDefault[0];
|
|
221
|
-
const defaultExportObject = defaultExportNode?.getChildren()?.find((node) => {
|
|
222
|
-
return node.kind === typescript_1.SyntaxKind.ObjectLiteralExpression;
|
|
223
|
-
});
|
|
224
|
-
const defaultPropertiesList = defaultExportObject
|
|
225
|
-
?.getChildren()
|
|
226
|
-
?.find((node) => {
|
|
227
|
-
return node.kind === typescript_1.SyntaxKind.SyntaxList;
|
|
228
|
-
});
|
|
229
|
-
const hasTitle = defaultPropertiesList?.getChildren()?.find((node) => {
|
|
230
|
-
return (node.kind === typescript_1.SyntaxKind.PropertyAssignment &&
|
|
231
|
-
node.getText().startsWith('title'));
|
|
232
|
-
});
|
|
233
|
-
/**
|
|
234
|
-
* A component node will look like this:
|
|
235
|
-
*
|
|
236
|
-
* component: MyTestComponent
|
|
237
|
-
*
|
|
238
|
-
* And this is what we need to remove.
|
|
239
|
-
*/
|
|
240
|
-
let firstComponentNode;
|
|
241
|
-
/**
|
|
242
|
-
* The result of ts.Node.getStart() will give us the index
|
|
243
|
-
* of that node in the whole original file.
|
|
244
|
-
* While we're editing that file, the getStart() will
|
|
245
|
-
* still reference the original file. So, during deletion,
|
|
246
|
-
* it would go and delete characters using the original index.
|
|
247
|
-
*
|
|
248
|
-
* We need to save the length of the characters that have been removed
|
|
249
|
-
* so far, so that we can substract it from the index.
|
|
250
|
-
* Since it's parsing the file linearly and in order, then this
|
|
251
|
-
* logic works.
|
|
252
|
-
* */
|
|
253
|
-
let lengthOfRemovalsSoFar = 0;
|
|
254
|
-
storiesVariableDeclaration?.forEach((oneStory) => {
|
|
255
|
-
const oneExportedStoryArrowFunction = oneStory
|
|
256
|
-
?.getChildren()
|
|
257
|
-
?.find((node) => {
|
|
258
|
-
return node.kind === typescript_1.SyntaxKind.ArrowFunction;
|
|
259
|
-
});
|
|
260
|
-
const inParenthesis = oneExportedStoryArrowFunction
|
|
261
|
-
?.getChildren()
|
|
262
|
-
?.find((node) => {
|
|
263
|
-
return node.kind === typescript_1.SyntaxKind.ParenthesizedExpression;
|
|
264
|
-
});
|
|
265
|
-
const objectLiteralOfStory = inParenthesis?.getChildren()?.find((node) => {
|
|
266
|
-
return node.kind === typescript_1.SyntaxKind.ObjectLiteralExpression;
|
|
267
|
-
});
|
|
268
|
-
const propertiesList = objectLiteralOfStory?.getChildren()?.find((node) => {
|
|
269
|
-
return node.kind === typescript_1.SyntaxKind.SyntaxList;
|
|
270
|
-
});
|
|
271
|
-
const hasComponentDeclared = propertiesList?.getChildren()?.find((node) => {
|
|
272
|
-
return (node.kind === typescript_1.SyntaxKind.PropertyAssignment &&
|
|
273
|
-
node.getText().startsWith('component'));
|
|
274
|
-
});
|
|
275
|
-
if (hasComponentDeclared) {
|
|
276
|
-
/**
|
|
277
|
-
* Here I am saving the first component to appear
|
|
278
|
-
* in the case where we have multiple stories
|
|
279
|
-
*/
|
|
280
|
-
if (!firstComponentNode) {
|
|
281
|
-
firstComponentNode = hasComponentDeclared;
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Here we are performing the following check:
|
|
285
|
-
* If the component we will be adding in the default declaration
|
|
286
|
-
* which is the first component that we find
|
|
287
|
-
* is the same for this story as well,
|
|
288
|
-
* then remove it.
|
|
289
|
-
*/
|
|
290
|
-
if (hasComponentDeclared.getText() === firstComponentNode.getText()) {
|
|
291
|
-
const indexOfPropertyName = hasComponentDeclared.getStart();
|
|
292
|
-
const lengthOfRemoval = hasComponentDeclared?.getText()?.length + 1;
|
|
293
|
-
newContents = (0, devkit_1.applyChangesToString)(newContents, [
|
|
294
|
-
{
|
|
295
|
-
type: devkit_1.ChangeType.Delete,
|
|
296
|
-
start: indexOfPropertyName - lengthOfRemovalsSoFar,
|
|
297
|
-
length: lengthOfRemoval,
|
|
298
|
-
},
|
|
299
|
-
]);
|
|
300
|
-
lengthOfRemovalsSoFar = lengthOfRemovalsSoFar + lengthOfRemoval;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
});
|
|
304
|
-
if (hasTitle && firstComponentNode) {
|
|
305
|
-
const indexOfPropertyName = hasTitle.getEnd();
|
|
306
|
-
newContents = (0, devkit_1.applyChangesToString)(newContents, [
|
|
307
|
-
{
|
|
308
|
-
type: devkit_1.ChangeType.Insert,
|
|
309
|
-
index: indexOfPropertyName + 2,
|
|
310
|
-
text: firstComponentNode.getText() + ',',
|
|
311
|
-
},
|
|
312
|
-
]);
|
|
313
|
-
tree.write(storyFilePath, newContents);
|
|
314
|
-
}
|
|
315
|
-
await (0, devkit_1.formatFiles)(tree);
|
|
316
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const migrate_defaults_5_to_6_1 = require("./migrate-defaults-5-to-6/migrate-defaults-5-to-6");
|
|
4
|
-
const migrate_stories_to_6_2_1 = require("./migrate-stories-to-6-2/migrate-stories-to-6-2");
|
|
5
|
-
async function migrateToStorybook6(tree) {
|
|
6
|
-
(0, migrate_stories_to_6_2_1.migrateStoriesTo62Generator)(tree);
|
|
7
|
-
return (0, migrate_defaults_5_to_6_1.migrateDefaultsGenerator)(tree);
|
|
8
|
-
}
|
|
9
|
-
exports.default = migrateToStorybook6;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { Tree } from '@nx/devkit';
|
|
2
|
-
export declare function changeStorybookTargetsGenerator(tree: Tree): Promise<void>;
|
|
3
|
-
export default changeStorybookTargetsGenerator;
|
|
4
|
-
export declare const changeStorybookTargetsSchematic: (generatorOptions: any) => (tree: any, context: any) => Promise<any>;
|