@nx/angular 16.6.0-beta.4 → 16.6.0-beta.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/angular",
3
- "version": "16.6.0-beta.4",
3
+ "version": "16.6.0-beta.5",
4
4
  "private": false,
5
5
  "description": "The Nx Plugin for Angular contains executors, generators, and utilities for managing Angular applications and libraries within an Nx workspace. It provides: \n\n- Integration with libraries such as Storybook, Jest, ESLint, Tailwind CSS, and Cypress. \n\n- Generators to help scaffold code quickly (like: Micro Frontends, Libraries, both internal to your codebase and publishable to npm) \n\n- Upgrading AngularJS applications \n\n- Single Component Application Modules (SCAMs) \n\n- NgRx helpers. \n\n- Utilities for automatic workspace refactoring.",
6
6
  "repository": {
@@ -66,28 +66,26 @@
66
66
  "migrations": "./migrations.json"
67
67
  },
68
68
  "dependencies": {
69
- "@nrwl/angular": "16.6.0-beta.4",
70
- "@nx/cypress": "16.6.0-beta.4",
71
- "@nx/devkit": "16.6.0-beta.4",
72
- "@nx/jest": "16.6.0-beta.4",
73
- "@nx/js": "16.6.0-beta.4",
74
- "@nx/linter": "16.6.0-beta.4",
75
- "@nx/webpack": "16.6.0-beta.4",
76
- "@nx/workspace": "16.6.0-beta.4",
69
+ "@nrwl/angular": "16.6.0-beta.5",
70
+ "@nx/cypress": "16.6.0-beta.5",
71
+ "@nx/devkit": "16.6.0-beta.5",
72
+ "@nx/jest": "16.6.0-beta.5",
73
+ "@nx/js": "16.6.0-beta.5",
74
+ "@nx/linter": "16.6.0-beta.5",
75
+ "@nx/webpack": "16.6.0-beta.5",
76
+ "@nx/workspace": "16.6.0-beta.5",
77
77
  "@phenomnomnominal/tsquery": "~5.0.1",
78
78
  "@typescript-eslint/type-utils": "^5.36.1",
79
79
  "chalk": "^4.1.0",
80
- "chokidar": "^3.5.1",
81
80
  "enquirer": "^2.3.6",
82
81
  "find-cache-dir": "^3.3.2",
83
- "http-server": "^14.1.0",
84
82
  "ignore": "^5.0.4",
85
83
  "magic-string": "~0.26.2",
86
84
  "minimatch": "3.0.5",
87
85
  "semver": "7.5.3",
88
86
  "tslib": "^2.3.0",
89
87
  "webpack": "^5.80.0",
90
- "webpack-merge": "5.7.3"
88
+ "webpack-merge": "^5.8.0"
91
89
  },
92
90
  "peerDependencies": {
93
91
  "@angular-devkit/build-angular": ">= 14.0.0 < 17.0.0",
@@ -109,5 +107,5 @@
109
107
  "module": "fesm2022/nx-angular.mjs",
110
108
  "typings": "index.d.ts",
111
109
  "sideEffects": false,
112
- "gitHead": "b1a9ae7ce76697019b26ec9a172005840cca8da6"
110
+ "gitHead": "aab868aa0c30949832fe2c4b9cb109c204442e39"
113
111
  }
@@ -5,7 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const devkit_1 = require("@nx/devkit");
6
6
  const webpack_nx_build_coordination_plugin_1 = require("@nx/webpack/src/plugins/webpack-nx-build-coordination-plugin");
7
7
  const fs_1 = require("fs");
8
- const file_utils_1 = require("nx/src/project-graph/file-utils");
8
+ const configuration_1 = require("nx/src/config/configuration");
9
9
  const operators_1 = require("nx/src/project-graph/operators");
10
10
  const utils_1 = require("nx/src/tasks-runner/utils");
11
11
  const rxjs_1 = require("rxjs");
@@ -15,7 +15,7 @@ const webpack_1 = require("../utilities/webpack");
15
15
  const validate_options_1 = require("./validate-options");
