@nx/js 17.2.0-beta.0 → 17.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/js",
3
- "version": "17.2.0-beta.0",
3
+ "version": "17.2.0-beta.2",
4
4
  "private": false,
5
5
  "description": "The JS plugin for Nx contains executors and generators that provide the best experience for developing JavaScript and TypeScript projects. ",
6
6
  "repository": {
@@ -57,9 +57,9 @@
57
57
  "semver": "7.5.3",
58
58
  "source-map-support": "0.5.19",
59
59
  "tslib": "^2.3.0",
60
- "@nx/devkit": "17.2.0-beta.0",
61
- "@nx/workspace": "17.2.0-beta.0",
62
- "@nrwl/js": "17.2.0-beta.0"
60
+ "@nx/devkit": "17.2.0-beta.2",
61
+ "@nx/workspace": "17.2.0-beta.2",
62
+ "@nrwl/js": "17.2.0-beta.2"
63
63
  },
64
64
  "peerDependencies": {
65
65
  "verdaccio": "^5.0.4"
@@ -39,6 +39,9 @@ async function runExecutor(options, context) {
39
39
  if (options.tag) {
40
40
  npmPublishCommandSegments.push(`--tag=${options.tag}`);
41
41
  }
42
+ if (options.otp) {
43
+ npmPublishCommandSegments.push(`--otp=${options.otp}`);
44
+ }
42
45
  if (options.dryRun) {
43
46
  npmPublishCommandSegments.push(`--dry-run`);
44
47
  }
@@ -2,5 +2,6 @@ export interface PublishExecutorSchema {
2
2
  packageRoot?: string;
3
3
  registry?: string;
4
4
  tag?: string;
5
+ otp?: number;
5
6
  dryRun?: boolean;
6
7
  }
@@ -1,4 +1,5 @@
1
1
  import { Tree } from '@nx/devkit';
2
+ import { VersionData } from 'nx/src/command-line/release/version';
2
3
  import { ReleaseVersionGeneratorSchema } from './schema';
3
- export declare function releaseVersionGenerator(tree: Tree, options: ReleaseVersionGeneratorSchema): Promise<void>;
4
+ export declare function releaseVersionGenerator(tree: Tree, options: ReleaseVersionGeneratorSchema): Promise<VersionData>;
4
5
  export default releaseVersionGenerator;
@@ -4,6 +4,7 @@ exports.releaseVersionGenerator = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const chalk = require("chalk");
6
6
  const child_process_1 = require("child_process");
7
+ const config_1 = require("nx/src/command-line/release/config/config");
7
8
  const git_1 = require("nx/src/command-line/release/utils/git");
8
9
  const resolve_semver_specifier_1 = require("nx/src/command-line/release/utils/resolve-semver-specifier");
9
10
  const semver_1 = require("nx/src/command-line/release/utils/semver");
@@ -15,23 +16,28 @@ const semver_2 = require("semver");
15
16
  const resolve_local_package_dependencies_1 = require("./utils/resolve-local-package-dependencies");
16
17
  async function releaseVersionGenerator(tree, options) {
17
18
  try {
19
+ const versionData = {};
18
20
  // If the user provided a specifier, validate that it is valid semver or a relative semver keyword
19
21
  if (options.specifier && !(0, semver_1.isValidSemverSpecifier)(options.specifier)) {
20
22
  throw new Error(`The given version specifier "${options.specifier}" is not valid. You provide an exact version or a valid semver keyword such as "major", "minor", "patch", etc.`);
21
23
  }
22
24
  const projects = options.projects;
25
+ const createResolvePackageRoot = (customPackageRoot) => (projectNode) => {
26
+ // Default to the project root if no custom packageRoot
27
+ if (!customPackageRoot) {
28
+ return projectNode.data.root;
29
+ }
30
+ return (0, utils_1.interpolate)(customPackageRoot, {
31
+ workspaceRoot: '',
32
+ projectRoot: projectNode.data.root,
33
+ projectName: projectNode.name,
34
+ });
35
+ };
36
+ const resolvePackageRoot = createResolvePackageRoot(options.packageRoot);
23
37
  // Resolve any custom package roots for each project upfront as they will need to be reused during dependency resolution
24
38
  const projectNameToPackageRootMap = new Map();
25
39
  for (const project of projects) {
26
- projectNameToPackageRootMap.set(project.name,
27
- // Default to the project root if no custom packageRoot
28
- !options.packageRoot
29
- ? project.data.root
30
- : (0, utils_1.interpolate)(options.packageRoot, {
31
- workspaceRoot: '',
32
- projectRoot: project.data.root,
33
- projectName: project.name,
34
- }));
40
+ projectNameToPackageRootMap.set(project.name, resolvePackageRoot(project));
35
41
  }
36
42
  let currentVersion;
37
43
  // only used for options.currentVersionResolver === 'git-tag', but
@@ -65,8 +71,12 @@ To fix this you will either need to add a package.json file at that location, or
65
71
  (await getNpmRegistry()) ??
66
72
  'https://registry.npmjs.org';
67
73
  const tag = metadata?.tag ?? 'latest';
68
- // If the currentVersionResolver is set to registry, we only want to make the request once for the whole batch of projects
69
- if (!currentVersion) {
74
+ /**
75
+ * If the currentVersionResolver is set to registry, and the projects are not independent, we only want to make the request once for the whole batch of projects.
76
+ * For independent projects, we need to make a request for each project individually as they will most likely have different versions.
77
+ */
78
+ if (!currentVersion ||
79
+ options.releaseGroup.projectsRelationship === 'independent') {
70
80
  const spinner = ora(`${Array.from(new Array(projectName.length + 3)).join(' ')}Resolving the current version for tag "${tag}" on ${registry}`);
71
81
  spinner.color =
72
82
  color.spinnerColor;
@@ -96,13 +106,15 @@ To fix this you will either need to add a package.json file at that location, or
96
106
  log(`📄 Resolved the current version as ${currentVersion} from ${packageJsonPath}`);
97
107
  break;
98
108
  case 'git-tag': {
99
- if (!currentVersion) {
109
+ if (!currentVersion ||
110
+ // We always need to independently resolve the current version from git tag per project if the projects are independent
111
+ options.releaseGroup.projectsRelationship === 'independent') {
100
112
  const releaseTagPattern = options.releaseGroup.releaseTagPattern;
101
113
  latestMatchingGitTag = await (0, git_1.getLatestGitTagForPattern)(releaseTagPattern, {
102
114
  projectName: project.name,
103
115
  });
104
116
  if (!latestMatchingGitTag) {
105
- throw new Error(`No git tags matching pattern "${releaseTagPattern}" for project "${project.name}" were found.`);
117
+ throw new Error(`No git tags matching pattern "${releaseTagPattern}" for project "${project.name}" were found. You will need to create an initial matching tag to use as a base for determining the next version.`);
106
118
  }
107
119
  currentVersion = latestMatchingGitTag.extractedVersion;
108
120
  log(`📄 Resolved the current version as ${currentVersion} from git tag "${latestMatchingGitTag.tag}".`);
@@ -118,8 +130,19 @@ To fix this you will either need to add a package.json file at that location, or
118
130
  if (options.specifier) {
119
131
  log(`📄 Using the provided version specifier "${options.specifier}".`);
120
132
  }
121
- // if specifier is null, then we determined previously via conventional commits that no changes are necessary
122
- if (specifier === undefined) {
133
+ /**
134
+ * If we are versioning independently then we always need to determine the specifier for each project individually, except
135
+ * for the case where the user has provided an explicit specifier on the command.
136
+ *
137
+ * Otherwise, if versioning the projects together we only need to perform this logic if the specifier is still unset from
138
+ * previous iterations of the loop.
139
+ *
140
+ * NOTE: In the case that we have previously determined via conventional commits that no changes are necessary, the specifier
141
+ * will be explicitly set to `null`, so that is why we only check for `undefined` explicitly here.
142
+ */
143
+ if (specifier === undefined ||
144
+ (options.releaseGroup.projectsRelationship === 'independent' &&
145
+ !options.specifier)) {
123
146
  const specifierSource = options.specifierSource;
124
147
  switch (specifierSource) {
125
148
  case 'conventional-commits':
@@ -131,6 +154,8 @@ To fix this you will either need to add a package.json file at that location, or
131
154
  log(`🚫 No changes were detected using git history and the conventional commits standard.`);
132
155
  break;
133
156
  }
157
+ // TODO: reevaluate this logic/workflow for independent projects
158
+ //
134
159
  // Always assume that if the current version is a prerelease, then the next version should be a prerelease.
135
160
  // Users must manually graduate from a prerelease to a release by providing an explicit specifier.
136
161
  if ((0, semver_2.prerelease)(currentVersion)) {
@@ -141,9 +166,22 @@ To fix this you will either need to add a package.json file at that location, or
141
166
  log(`📄 Resolved the specifier as "${specifier}" using git history and the conventional commits standard.`);
142
167
  }
143
168
  break;
144
- case 'prompt':
145
- specifier = await (0, resolve_semver_specifier_1.resolveSemverSpecifierFromPrompt)(`What kind of change is this for the ${projects.length} matched projects(s) within release group "${options.releaseGroup.name}"?`, `What is the exact version for the ${projects.length} matched project(s) within release group "${options.releaseGroup.name}"?`);
169
+ case 'prompt': {
170
+ // Only add the release group name to the log if it is one set by the user, otherwise it is useless noise
171
+ const maybeLogReleaseGroup = (log) => {
172
+ if (options.releaseGroup.name === config_1.CATCH_ALL_RELEASE_GROUP) {
173
+ return log;
174
+ }
175
+ return `${log} within release group "${options.releaseGroup.name}"`;
176
+ };
177
+ if (options.releaseGroup.projectsRelationship === 'independent') {
178
+ specifier = await (0, resolve_semver_specifier_1.resolveSemverSpecifierFromPrompt)(`${maybeLogReleaseGroup(`What kind of change is this for project "${projectName}"`)}?`, `${maybeLogReleaseGroup(`What is the exact version for project "${projectName}"`)}?`);
179
+ }
180
+ else {
181
+ specifier = await (0, resolve_semver_specifier_1.resolveSemverSpecifierFromPrompt)(`${maybeLogReleaseGroup(`What kind of change is this for the ${projects.length} matched projects(s)`)}?`, `${maybeLogReleaseGroup(`What is the exact version for the ${projects.length} matched project(s)`)}?`);
182
+ }
146
183
  break;
184
+ }
147
185
  default:
148
186
  throw new Error(`Invalid specifierSource "${specifierSource}" provided. Must be one of "prompt" or "conventional-commits"`);
149
187
  }
@@ -153,7 +191,9 @@ To fix this you will either need to add a package.json file at that location, or
153
191
  continue;
154
192
  }
155
193
  // Resolve any local package dependencies for this project (before applying the new version)
156
- const localPackageDependencies = (0, resolve_local_package_dependencies_1.resolveLocalPackageDependencies)(tree, options.projectGraph, projects, projectNameToPackageRootMap);
194
+ const localPackageDependencies = (0, resolve_local_package_dependencies_1.resolveLocalPackageDependencies)(tree, options.projectGraph, projects, projectNameToPackageRootMap, resolvePackageRoot,
195
+ // includeAll when the release group is independent, as we may be filtering to a specific subset of projects, but we still want to update their dependents
196
+ options.releaseGroup.projectsRelationship === 'independent');
157
197
  const newVersion = (0, version_1.deriveNewSemverVersion)(currentVersion, specifier, options.preid);
158
198
  (0, devkit_1.writeJson)(tree, packageJsonPath, {
159
199
  ...projectPackageJson,
@@ -177,7 +217,19 @@ To fix this you will either need to add a package.json file at that location, or
177
217
  return json;
178
218
  });
179
219
  }
220
+ versionData[projectName] = {
221
+ currentVersion,
222
+ newVersion,
223
+ dependentProjects,
224
+ };
180
225
  }
226
+ /**
227
+ * Ensure that formatting is applied so that version bump diffs are as mimimal as possible
228
+ * within the context of the user's workspace.
229
+ */
230
+ await (0, devkit_1.formatFiles)(tree);
231
+ // Return the version data so that it can be leveraged by the overall version command
232
+ return versionData;
181
233
  }
182
234
  catch (e) {
183
235
  if (process.env.NX_VERBOSE_LOGGING === 'true') {
@@ -2,5 +2,5 @@ import { ProjectGraph, ProjectGraphDependency, ProjectGraphProjectNode, Tree } f
2
2
  interface LocalPackageDependency extends ProjectGraphDependency {
3
3
  dependencyCollection: 'dependencies' | 'devDependencies' | 'optionalDependencies';
4
4
  }
5
- export declare function resolveLocalPackageDependencies(tree: Tree, projectGraph: ProjectGraph, projects: ProjectGraphProjectNode[], projectNameToPackageRootMap: Map<string, string>): Record<string, LocalPackageDependency[]>;
5
+ export declare function resolveLocalPackageDependencies(tree: Tree, projectGraph: ProjectGraph, filteredProjects: ProjectGraphProjectNode[], projectNameToPackageRootMap: Map<string, string>, resolvePackageRoot: (projectNode: ProjectGraphProjectNode) => string, includeAll?: boolean): Record<string, LocalPackageDependency[]>;
6
6
  export {};
@@ -5,15 +5,24 @@ const devkit_1 = require("@nx/devkit");
5
5
  const semver_1 = require("semver");
6
6
  const package_1 = require("./package");
7
7
  const resolve_version_spec_1 = require("./resolve-version-spec");
8
- function resolveLocalPackageDependencies(tree, projectGraph, projects, projectNameToPackageRootMap) {
8
+ function resolveLocalPackageDependencies(tree, projectGraph, filteredProjects, projectNameToPackageRootMap, resolvePackageRoot, includeAll = false) {
9
9
  const localPackageDependencies = {};
10
10
  const projectNodeToPackageMap = new Map();
11
+ const projects = includeAll
12
+ ? Object.values(projectGraph.nodes)
13
+ : filteredProjects;
11
14
  // Iterate through the projects being released and resolve any relevant package.json data
12
15
  for (const projectNode of projects) {
13
16
  // Resolve the package.json path for the project, taking into account any custom packageRoot settings
14
- const packageRoot = projectNameToPackageRootMap.get(projectNode.name);
15
- if (!packageRoot) {
16
- continue;
17
+ let packageRoot = projectNameToPackageRootMap.get(projectNode.name);
18
+ // packageRoot wasn't added to the map yet, try to resolve it dynamically
19
+ if (!packageRoot && includeAll) {
20
+ packageRoot = resolvePackageRoot(projectNode);
21
+ if (!packageRoot) {
22
+ continue;
23
+ }
24
+ // Append it to the map for later use within the release version generator
25
+ projectNameToPackageRootMap.set(projectNode.name, packageRoot);
17
26
  }
18
27
  const packageJsonPath = (0, devkit_1.joinPathFragments)(packageRoot, 'package.json');
19
28
  if (!tree.exists(packageJsonPath)) {
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.findNpmDependencies = void 0;
4
4
  const path_1 = require("path");
5
5
  const configuration_1 = require("nx/src/config/configuration");
6
- const task_hasher_1 = require("nx/src/hasher/task-hasher");
7
6
  const devkit_1 = require("@nx/devkit");
8
7
  const fileutils_1 = require("nx/src/utils/fileutils");
9
8
  const project_graph_1 = require("nx/src/config/project-graph");
10
9
  const ts_config_1 = require("./typescript/ts-config");
10
+ const task_hasher_1 = require("nx/src/hasher/task-hasher");
11
11
  /**
12
12
  * Finds all npm dependencies and their expected versions for a given project.
13
13
  */