@nx/js 19.7.0 → 19.7.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": "19.7.0",
3
+ "version": "19.7.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": {
@@ -39,8 +39,8 @@
39
39
  "@babel/preset-env": "^7.23.2",
40
40
  "@babel/preset-typescript": "^7.22.5",
41
41
  "@babel/runtime": "^7.22.6",
42
- "@nx/devkit": "19.7.0",
43
- "@nx/workspace": "19.7.0",
42
+ "@nx/devkit": "19.7.2",
43
+ "@nx/workspace": "19.7.2",
44
44
  "babel-plugin-const-enum": "^1.0.1",
45
45
  "babel-plugin-macros": "^2.8.0",
46
46
  "babel-plugin-transform-typescript-metadata": "^0.3.1",
@@ -61,7 +61,7 @@
61
61
  "ts-node": "10.9.1",
62
62
  "tsconfig-paths": "^4.1.2",
63
63
  "tslib": "^2.3.0",
64
- "@nrwl/js": "19.7.0"
64
+ "@nrwl/js": "19.7.2"
65
65
  },
66
66
  "peerDependencies": {
67
67
  "verdaccio": "^5.0.4"
@@ -5,10 +5,11 @@ const devkit_1 = require("@nx/devkit");
5
5
  const child_process_1 = require("child_process");
6
6
  const npm_run_path_1 = require("npm-run-path");
7
7
  const path_1 = require("path");
8
+ const is_locally_linked_package_version_1 = require("../../utils/is-locally-linked-package-version");
8
9
  const npm_config_1 = require("../../utils/npm-config");
10
+ const extract_npm_publish_json_data_1 = require("./extract-npm-publish-json-data");
9
11
  const log_tar_1 = require("./log-tar");
10
12
  const chalk = require("chalk");
11
- const extract_npm_publish_json_data_1 = require("./extract-npm-publish-json-data");
12
13
  const LARGE_BUFFER = 1024 * 1000000;
13
14
  function processEnv(color) {
14
15
  const env = {
@@ -21,6 +22,7 @@ function processEnv(color) {
21
22
  return env;
22
23
  }
23
24
  async function runExecutor(options, context) {
25
+ const pm = (0, devkit_1.detectPackageManager)();
24
26
  /**
25
27
  * We need to check both the env var and the option because the executor may have been triggered
26
28
  * indirectly via dependsOn, in which case the env var will be set, but the option will not.
@@ -31,6 +33,28 @@ async function runExecutor(options, context) {
31
33
  const packageJsonPath = (0, path_1.join)(packageRoot, 'package.json');
32
34
  const packageJson = (0, devkit_1.readJsonFile)(packageJsonPath);
33
35
  const packageName = packageJson.name;
36
+ /**
37
+ * pnpm supports dynamically updating locally linked packages during its packing phase, but other package managers do not.
38
+ * Therefore, protect the user from publishing invalid packages by checking if it contains local dependency protocols.
39
+ */
40
+ if (pm !== 'pnpm') {
41
+ const depTypes = ['dependencies', 'devDependencies', 'peerDependencies'];
42
+ for (const depType of depTypes) {
43
+ const deps = packageJson[depType];
44
+ if (deps) {
45
+ for (const depName in deps) {
46
+ if ((0, is_locally_linked_package_version_1.isLocallyLinkedPackageVersion)(deps[depName])) {
47
+ console.error(`Error: Cannot publish package "${packageName}" because it contains a local dependency protocol in its "${depType}", and your package manager is ${pm}.
48
+
49
+ Please update the local dependency on "${depName}" to be a valid semantic version (e.g. using \`nx release\`) before publishing, or switch to pnpm as a package manager, which supports dynamically replacing these protocols during publishing.`);
50
+ return {
51
+ success: false,
52
+ };
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
34
58
  // If package and project name match, we can make log messages terser
35
59
  let packageTxt = packageName === context.projectName
36
60
  ? `package "${packageName}"`
@@ -63,7 +87,7 @@ async function runExecutor(options, context) {
63
87
  * request with.
64
88
  *
65
89
  * Therefore, so as to not produce misleading output in dry around dist-tags being altered, we do not
66
- * perform the npm view step, and just show npm publish's dry-run output.
90
+ * perform the npm view step, and just show npm/pnpm publish's dry-run output.
67
91
  */
68
92
  if (!isDryRun && !options.firstRelease) {
69
93
  const currentVersion = packageJson.version;
@@ -154,35 +178,38 @@ async function runExecutor(options, context) {
154
178
  }
155
179
  /**
156
180
  * NOTE: If this is ever changed away from running the command at the workspace root and pointing at the package root (e.g. back
157
- * to running from the package root directly), then special attention should be paid to the fact that npm publish will nest its
181
+ * to running from the package root directly), then special attention should be paid to the fact that npm/pnpm publish will nest its
158
182
  * JSON output under the name of the package in that case (and it would need to be handled below).
159
183
  */
160
- const npmPublishCommandSegments = [
161
- `npm publish "${packageRoot}" --json --"${registryConfigKey}=${registry}" --tag=${tag}`,
184
+ const publishCommandSegments = [
185
+ pm === 'pnpm'
186
+ ? // Unlike npm, pnpm publish does not support a custom registryConfigKey option, and will error on uncommitted changes by default if --no-git-checks is not set
187
+ `pnpm publish "${packageRoot}" --json --registry="${registry}" --tag=${tag} --no-git-checks`
188
+ : `npm publish "${packageRoot}" --json --"${registryConfigKey}=${registry}" --tag=${tag}`,
162
189
  ];
163
190
  if (options.otp) {
164
- npmPublishCommandSegments.push(`--otp=${options.otp}`);
191
+ publishCommandSegments.push(`--otp=${options.otp}`);
165
192
  }
166
193
  if (options.access) {
167
- npmPublishCommandSegments.push(`--access=${options.access}`);
194
+ publishCommandSegments.push(`--access=${options.access}`);
168
195
  }
169
196
  if (isDryRun) {
170
- npmPublishCommandSegments.push(`--dry-run`);
197
+ publishCommandSegments.push(`--dry-run`);
171
198
  }
172
199
  try {
173
- const output = (0, child_process_1.execSync)(npmPublishCommandSegments.join(' '), {
200
+ const output = (0, child_process_1.execSync)(publishCommandSegments.join(' '), {
174
201
  maxBuffer: LARGE_BUFFER,
175
202
  env: processEnv(true),
176
203
  cwd: context.root,
177
204
  stdio: ['ignore', 'pipe', 'pipe'],
178
205
  });
179
206
  /**
180
- * We cannot JSON.parse the output directly because if the user is using lifecycle scripts, npm will mix its publish output with the JSON output all on stdout.
207
+ * We cannot JSON.parse the output directly because if the user is using lifecycle scripts, npm/pnpm will mix its publish output with the JSON output all on stdout.
181
208
  * Additionally, we want to capture and show the lifecycle script outputs as beforeJsonData and afterJsonData and print them accordingly below.
182
209
  */
183
210
  const { beforeJsonData, jsonData, afterJsonData } = (0, extract_npm_publish_json_data_1.extractNpmPublishJsonData)(output.toString());
184
211
  if (!jsonData) {
185
- console.error('The npm publish output data could not be extracted. Please report this issue on https://github.com/nrwl/nx');
212
+ console.error(`The ${pm} publish output data could not be extracted. Please report this issue on https://github.com/nrwl/nx`);
186
213
  return {
187
214
  success: false,
188
215
  };
@@ -218,7 +245,7 @@ async function runExecutor(options, context) {
218
245
  catch (err) {
219
246
  try {
220
247
  const stdoutData = JSON.parse(err.stdout?.toString() || '{}');
221
- console.error('npm publish error:');
248
+ console.error(`${pm} publish error:`);
222
249
  if (stdoutData.error?.summary) {
223
250
  console.error(stdoutData.error.summary);
224
251
  }
@@ -226,7 +253,7 @@ async function runExecutor(options, context) {
226
253
  console.error(stdoutData.error.detail);
227
254
  }
228
255
  if (context.isVerbose) {
229
- console.error('npm publish stdout:');
256
+ console.error(`${pm} publish stdout:`);
230
257
  console.error(JSON.stringify(stdoutData, null, 2));
231
258
  }
232
259
  if (!stdoutData.error) {
@@ -237,7 +264,7 @@ async function runExecutor(options, context) {
237
264
  };
238
265
  }
239
266
  catch (err) {
240
- console.error('Something unexpected went wrong when processing the npm publish output\n', err);
267
+ console.error(`Something unexpected went wrong when processing the ${pm} publish output\n`, err);
241
268
  return {
242
269
  success: false,
243
270
  };
@@ -14,6 +14,7 @@ const version_1 = require("nx/src/command-line/release/version");
14
14
  const utils_1 = require("nx/src/tasks-runner/utils");
15
15
  const ora = require("ora");
16
16
  const semver_2 = require("semver");
17
+ const is_locally_linked_package_version_1 = require("../../utils/is-locally-linked-package-version");
17
18
  const npm_config_1 = require("../../utils/npm-config");
18
19
  const resolve_local_package_dependencies_1 = require("./utils/resolve-local-package-dependencies");
19
20
  const sort_projects_topologically_1 = require("./utils/sort-projects-topologically");
@@ -237,7 +238,8 @@ To fix this you will either need to add a package.json file at that location, or
237
238
  }
238
239
  specifier = await (0, resolve_semver_specifier_1.resolveSemverSpecifierFromConventionalCommits)(previousVersionRef, options.projectGraph, affectedProjects, options.conventionalCommitsConfig);
239
240
  if (!specifier) {
240
- if (projectToDependencyBumps.has(projectName)) {
241
+ if (updateDependents !== 'never' &&
242
+ projectToDependencyBumps.has(projectName)) {
241
243
  // No applicable changes to the project directly by the user, but one or more dependencies have been bumped and updateDependents is enabled
242
244
  specifier = updateDependentsBump;
243
245
  logger.buffer(`📄 Resolved the specifier as "${specifier}" because "release.version.generatorOptions.updateDependents" is enabled`);
@@ -471,7 +473,7 @@ To fix this you will either need to add a package.json file at that location, or
471
473
  // Depending on the package manager, locally linked packages could reference packages with `"private": true` and no version field at all
472
474
  const currentPackageVersion = json.version ?? null;
473
475
  if (!currentPackageVersion &&
474
- isLocallyLinkedPackageVersion(currentDependencyVersion)) {
476
+ (0, is_locally_linked_package_version_1.isLocallyLinkedPackageVersion)(currentDependencyVersion)) {
475
477
  if (forceVersionBump) {
476
478
  // Look up any dependent projects from the transitiveLocalPackageDependents list
477
479
  const transitiveDependentProjects = transitiveLocalPackageDependents.filter((localPackageDependency) => localPackageDependency.target === dependentProject.source);
@@ -496,10 +498,14 @@ To fix this you will either need to add a package.json file at that location, or
496
498
  }
497
499
  }
498
500
  }
499
- // Apply the new version of the dependency to the dependent
500
- const newDepVersion = `${versionPrefix}${newDependencyVersion}`;
501
- json[dependentProject.dependencyCollection][dependencyPackageName] =
502
- newDepVersion;
501
+ // Apply the new version of the dependency to the dependent (if not preserving locally linked package protocols)
502
+ const shouldUpdateDependency = !((0, is_locally_linked_package_version_1.isLocallyLinkedPackageVersion)(currentDependencyVersion) &&
503
+ options.preserveLocalDependencyProtocols);
504
+ if (shouldUpdateDependency) {
505
+ const newDepVersion = `${versionPrefix}${newDependencyVersion}`;
506
+ json[dependentProject.dependencyCollection][dependencyPackageName] =
507
+ newDepVersion;
508
+ }
503
509
  // Bump the dependent's version if applicable and record it in the version data
504
510
  if (forceVersionBump) {
505
511
  const newPackageVersion = (0, version_1.deriveNewSemverVersion)(currentPackageVersion, forceVersionBump, options.preid);
@@ -669,33 +675,3 @@ class ProjectLogger {
669
675
  });
670
676
  }
671
677
  }
672
- let pm;
673
- let pmVersion;
674
- const localPackageProtocols = [
675
- 'file:', // all package managers
676
- 'workspace:', // not npm
677
- 'portal:', // modern yarn only
678
- ];
679
- function isLocallyLinkedPackageVersion(version) {
680
- // Not using a supported local protocol
681
- if (!localPackageProtocols.some((protocol) => version.startsWith(protocol))) {
682
- return false;
683
- }
684
- // Supported by all package managers
685
- if (version.startsWith('file:')) {
686
- return true;
687
- }
688
- // Determine specific package manager in use
689
- if (!pm) {
690
- pm = (0, devkit_1.detectPackageManager)();
691
- pmVersion = (0, devkit_1.getPackageManagerVersion)(pm);
692
- }
693
- if (pm === 'npm' && version.startsWith('workspace:')) {
694
- throw new Error(`The "workspace:" protocol is not yet supported by npm (https://github.com/npm/rfcs/issues/765). Please ensure you have a valid setup according to your package manager before attempting to release packages.`);
695
- }
696
- if (version.startsWith('portal:') &&
697
- (pm !== 'yarn' || (0, semver_2.lt)(pmVersion, '2.0.0'))) {
698
- throw new Error(`The "portal:" protocol is only supported by yarn@2.0.0 and above. Please ensure you have a valid setup according to your package manager before attempting to release packages.`);
699
- }
700
- return true;
701
- }
@@ -0,0 +1 @@
1
+ export declare function isLocallyLinkedPackageVersion(version: string): boolean;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isLocallyLinkedPackageVersion = isLocallyLinkedPackageVersion;
4
+ const devkit_1 = require("@nx/devkit");
5
+ // import { lt } from 'semver';
6
+ let pm;
7
+ // let pmVersion: string | undefined;
8
+ const localPackageProtocols = [
9
+ 'file:', // all package managers
10
+ 'workspace:', // not npm
11
+ // TODO: Support portal protocol at the project graph level before enabling here
12
+ // 'portal:', // modern yarn only
13
+ ];
14
+ function isLocallyLinkedPackageVersion(version) {
15
+ // Not using a supported local protocol
16
+ if (!localPackageProtocols.some((protocol) => version.startsWith(protocol))) {
17
+ return false;
18
+ }
19
+ // Supported by all package managers
20
+ if (version.startsWith('file:')) {
21
+ return true;
22
+ }
23
+ // Determine specific package manager in use
24
+ if (!pm) {
25
+ pm = (0, devkit_1.detectPackageManager)();
26
+ // pmVersion = getPackageManagerVersion(pm);
27
+ }
28
+ if (pm === 'npm' && version.startsWith('workspace:')) {
29
+ throw new Error(`The "workspace:" protocol is not yet supported by npm (https://github.com/npm/rfcs/issues/765). Please ensure you have a valid setup according to your package manager before attempting to release packages.`);
30
+ }
31
+ // TODO: Support portal protocol at the project graph level before enabling here
32
+ // if (
33
+ // version.startsWith('portal:') &&
34
+ // (pm !== 'yarn' || lt(pmVersion, '2.0.0'))
35
+ // ) {
36
+ // throw new Error(
37
+ // `The "portal:" protocol is only supported by yarn@2.0.0 and above. Please ensure you have a valid setup according to your package manager before attempting to release packages.`
38
+ // );
39
+ // }
40
+ return true;
41
+ }