@nx/storybook 23.2.0-beta.7 → 23.2.0-beta.9
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/src/generators/configuration/configuration.js +3 -0
- package/dist/src/generators/configuration/lib/util-functions.js +2 -2
- package/dist/src/plugins/plugin.js +134 -31
- package/dist/src/utils/utilities.js +8 -11
- package/dist/src/utils/versions.d.ts +2 -0
- package/dist/src/utils/versions.js +26 -5
- package/migrations.json +13 -0
- package/package.json +7 -7
|
@@ -96,6 +96,9 @@ async function configurationGeneratorInternal(tree, rawSchema) {
|
|
|
96
96
|
else {
|
|
97
97
|
devDeps['storybook'] = (0, utilities_1.getStorybookVersionToInstall)(tree);
|
|
98
98
|
}
|
|
99
|
+
if (schema.interactionTests) {
|
|
100
|
+
devDeps['@storybook/test-runner'] = (0, versions_1.versions)(tree).testRunnerVersion;
|
|
101
|
+
}
|
|
99
102
|
if (schema.tsConfiguration) {
|
|
100
103
|
devDeps['ts-node'] = versions_1.tsNodeVersion;
|
|
101
104
|
}
|
|
@@ -74,7 +74,7 @@ function addAngularStorybookTarget(tree, projectName, interactionTests) {
|
|
|
74
74
|
options: {
|
|
75
75
|
port: 4400,
|
|
76
76
|
configDir: `${projectConfig.root}/.storybook`,
|
|
77
|
-
browserTarget: `${projectName}:${ngBuildTarget
|
|
77
|
+
browserTarget: `${projectName}:${ngBuildTarget ?? 'build-storybook'}`,
|
|
78
78
|
compodoc: false,
|
|
79
79
|
},
|
|
80
80
|
configurations: {
|
|
@@ -89,7 +89,7 @@ function addAngularStorybookTarget(tree, projectName, interactionTests) {
|
|
|
89
89
|
options: {
|
|
90
90
|
outputDir: (0, devkit_1.joinPathFragments)('dist/storybook', projectName),
|
|
91
91
|
configDir: `${projectConfig.root}/.storybook`,
|
|
92
|
-
browserTarget: `${projectName}:${ngBuildTarget
|
|
92
|
+
browserTarget: `${projectName}:${ngBuildTarget ?? 'build-storybook'}`,
|
|
93
93
|
compodoc: false,
|
|
94
94
|
},
|
|
95
95
|
configurations: {
|
|
@@ -8,6 +8,7 @@ const fs_1 = require("fs");
|
|
|
8
8
|
const js_1 = require("@nx/js");
|
|
9
9
|
const tsquery_1 = require("@phenomnomnominal/tsquery");
|
|
10
10
|
const internal_2 = require("@nx/js/internal");
|
|
11
|
+
const utilities_1 = require("../utils/utilities");
|
|
11
12
|
/**
|
|
12
13
|
* @deprecated The 'createDependencies' function is now a no-op. This functionality is included in 'createNodesV2'.
|
|
13
14
|
*/
|
|
@@ -16,6 +17,23 @@ const createDependencies = () => {
|
|
|
16
17
|
};
|
|
17
18
|
exports.createDependencies = createDependencies;
|
|
18
19
|
const storybookConfigGlob = '**/.storybook/main.{js,ts,mjs,mts,cjs,cts}';
|
|
20
|
+
// Vite-builder frameworks we infer the addon target for. The addon itself only
|
|
21
|
+
// checks that the resolved builder is Vite, so this list is conservative rather
|
|
22
|
+
// than exhaustive. `@storybook/sveltekit` uses the Vite builder despite the name.
|
|
23
|
+
const VITE_BUILDER_FRAMEWORKS = new Set([
|
|
24
|
+
'@storybook/angular-vite',
|
|
25
|
+
'@storybook/react-vite',
|
|
26
|
+
'@storybook/react-native-web-vite',
|
|
27
|
+
'@storybook/tanstack-react',
|
|
28
|
+
'@storybook/vue-vite',
|
|
29
|
+
'@storybook/vue3-vite',
|
|
30
|
+
'@storybook/svelte-vite',
|
|
31
|
+
'@storybook/sveltekit',
|
|
32
|
+
'@storybook/web-components-vite',
|
|
33
|
+
'@storybook/html-vite',
|
|
34
|
+
'@storybook/preact-vite',
|
|
35
|
+
'@storybook/nextjs-vite',
|
|
36
|
+
]);
|
|
19
37
|
exports.createNodes = [
|
|
20
38
|
storybookConfigGlob,
|
|
21
39
|
async (configFilePaths, options, context) => {
|
|
@@ -69,9 +87,9 @@ function getProjectRootFromConfigPath(configFilePath) {
|
|
|
69
87
|
return projectRoot;
|
|
70
88
|
}
|
|
71
89
|
async function createNodesInternal(configFilePath, options, context, targetsCache, pmc, projectRoot, hash) {
|
|
72
|
-
const projectName =
|
|
90
|
+
const { projectName, angularBuildTarget } = getProjectMetadata(projectRoot, context.workspaceRoot);
|
|
73
91
|
if (!targetsCache.has(hash)) {
|
|
74
|
-
targetsCache.set(hash, await buildStorybookTargets(configFilePath, projectRoot, options, context, projectName, pmc));
|
|
92
|
+
targetsCache.set(hash, await buildStorybookTargets(configFilePath, projectRoot, options, context, projectName, angularBuildTarget, pmc));
|
|
75
93
|
}
|
|
76
94
|
const result = {
|
|
77
95
|
projects: {
|
|
@@ -83,35 +101,51 @@ async function createNodesInternal(configFilePath, options, context, targetsCach
|
|
|
83
101
|
};
|
|
84
102
|
return result;
|
|
85
103
|
}
|
|
86
|
-
async function buildStorybookTargets(configFilePath, projectRoot, options, context, projectName, pmc) {
|
|
104
|
+
async function buildStorybookTargets(configFilePath, projectRoot, options, context, projectName, angularBuildTarget, pmc) {
|
|
87
105
|
const buildOutputs = getOutputs();
|
|
88
106
|
const namedInputs = (0, internal_1.getNamedInputs)(projectRoot, context);
|
|
89
107
|
// First attempt to do a very fast lookup for the framework
|
|
90
108
|
// If that fails, the framework might be inherited, so do a very heavyweight lookup
|
|
91
|
-
|
|
92
|
-
|
|
109
|
+
// The slow path returns whatever the config holds, which for the common
|
|
110
|
+
// `getAbsolutePath('@storybook/react-vite')` shape is a resolved path.
|
|
111
|
+
const storybookFramework = normalizePackageName((await getStorybookFramework(configFilePath, context)) ||
|
|
112
|
+
(await getStorybookFullyResolvedFramework(configFilePath, context)));
|
|
93
113
|
const frameworkIsAngular = storybookFramework === '@storybook/angular';
|
|
94
114
|
if (frameworkIsAngular && !projectName) {
|
|
95
115
|
throw new Error(`Could not find a name for the project at '${projectRoot}'. Please make sure that the project has a package.json or project.json file with name specified.`);
|
|
96
116
|
}
|
|
97
117
|
const targets = {};
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
118
|
+
// Resolution alone is not enough: the addon lives in the root package.json, so
|
|
119
|
+
// it resolves for every project. Registration in this project's own config is
|
|
120
|
+
// what makes it ours. Resolve first - it is a stat walk, while reading the
|
|
121
|
+
// registration executes the user's config.
|
|
122
|
+
const usesVitestAddon = VITE_BUILDER_FRAMEWORKS.has(storybookFramework) &&
|
|
123
|
+
isInstalled('@storybook/addon-vitest', context.workspaceRoot, projectRoot) &&
|
|
124
|
+
(await registersVitestAddon(configFilePath, context));
|
|
125
|
+
const hasTestRunner = isInstalled('@storybook/test-runner', context.workspaceRoot, projectRoot);
|
|
126
|
+
// Falls back to the storybook build target, whose name is configurable, so
|
|
127
|
+
// resolve it from the options rather than assuming the default.
|
|
128
|
+
const browserTarget = `${projectName}:${angularBuildTarget ?? options.buildStorybookTargetName}`;
|
|
129
|
+
targets[options.buildStorybookTargetName] = buildTarget(namedInputs, buildOutputs, projectRoot, frameworkIsAngular, browserTarget, configFilePath, hasTestRunner);
|
|
130
|
+
targets[options.serveStorybookTargetName] = serveTarget(projectRoot, frameworkIsAngular, browserTarget, configFilePath);
|
|
131
|
+
if (usesVitestAddon) {
|
|
132
|
+
targets[options.testStorybookTargetName] = vitestTestTarget(projectRoot);
|
|
133
|
+
}
|
|
134
|
+
else if (hasTestRunner) {
|
|
101
135
|
targets[options.testStorybookTargetName] = testTarget(projectRoot);
|
|
102
136
|
}
|
|
103
137
|
targets[options.staticStorybookTargetName] = serveStaticTarget(options, projectRoot);
|
|
104
138
|
(0, internal_2.addBuildAndWatchDepsTargets)(context.workspaceRoot, projectRoot, targets, options, pmc);
|
|
105
139
|
return targets;
|
|
106
140
|
}
|
|
107
|
-
function buildTarget(namedInputs, outputs, projectRoot, frameworkIsAngular,
|
|
141
|
+
function buildTarget(namedInputs, outputs, projectRoot, frameworkIsAngular, browserTarget, configFilePath, hasTestRunner) {
|
|
108
142
|
let targetConfig;
|
|
109
143
|
if (frameworkIsAngular) {
|
|
110
144
|
targetConfig = {
|
|
111
145
|
executor: '@storybook/angular:build-storybook',
|
|
112
146
|
options: {
|
|
113
147
|
configDir: `${(0, path_1.dirname)(configFilePath)}`,
|
|
114
|
-
browserTarget
|
|
148
|
+
browserTarget,
|
|
115
149
|
compodoc: false,
|
|
116
150
|
outputDir: (0, devkit_1.joinPathFragments)(projectRoot, 'storybook-static'),
|
|
117
151
|
},
|
|
@@ -125,9 +159,7 @@ function buildTarget(namedInputs, outputs, projectRoot, frameworkIsAngular, proj
|
|
|
125
159
|
externalDependencies: [
|
|
126
160
|
'storybook',
|
|
127
161
|
'@storybook/angular',
|
|
128
|
-
|
|
129
|
-
? '@storybook/test-runner'
|
|
130
|
-
: undefined,
|
|
162
|
+
hasTestRunner ? '@storybook/test-runner' : undefined,
|
|
131
163
|
].filter(Boolean),
|
|
132
164
|
},
|
|
133
165
|
],
|
|
@@ -146,9 +178,7 @@ function buildTarget(namedInputs, outputs, projectRoot, frameworkIsAngular, proj
|
|
|
146
178
|
{
|
|
147
179
|
externalDependencies: [
|
|
148
180
|
'storybook',
|
|
149
|
-
|
|
150
|
-
? '@storybook/test-runner'
|
|
151
|
-
: undefined,
|
|
181
|
+
hasTestRunner ? '@storybook/test-runner' : undefined,
|
|
152
182
|
].filter(Boolean),
|
|
153
183
|
},
|
|
154
184
|
],
|
|
@@ -156,15 +186,18 @@ function buildTarget(namedInputs, outputs, projectRoot, frameworkIsAngular, proj
|
|
|
156
186
|
}
|
|
157
187
|
return targetConfig;
|
|
158
188
|
}
|
|
159
|
-
function serveTarget(projectRoot, frameworkIsAngular,
|
|
189
|
+
function serveTarget(projectRoot, frameworkIsAngular, browserTarget, configFilePath) {
|
|
160
190
|
if (frameworkIsAngular) {
|
|
161
191
|
return {
|
|
162
192
|
continuous: true,
|
|
163
193
|
executor: '@storybook/angular:start-storybook',
|
|
164
194
|
options: {
|
|
165
195
|
configDir: `${(0, path_1.dirname)(configFilePath)}`,
|
|
166
|
-
browserTarget
|
|
196
|
+
browserTarget,
|
|
167
197
|
compodoc: false,
|
|
198
|
+
// The builder defaults to 9009, but test-storybook looks for 6006. Match
|
|
199
|
+
// the port the non-Angular `storybook dev` target serves on.
|
|
200
|
+
port: 6006,
|
|
168
201
|
},
|
|
169
202
|
};
|
|
170
203
|
}
|
|
@@ -188,6 +221,24 @@ function testTarget(projectRoot) {
|
|
|
188
221
|
};
|
|
189
222
|
return targetConfig;
|
|
190
223
|
}
|
|
224
|
+
function vitestTestTarget(projectRoot) {
|
|
225
|
+
const targetConfig = {
|
|
226
|
+
// `--passWithNoTests` so the target is green before any stories exist. It does
|
|
227
|
+
// not mask a missing `storybook` project: that is a startup error either way.
|
|
228
|
+
command: `vitest run --project=storybook --passWithNoTests`,
|
|
229
|
+
options: { cwd: projectRoot },
|
|
230
|
+
inputs: [
|
|
231
|
+
{
|
|
232
|
+
externalDependencies: [
|
|
233
|
+
'storybook',
|
|
234
|
+
'@storybook/addon-vitest',
|
|
235
|
+
'vitest',
|
|
236
|
+
],
|
|
237
|
+
},
|
|
238
|
+
],
|
|
239
|
+
};
|
|
240
|
+
return targetConfig;
|
|
241
|
+
}
|
|
191
242
|
function serveStaticTarget(options, projectRoot) {
|
|
192
243
|
const targetConfig = {
|
|
193
244
|
dependsOn: [`${options.buildStorybookTargetName}`],
|
|
@@ -208,10 +259,11 @@ async function getStorybookFramework(configFilePath, context) {
|
|
|
208
259
|
return parseFrameworkName(mainTsJs);
|
|
209
260
|
}
|
|
210
261
|
const storybookConfigImportPackage = (0, tsquery_1.query)(importDeclarations, 'StringLiteral')?.[0];
|
|
211
|
-
|
|
262
|
+
const frameworkPackage = stringLiteralValue(storybookConfigImportPackage);
|
|
263
|
+
if (frameworkPackage === '@storybook/core-common') {
|
|
212
264
|
return parseFrameworkName(mainTsJs);
|
|
213
265
|
}
|
|
214
|
-
return
|
|
266
|
+
return frameworkPackage;
|
|
215
267
|
}
|
|
216
268
|
function parseFrameworkName(mainTsJs) {
|
|
217
269
|
const frameworkPropertyAssignment = (0, tsquery_1.query)(mainTsJs, `PropertyAssignment:has(Identifier:has([text="framework"]))`)?.[0];
|
|
@@ -224,9 +276,13 @@ function parseFrameworkName(mainTsJs) {
|
|
|
224
276
|
});
|
|
225
277
|
if (!namePropertyAssignment) {
|
|
226
278
|
const storybookConfigImportPackage = (0, tsquery_1.query)(frameworkPropertyAssignment, 'StringLiteral')?.[0];
|
|
227
|
-
return storybookConfigImportPackage
|
|
279
|
+
return stringLiteralValue(storybookConfigImportPackage);
|
|
228
280
|
}
|
|
229
|
-
return (0, tsquery_1.query)(namePropertyAssignment, `StringLiteral`)?.[0]
|
|
281
|
+
return stringLiteralValue((0, tsquery_1.query)(namePropertyAssignment, `StringLiteral`)?.[0]);
|
|
282
|
+
}
|
|
283
|
+
function stringLiteralValue(node) {
|
|
284
|
+
const value = node?.getText();
|
|
285
|
+
return value?.slice(1, -1);
|
|
230
286
|
}
|
|
231
287
|
async function getStorybookFullyResolvedFramework(configFilePath, context) {
|
|
232
288
|
const resolvedPath = (0, path_1.join)(context.workspaceRoot, configFilePath);
|
|
@@ -274,26 +330,73 @@ function normalizeOptions(options) {
|
|
|
274
330
|
watchDepsTargetName: options.watchDepsTargetName ?? 'watch-deps',
|
|
275
331
|
};
|
|
276
332
|
}
|
|
277
|
-
function
|
|
333
|
+
function getProjectMetadata(projectRoot, workspaceRoot) {
|
|
278
334
|
const packageJsonPath = (0, path_1.join)(workspaceRoot, projectRoot, 'package.json');
|
|
279
335
|
const projectJsonPath = (0, path_1.join)(workspaceRoot, projectRoot, 'project.json');
|
|
280
|
-
let
|
|
336
|
+
let projectJsonName;
|
|
337
|
+
let projectJsonTargets = {};
|
|
338
|
+
let packageJsonName;
|
|
339
|
+
let packageJsonTargets = {};
|
|
281
340
|
if ((0, fs_1.existsSync)(projectJsonPath)) {
|
|
282
341
|
const projectJson = (0, devkit_1.parseJson)((0, fs_1.readFileSync)(projectJsonPath, 'utf-8'));
|
|
283
|
-
|
|
342
|
+
projectJsonName = projectJson.name;
|
|
343
|
+
projectJsonTargets = projectJson.targets ?? {};
|
|
284
344
|
}
|
|
285
|
-
|
|
345
|
+
if ((0, fs_1.existsSync)(packageJsonPath)) {
|
|
286
346
|
const packageJson = (0, devkit_1.parseJson)((0, fs_1.readFileSync)(packageJsonPath, 'utf-8'));
|
|
287
|
-
|
|
347
|
+
packageJsonName = packageJson.name;
|
|
348
|
+
packageJsonTargets = packageJson.nx?.targets ?? {};
|
|
288
349
|
}
|
|
289
|
-
|
|
350
|
+
// Mirror how Nx itself names a project: project.json, then package.json, then
|
|
351
|
+
// the directory. Both files can carry targets, and project.json wins.
|
|
352
|
+
const targets = { ...packageJsonTargets, ...projectJsonTargets };
|
|
353
|
+
return {
|
|
354
|
+
projectName: projectJsonName ?? packageJsonName ?? nameFromRoot(projectRoot),
|
|
355
|
+
angularBuildTarget: (0, utilities_1.findStorybookAndBuildTargetsAndCompiler)(targets).ngBuildTarget,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
// Same derivation as Nx's `toProjectName`. The workspace root has no directory
|
|
359
|
+
// segment to name it after, so leave it undefined and let the caller complain.
|
|
360
|
+
function nameFromRoot(projectRoot) {
|
|
361
|
+
const segment = projectRoot.split(/[\/\\]/g).pop();
|
|
362
|
+
return !segment || segment === '.' ? undefined : segment.toLowerCase();
|
|
363
|
+
}
|
|
364
|
+
async function registersVitestAddon(configFilePath, context) {
|
|
365
|
+
try {
|
|
366
|
+
const { addons } = await (0, internal_1.loadConfigFile)((0, path_1.join)(context.workspaceRoot, configFilePath));
|
|
367
|
+
return addons?.some(isVitestAddon) ?? false;
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
function isVitestAddon(addon) {
|
|
374
|
+
const addonName = typeof addon === 'string'
|
|
375
|
+
? addon
|
|
376
|
+
: typeof addon === 'object' && addon !== null && 'name' in addon
|
|
377
|
+
? addon.name
|
|
378
|
+
: undefined;
|
|
379
|
+
return (typeof addonName === 'string' &&
|
|
380
|
+
normalizePackageName(addonName) === '@storybook/addon-vitest');
|
|
381
|
+
}
|
|
382
|
+
function normalizePackageName(packageName) {
|
|
383
|
+
return packageName
|
|
384
|
+
?.replace(/\\/g, '/')
|
|
385
|
+
.split('/')
|
|
386
|
+
.filter(Boolean)
|
|
387
|
+
.slice(-2)
|
|
388
|
+
.join('/');
|
|
290
389
|
}
|
|
291
|
-
|
|
390
|
+
// Resolved from the project first so a runner declared in the project's own
|
|
391
|
+
// package.json counts, not just one hoisted to the workspace root.
|
|
392
|
+
function isInstalled(packageName, workspaceRoot, projectRoot) {
|
|
292
393
|
try {
|
|
293
|
-
require.resolve(
|
|
394
|
+
require.resolve(packageName, {
|
|
395
|
+
paths: [(0, path_1.join)(workspaceRoot, projectRoot), workspaceRoot],
|
|
396
|
+
});
|
|
294
397
|
return true;
|
|
295
398
|
}
|
|
296
|
-
catch
|
|
399
|
+
catch {
|
|
297
400
|
return false;
|
|
298
401
|
}
|
|
299
402
|
}
|
|
@@ -67,24 +67,21 @@ function findStorybookAndBuildTargetsAndCompiler(targets) {
|
|
|
67
67
|
'@angular-devkit/build-angular:application',
|
|
68
68
|
'@angular-devkit/build-angular:browser',
|
|
69
69
|
'@angular-devkit/build-angular:browser-esbuild',
|
|
70
|
+
'@angular/build:application',
|
|
70
71
|
];
|
|
71
72
|
for (const target in targets) {
|
|
72
73
|
if (arrayOfBuilders.includes(targets[target].executor)) {
|
|
73
74
|
if (targets[target].executor === '@angular-devkit/build-angular:browser' ||
|
|
74
75
|
targets[target].executor ===
|
|
75
76
|
'@angular-devkit/build-angular:browser-esbuild' ||
|
|
76
|
-
targets[target].executor ===
|
|
77
|
+
targets[target].executor ===
|
|
78
|
+
'@angular-devkit/build-angular:application' ||
|
|
79
|
+
targets[target].executor === '@angular/build:application') {
|
|
77
80
|
/**
|
|
78
|
-
*
|
|
79
|
-
* @nx/angular:* executors
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* (and maybe the other custom executors)
|
|
83
|
-
* does not support styles and extra options, so the user
|
|
84
|
-
* will be forced to switch to build-storybook to add extra options.
|
|
85
|
-
*
|
|
86
|
-
* So we might as well use the build-storybook by default to
|
|
87
|
-
* avoid any errors.
|
|
81
|
+
* Only the official Angular application/browser builders. The
|
|
82
|
+
* '@nx/angular:*' executors (ng-packagr-lite and friends) do not
|
|
83
|
+
* support styles and extra options, so a project on one of those is
|
|
84
|
+
* better served by build-storybook, which can carry those options.
|
|
88
85
|
*/
|
|
89
86
|
returnObject.ngBuildTarget = target;
|
|
90
87
|
}
|
|
@@ -8,8 +8,10 @@ export declare const storybookVersion = "^10.5.0";
|
|
|
8
8
|
export declare const reactVersion = "^18.2.0";
|
|
9
9
|
export declare const viteVersion = "^6.0.0";
|
|
10
10
|
export declare const coreJsVersion = "^3.36.1";
|
|
11
|
+
export declare const testRunnerVersion = "^0.24.0";
|
|
11
12
|
type StorybookVersions = {
|
|
12
13
|
storybookVersion: string;
|
|
14
|
+
testRunnerVersion: string;
|
|
13
15
|
};
|
|
14
16
|
export declare function versions(tree: Tree): StorybookVersions;
|
|
15
17
|
export declare function storybookMajorVersion(tree?: Tree): number | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.coreJsVersion = exports.viteVersion = exports.reactVersion = exports.storybookVersion = exports.minSupportedStorybookVersion = exports.tsLibVersion = exports.tsNodeVersion = exports.litVersion = exports.nxVersion = void 0;
|
|
3
|
+
exports.testRunnerVersion = exports.coreJsVersion = exports.viteVersion = exports.reactVersion = exports.storybookVersion = exports.minSupportedStorybookVersion = exports.tsLibVersion = exports.tsNodeVersion = exports.litVersion = exports.nxVersion = void 0;
|
|
4
4
|
exports.versions = versions;
|
|
5
5
|
exports.storybookMajorVersion = storybookMajorVersion;
|
|
6
6
|
exports.getInstalledStorybookVersion = getInstalledStorybookVersion;
|
|
@@ -17,20 +17,41 @@ exports.storybookVersion = '^10.5.0';
|
|
|
17
17
|
exports.reactVersion = '^18.2.0';
|
|
18
18
|
exports.viteVersion = '^6.0.0';
|
|
19
19
|
exports.coreJsVersion = '^3.36.1';
|
|
20
|
+
exports.testRunnerVersion = '^0.24.0';
|
|
20
21
|
const latestVersions = {
|
|
21
22
|
storybookVersion: exports.storybookVersion,
|
|
23
|
+
testRunnerVersion: exports.testRunnerVersion,
|
|
22
24
|
};
|
|
23
25
|
const versionMap = {
|
|
24
|
-
8: { storybookVersion: '^8.6.11' },
|
|
25
|
-
9: { storybookVersion: '^9.0.5' },
|
|
26
|
-
10: { storybookVersion: '^10.5.0' },
|
|
26
|
+
8: { storybookVersion: '^8.6.11', testRunnerVersion: '^0.21.0' },
|
|
27
|
+
9: { storybookVersion: '^9.0.5', testRunnerVersion: '^0.23.0' },
|
|
28
|
+
10: { storybookVersion: '^10.5.0', testRunnerVersion: exports.testRunnerVersion },
|
|
27
29
|
};
|
|
28
30
|
function versions(tree) {
|
|
29
31
|
const installedStorybookMajor = storybookMajorVersion(tree);
|
|
30
32
|
if (installedStorybookMajor === undefined) {
|
|
31
33
|
return latestVersions;
|
|
32
34
|
}
|
|
33
|
-
|
|
35
|
+
const compat = versionMap[installedStorybookMajor] ?? latestVersions;
|
|
36
|
+
// 0.20 is the first runner line to declare a storybook peer, and it peers ^8.2.
|
|
37
|
+
// Ranges that cannot reach 8.2 need 0.17, the earliest line built against 8.
|
|
38
|
+
if (installedStorybookMajor === 8 &&
|
|
39
|
+
!storybookVersionIntersects(tree, '>=8.2.0')) {
|
|
40
|
+
return { ...compat, testRunnerVersion: '^0.17.0' };
|
|
41
|
+
}
|
|
42
|
+
return compat;
|
|
43
|
+
}
|
|
44
|
+
function storybookVersionIntersects(tree, range) {
|
|
45
|
+
const installedVersion = getInstalledStorybookVersion(tree);
|
|
46
|
+
if (!installedVersion) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
return (0, semver_1.intersects)(installedVersion, range);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
34
55
|
}
|
|
35
56
|
function storybookMajorVersion(tree) {
|
|
36
57
|
const installedVersion = getInstalledStorybookVersion(tree);
|
package/migrations.json
CHANGED
|
@@ -435,6 +435,19 @@
|
|
|
435
435
|
"alwaysAddToPackageJson": false
|
|
436
436
|
}
|
|
437
437
|
}
|
|
438
|
+
},
|
|
439
|
+
"23.2.0-test-runner": {
|
|
440
|
+
"version": "23.2.0-beta.8",
|
|
441
|
+
"requires": {
|
|
442
|
+
"storybook": ">=10.0.0 <11.0.0",
|
|
443
|
+
"@storybook/test-runner": "<0.24.0"
|
|
444
|
+
},
|
|
445
|
+
"packages": {
|
|
446
|
+
"@storybook/test-runner": {
|
|
447
|
+
"version": "^0.24.0",
|
|
448
|
+
"alwaysAddToPackageJson": false
|
|
449
|
+
}
|
|
450
|
+
}
|
|
438
451
|
}
|
|
439
452
|
}
|
|
440
453
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/storybook",
|
|
3
|
-
"version": "23.2.0-beta.
|
|
3
|
+
"version": "23.2.0-beta.9",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"files": [
|
|
@@ -92,18 +92,18 @@
|
|
|
92
92
|
"@phenomnomnominal/tsquery": "~6.2.0",
|
|
93
93
|
"semver": "^7.6.3",
|
|
94
94
|
"tslib": "^2.3.0",
|
|
95
|
-
"@nx/devkit": "23.2.0-beta.
|
|
96
|
-
"@nx/cypress": "23.2.0-beta.
|
|
97
|
-
"@nx/js": "23.2.0-beta.
|
|
98
|
-
"@nx/eslint": "23.2.0-beta.
|
|
95
|
+
"@nx/devkit": "23.2.0-beta.9",
|
|
96
|
+
"@nx/cypress": "23.2.0-beta.9",
|
|
97
|
+
"@nx/js": "23.2.0-beta.9",
|
|
98
|
+
"@nx/eslint": "23.2.0-beta.9"
|
|
99
99
|
},
|
|
100
100
|
"devDependencies": {
|
|
101
101
|
"storybook": "9.0.6",
|
|
102
|
-
"nx": "23.2.0-beta.
|
|
102
|
+
"nx": "23.2.0-beta.9"
|
|
103
103
|
},
|
|
104
104
|
"peerDependencies": {
|
|
105
105
|
"storybook": ">=8.0.0 <11.0.0",
|
|
106
|
-
"@nx/web": "23.2.0-beta.
|
|
106
|
+
"@nx/web": "23.2.0-beta.9"
|
|
107
107
|
},
|
|
108
108
|
"peerDependenciesMeta": {
|
|
109
109
|
"@nx/web": {
|