16
16
  function shouldSkipInitialTargetRun(projectGraph, project, target) {
17
17
  var _a;
18
- const nxJson = (0, file_utils_1.readNxJson)();
18
+ const nxJson = (0, configuration_1.readNxJson)();
19
19
  const defaultDependencyConfigs = Object.entries((_a = nxJson.targetDefaults) !== null && _a !== void 0 ? _a : {}).reduce((acc, [targetName, dependencyConfig]) => {
20
20
  acc[targetName] = dependencyConfig.dependsOn;
21
21
  return acc;
@@ -6,7 +6,7 @@ const devkit_1 = require("@nx/devkit");
6
6
  const buildable_libs_utils_1 = require("@nx/js/src/utils/buildable-libs-utils");
7
7
  function delegateBuildExecutor(options, context) {
8
8
  return tslib_1.__asyncGenerator(this, arguments, function* delegateBuildExecutor_1() {
9
- const { target, dependencies } = (0, buildable_libs_utils_1.calculateProjectDependencies)(context.projectGraph, context.root, context.projectName, context.targetName, context.configurationName);
9
+ const { target, dependencies } = (0, buildable_libs_utils_1.calculateProjectBuildableDependencies)(context.taskGraph, context.projectGraph, context.root, context.projectName, context.targetName, context.configurationName);
10
10
  options.tsConfig = (0, buildable_libs_utils_1.createTmpTsConfig)((0, devkit_1.joinPathFragments)(context.root, options.tsConfig), context.root, target.data.root, dependencies);
11
11
  if (!(0, buildable_libs_utils_1.checkDependentProjectsHaveBeenBuilt)(context.root, context.projectName, context.targetName, dependencies)) {
12
12
  return yield tslib_1.__await({ success: false });
@@ -39,7 +39,7 @@ function initializeNgPackagr(options, context, projectDependencies) {
39
39
  function createLibraryExecutor(initializeNgPackagr) {
40
40
  return function (options, context) {
41
41
  return tslib_1.__asyncGenerator(this, arguments, function* () {
42
- const { target, dependencies, topLevelDependencies } = (0, buildable_libs_utils_1.calculateProjectDependencies)(context.projectGraph, context.root, context.projectName, context.targetName, context.configurationName);
42
+ const { target, dependencies, topLevelDependencies } = (0, buildable_libs_utils_1.calculateProjectBuildableDependencies)(context.taskGraph, context.projectGraph, context.root, context.projectName, context.targetName, context.configurationName);
43
43
  if (!(0, buildable_libs_utils_1.checkDependentProjectsHaveBeenBuilt)(context.root, context.projectName, context.targetName, dependencies)) {
44
44
  return yield tslib_1.__await(Promise.resolve({ success: false }));
45
45
  }
@@ -17,6 +17,8 @@ function componentStoryGenerator(tree, options) {
17
17
  (0, devkit_1.generateFiles)(tree, templatesDir, destinationDir, {
18
18
  componentFileName: componentFileName,
19
19
  componentName: componentName,
20
+ componentNameSimple: componentFileName.replace('.component', ''),
21
+ interactionTests: options.interactionTests,
20
22
  props: props.filter((p) => typeof p.defaultValue !== 'undefined'),
21
23
  tmpl: '',
22
24
  });
@@ -1,16 +1,31 @@
1
- import { Meta } from '@storybook/angular';
1
+ import type { Meta, StoryObj } from '@storybook/angular';
2
2
  import { <%=componentName%> } from './<%=componentFileName%>';
3
+ <% if ( interactionTests ) { %>
4
+ import { within } from '@storybook/testing-library';
5
+ import { expect } from '@storybook/jest';
6
+ <% } %>
3
7
 
4
- export default {
5
- title: '<%=componentName%>',
6
- component: <%=componentName%>
7
- } as Meta<<%=componentName%>>;
8
+ const meta: Meta<<%= componentName %>> = {
9
+ component: <%= componentName %>,
10
+ title: '<%= componentName %>',
11
+ };
12
+ export default meta;
13
+ type Story = StoryObj<<%=componentName%>>;
8
14
 
9
- export const Primary = {
10
- render: (args: <%=componentName%>) => ({
11
- props: args,
12
- }),
15
+ export const Primary: Story = {
13
16
  args: {<% for (let prop of props) { %>
14
17
  <%= prop.name %>: <%- prop.defaultValue %>,<% } %>
15
18
  },
16
- };
19
+ };
20
+
21
+ <% if ( interactionTests ) { %>
22
+ export const Heading: Story = {
23
+ args: {<% for (let prop of props) { %>
24
+ <%= prop.name %>: <%- prop.defaultValue %>,<% } %>
25
+ },
26
+ play: async ({ canvasElement }) => {
27
+ const canvas = within(canvasElement);
28
+ expect(canvas.getByText(/<%=componentNameSimple%> works!/gi)).toBeTruthy();
29
+ },
30
+ };
31
+ <% } %>
@@ -1,5 +1,6 @@
1
1
  export interface ComponentStoryGeneratorOptions {
2
2
  projectPath: string;
3
+ interactionTests?: boolean;
3
4
  componentName: string;
4
5
  componentPath: string;
5
6
  componentFileName: string;
@@ -29,6 +29,13 @@
29
29
  "examples": ["awesome.component"],
30
30
  "x-priority": "important"
31
31
  },
32
+ "interactionTests": {
33
+ "type": "boolean",
34
+ "description": "Set up Storybook interaction tests.",
35
+ "x-prompt": "Do you want to set up Storybook interaction tests?",
36
+ "x-priority": "important",
37
+ "default": true
38
+ },
32
39
  "skipFormat": {
33
40
  "description": "Skip formatting files.",
34
41
  "type": "boolean",
@@ -1,7 +1,8 @@
1
1
  export interface StoriesGeneratorOptions {
2
2
  name: string;
3
- cypressProject?: string;
4
- generateCypressSpecs?: boolean;
3
+ interactionTests?: boolean;
5
4
  skipFormat?: boolean;
6
5
  ignorePaths?: string[];
6
+ cypressProject?: string;
7
+ generateCypressSpecs?: boolean;
7
8
  }
@@ -18,11 +18,16 @@
18
18
  "x-dropdown": "projects",
19
19
  "x-priority": "important"
20
20
  },
21
+ "interactionTests": {
22
+ "type": "boolean",
23
+ "description": "Set up Storybook interaction tests.",
24
+ "x-prompt": "Do you want to set up Storybook interaction tests?",
25
+ "x-priority": "important",
26
+ "default": true
27
+ },
21
28
  "generateCypressSpecs": {
22
29
  "type": "boolean",
23
- "description": "Specifies whether to automatically generate `*.spec.ts` files in the Cypress e2e app generated by the `cypress-configure` generator.",
24
- "x-prompt": "Do you want to generate Cypress specs as well?",
25
- "x-priority": "important"
30
+ "description": "Specifies whether to automatically generate `*.spec.ts` files in the Cypress e2e app generated by the `cypress-configure` generator."
26
31
  },
27
32
  "cypressProject": {
28
33
  "type": "string",
@@ -1,4 +1,4 @@
1
- import { Tree } from '@nx/devkit';
1
+ import { GeneratorCallback, Tree } from '@nx/devkit';
2
2
  import type { StoriesGeneratorOptions } from './schema';
3
- export declare function angularStoriesGenerator(tree: Tree, options: StoriesGeneratorOptions): Promise<void>;
3
+ export declare function angularStoriesGenerator(tree: Tree, options: StoriesGeneratorOptions): Promise<GeneratorCallback>;
4
4
  export default angularStoriesGenerator;
@@ -10,8 +10,9 @@ const entry_point_1 = require("../utils/storybook-ast/entry-point");
10
10
  const get_e2e_project_1 = require("./lib/get-e2e-project");
11
11
  const module_info_1 = require("../utils/storybook-ast/module-info");
12
12
  const minimatch = require("minimatch");
13
+ const versions_1 = require("../../utils/versions");
13
14
  function angularStoriesGenerator(tree, options) {
14
- var _a;
15
+ var _a, _b;
15
16
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
16
17
  const e2eProjectName = (_a = options.cypressProject) !== null && _a !== void 0 ? _a : `${options.name}-e2e`;
17
18
  const e2eProject = (0, get_e2e_project_1.getE2EProject)(tree, e2eProjectName);
@@ -40,6 +41,7 @@ function angularStoriesGenerator(tree, options) {
40
41
  componentName: info.name,
41
42
  componentPath: info.path,
42
43
  componentFileName: info.componentFileName,
44
+ interactionTests: (_b = options.interactionTests) !== null && _b !== void 0 ? _b : true,
43
45
  skipFormat: true,
44
46
  });
45
47
  if (options.generateCypressSpecs && e2eProject) {
@@ -55,9 +57,17 @@ function angularStoriesGenerator(tree, options) {
55
57
  });
56
58
  }
57
59
  }
60
+ const tasks = [];
61
+ if (options.interactionTests) {
62
+ const { interactionTestsDependencies, addInteractionsInAddons } = (0, devkit_1.ensurePackage)('@nx/storybook', versions_1.nxVersion);
63
+ const projectConfiguration = (0, devkit_1.readProjectConfiguration)(tree, options.name);
64
+ addInteractionsInAddons(tree, projectConfiguration);
65
+ tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, interactionTestsDependencies()));
66
+ }
58
67
  if (!options.skipFormat) {
59
68
  yield (0, devkit_1.formatFiles)(tree);
60
69
  }
70
+ return (0, devkit_1.runTasksInSerial)(...tasks);
61
71
  });
62
72
  }
63
73
  exports.angularStoriesGenerator = angularStoriesGenerator;
@@ -14,6 +14,7 @@ function generateStories(tree, options) {
14
14
  generateCypressSpecs: options.configureCypress && options.generateCypressSpecs,
15
15
  cypressProject: e2eProjectName,
16
16
  ignorePaths: options.ignorePaths,
17
+ interactionTests: options.interactionTests,
17
18
  skipFormat: true,
18
19
  });
19
20
  });
@@ -1,15 +1,15 @@
1
1
  import type { Linter } from '@nx/linter';
2
2
 
3
3
  export interface StorybookConfigurationOptions {
4
- configureCypress: boolean;
5
4
  configureStaticServe?: boolean;
6
- generateCypressSpecs: boolean;
7
5
  generateStories: boolean;
8
6
  linter: Linter;
9
7
  name: string;
10
- cypressDirectory?: string;
11
8
  tsConfiguration?: boolean;
12
9
  skipFormat?: boolean;
13
10
  ignorePaths?: string[];
14
11
  interactionTests?: boolean;
12
+ configureCypress?: boolean;
13
+ generateCypressSpecs?: boolean;
14
+ cypressDirectory?: string;
15
15
  }
@@ -28,8 +28,7 @@
28
28
  },
29
29
  "configureCypress": {
30
30
  "type": "boolean",
31
- "description": "Specifies whether to configure Cypress or not.",
32
- "x-deprecated": "Please use Storybook interaction tests instead."
31
+ "description": "Specifies whether to configure Cypress or not."
33
32
  },
34
33
  "generateStories": {
35
34
  "type": "boolean",
@@ -40,8 +39,7 @@
40
39
  },
41
40
  "generateCypressSpecs": {
42
41
  "type": "boolean",
43
- "description": "Specifies whether to automatically generate test files in the generated Cypress e2e app.",
44
- "x-deprecated": "Please use Storybook interaction tests instead."
42
+ "description": "Specifies whether to automatically generate test files in the generated Cypress e2e app."
45
43
  },
46
44
  "configureStaticServe": {
47
45
  "type": "boolean",
@@ -52,8 +50,7 @@
52
50
  },
53
51
  "cypressDirectory": {
54
52
  "type": "string",
55
- "description": "A directory where the Cypress project will be placed. Placed at the root by default.",
56
- "x-deprecated": "Please use Storybook interaction tests instead."
53
+ "description": "A directory where the Cypress project will be placed. Placed at the root by default."
57
54
  },
58
55
  "linter": {
59
56
  "description": "The tool to use for running lint checks.",
@@ -7,13 +7,15 @@ const assert_compatible_storybook_version_1 = require("./lib/assert-compatible-s
7
7
  const generate_stories_1 = require("./lib/generate-stories");
8
8
  const generate_storybook_configuration_1 = require("./lib/generate-storybook-configuration");
9
9
  const validate_options_1 = require("./lib/validate-options");
10
+ // TODO(v18): remove Cypress
10
11
  function storybookConfigurationGenerator(tree, options) {
12
+ var _a, _b, _c;
11
13
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
12
14
  (0, assert_compatible_storybook_version_1.assertCompatibleStorybookVersion)();
13
15
  (0, validate_options_1.validateOptions)(options);
14
- const storybookGeneratorInstallTask = yield (0, generate_storybook_configuration_1.generateStorybookConfiguration)(tree, options);
16
+ const storybookGeneratorInstallTask = yield (0, generate_storybook_configuration_1.generateStorybookConfiguration)(tree, Object.assign(Object.assign({}, options), { interactionTests: (_a = options.interactionTests) !== null && _a !== void 0 ? _a : true, tsConfiguration: (_b = options.tsConfiguration) !== null && _b !== void 0 ? _b : true }));
15
17
  if (options.generateStories) {
16
- yield (0, generate_stories_1.generateStories)(tree, Object.assign(Object.assign({}, options), { skipFormat: true }));
18
+ yield (0, generate_stories_1.generateStories)(tree, Object.assign(Object.assign({}, options), { interactionTests: (_c = options.interactionTests) !== null && _c !== void 0 ? _c : true, skipFormat: true }));
17
19
  }
18
20
  if (!options.skipFormat) {
19
21
  yield (0, devkit_1.formatFiles)(tree);
@@ -1,12 +1,12 @@
1
1
  import type { Tree } from '@nx/devkit';
2
2
  import type { PropertyDeclaration } from 'typescript';
3
- export type KnobType = 'text' | 'boolean' | 'number' | 'select';
3
+ export type ArgType = 'text' | 'boolean' | 'number' | 'select';
4
4
  export interface InputDescriptor {
5
5
  name: string;
6
- type: KnobType;
6
+ type: ArgType;
7
7
  defaultValue?: string;
8
8
  }
9
9
  export declare function getInputPropertyDeclarations(tree: Tree, path: string): PropertyDeclaration[];
10
10
  export declare function getComponentProps(tree: Tree, componentPath: string, getArgsDefaultValueFn?: (property: PropertyDeclaration) => string | undefined, useDecoratorName?: boolean): InputDescriptor[];
11
- export declare function getKnobType(property: PropertyDeclaration): KnobType;
11
+ export declare function getArgType(property: PropertyDeclaration): ArgType;
12
12
  export declare function getArgsDefaultValue(property: PropertyDeclaration): string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getArgsDefaultValue = exports.getKnobType = exports.getComponentProps = exports.getInputPropertyDeclarations = void 0;
3
+ exports.getArgsDefaultValue = exports.getArgType = exports.getComponentProps = exports.getInputPropertyDeclarations = void 0;
4
4
  const js_1 = require("@nx/js");
5
5
  const ast_utils_1 = require("../../../utils/nx-devkit/ast-utils");
6
6
  const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript");
@@ -27,7 +27,7 @@ function getComponentProps(tree, componentPath, getArgsDefaultValueFn = getArgsD
27
27
  ? decoratorContent[0].getText().slice(1, -1)
28
28
  : node.name.getText()
29
29
  : node.name.getText();
30
- const type = getKnobType(node);
30
+ const type = getArgType(node);
31
31
  const defaultValue = getArgsDefaultValueFn(node);
32
32
  return {
33
33
  name,
@@ -38,31 +38,31 @@ function getComponentProps(tree, componentPath, getArgsDefaultValueFn = getArgsD
38
38
  return props;
39
39
  }
40
40
  exports.getComponentProps = getComponentProps;
41
- function getKnobType(property) {
41
+ function getArgType(property) {
42
42
  if (!tsModule) {
43
43
  tsModule = (0, ensure_typescript_1.ensureTypescript)();
44
44
  }
45
45
  if (property.type) {
46
46
  const typeName = property.type.getText();
47
- const typeNameToKnobType = {
47
+ const typeNameToArgType = {
48
48
  string: 'text',
49
49
  number: 'number',
50
50
  boolean: 'boolean',
51
51
  };
52
- return typeNameToKnobType[typeName] || 'text';
52
+ return typeNameToArgType[typeName] || 'text';
53
53
  }
54
54
  if (property.initializer) {
55
- const initializerKindToKnobType = {
55
+ const initializerKindToArgType = {
56
56
  [tsModule.SyntaxKind.StringLiteral]: 'text',
57
57
  [tsModule.SyntaxKind.NumericLiteral]: 'number',
58
58
  [tsModule.SyntaxKind.TrueKeyword]: 'boolean',
59
59
  [tsModule.SyntaxKind.FalseKeyword]: 'boolean',
60
60
  };
61
- return initializerKindToKnobType[property.initializer.kind] || 'text';
61
+ return initializerKindToArgType[property.initializer.kind] || 'text';
62
62
  }
63
63
  return 'text';
64
64
  }
65
- exports.getKnobType = getKnobType;
65
+ exports.getArgType = getArgType;
66
66
  function getArgsDefaultValue(property) {
67
67
  const typeNameToDefault = {
68
68
  string: "''",