@nx/js 19.8.0 → 19.8.1

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.8.0",
3
+ "version": "19.8.1",
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,14 +39,15 @@
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.8.0",
43
- "@nx/workspace": "19.8.0",
42
+ "@nx/devkit": "19.8.1",
43
+ "@nx/workspace": "19.8.1",
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",
47
47
  "chalk": "^4.1.0",
48
48
  "columnify": "^1.6.0",
49
49
  "detect-port": "^1.5.1",
50
+ "enquirer": "~2.3.6",
50
51
  "fast-glob": "3.2.7",
51
52
  "ignore": "^5.0.4",
52
53
  "js-tokens": "^4.0.0",
@@ -60,7 +61,7 @@
60
61
  "ts-node": "10.9.1",
61
62
  "tsconfig-paths": "^4.1.2",
62
63
  "tslib": "^2.3.0",
63
- "@nrwl/js": "19.8.0"
64
+ "@nrwl/js": "19.8.1"
64
65
  },
65
66
  "peerDependencies": {
66
67
  "verdaccio": "^5.0.4"
@@ -19,7 +19,9 @@ async function killTree(pid, signal) {
19
19
  };
20
20
  switch (process.platform) {
21
21
  case 'win32':
22
- (0, child_process_1.exec)('taskkill /pid ' + pid + ' /T /F', (error) => {
22
+ (0, child_process_1.exec)('taskkill /pid ' + pid + ' /T /F', {
23
+ windowsHide: true,
24
+ }, (error) => {
23
25
  // Ignore Fatal errors (128) because it might be due to the process already being killed.
24
26
  // On Linux/Mac we can check ESRCH (no such process), but on Windows we can't.
25
27
  callback(error?.code !== 128 ? error : null);
@@ -27,20 +29,18 @@ async function killTree(pid, signal) {
27
29
  break;
28
30
  case 'darwin':
29
31
  buildProcessTree(pid, tree, pidsToProcess, function (parentPid) {
30
- return (0, child_process_1.spawn)('pgrep', ['-P', parentPid]);
32
+ return (0, child_process_1.spawn)('pgrep', ['-P', parentPid], {
33
+ windowsHide: true,
34
+ });
31
35
  }, function () {
32
36
  killAll(tree, signal, callback);
33
37
  });
34
38
  break;
35
39
  default: // Linux
36
40
  buildProcessTree(pid, tree, pidsToProcess, function (parentPid) {
37
- return (0, child_process_1.spawn)('ps', [
38
- '-o',
39
- 'pid',
40
- '--no-headers',
41
- '--ppid',
42
- parentPid,
43
- ]);
41
+ return (0, child_process_1.spawn)('ps', ['-o', 'pid', '--no-headers', '--ppid', parentPid], {
42
+ windowsHide: true,
43
+ });
44
44
  }, function () {
45
45
  killAll(tree, signal, callback);
46
46
  });
@@ -96,6 +96,7 @@ Please update the local dependency on "${depName}" to be a valid semantic versio
96
96
  env: processEnv(true),
97
97
  cwd: context.root,
98
98
  stdio: ['ignore', 'pipe', 'pipe'],
99
+ windowsHide: true,
99
100
  });
100
101
  const resultJson = JSON.parse(result.toString());
101
102
  const distTags = resultJson['dist-tags'] || {};
@@ -116,6 +117,7 @@ Please update the local dependency on "${depName}" to be a valid semantic versio
116
117
  env: processEnv(true),
117
118
  cwd: context.root,
118
119
  stdio: 'ignore',
120
+ windowsHide: true,
119
121
  });
120
122
  console.log(`Added the dist-tag ${tag} to v${currentVersion} for registry ${registry}.\n`);
121
123
  }
@@ -202,6 +204,7 @@ Please update the local dependency on "${depName}" to be a valid semantic versio
202
204
  env: processEnv(true),
203
205
  cwd: context.root,
204
206
  stdio: ['ignore', 'pipe', 'pipe'],
207
+ windowsHide: true,
205
208
  });
206
209
  /**
207
210
  * 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.
@@ -113,7 +113,7 @@ function createVerdaccioOptions(options, workspaceRoot) {
113
113
  }
114
114
  function setupNpm(options) {
115
115
  try {
116
- (0, child_process_1.execSync)('npm --version', { env });
116
+ (0, child_process_1.execSync)('npm --version', { env, windowsHide: true });
117
117
  }
118
118
  catch (e) {
119
119
  return () => { };
@@ -124,13 +124,13 @@ function setupNpm(options) {
124
124
  scopes.forEach((scope) => {
125
125
  const registryName = scope ? `${scope}:registry` : 'registry';
126
126
  try {
127
- npmRegistryPaths.push((0, child_process_1.execSync)(`npm config get ${registryName} --location ${options.location}`, { env })
127
+ npmRegistryPaths.push((0, child_process_1.execSync)(`npm config get ${registryName} --location ${options.location}`, { env, windowsHide: true })
128
128
  ?.toString()
129
129
  ?.trim()
130
130
  ?.replace('\u001b[2K\u001b[1G', '') // strip out ansi codes
131
131
  );
132
- (0, child_process_1.execSync)(`npm config set ${registryName} http://localhost:${options.port}/ --location ${options.location}`, { env });
133
- (0, child_process_1.execSync)(`npm config set //localhost:${options.port}/:_authToken="secretVerdaccioToken" --location ${options.location}`, { env });
132
+ (0, child_process_1.execSync)(`npm config set ${registryName} http://localhost:${options.port}/ --location ${options.location}`, { env, windowsHide: true });
133
+ (0, child_process_1.execSync)(`npm config set //localhost:${options.port}/:_authToken="secretVerdaccioToken" --location ${options.location}`, { env, windowsHide: true });
134
134
  devkit_1.logger.info(`Set npm ${registryName} to http://localhost:${options.port}/`);
135
135
  }
136
136
  catch (e) {
@@ -139,7 +139,7 @@ function setupNpm(options) {
139
139
  });
140
140
  return () => {
141
141
  try {
142
- const currentNpmRegistryPath = (0, child_process_1.execSync)(`npm config get registry --location ${options.location}`, { env })
142
+ const currentNpmRegistryPath = (0, child_process_1.execSync)(`npm config get registry --location ${options.location}`, { env, windowsHide: true })
143
143
  ?.toString()
144
144
  ?.trim()
145
145
  ?.replace('\u001b[2K\u001b[1G', ''); // strip out ansi codes
@@ -147,17 +147,18 @@ function setupNpm(options) {
147
147
  const registryName = scope ? `${scope}:registry` : 'registry';
148
148
  if (npmRegistryPaths[index] &&
149
149
  currentNpmRegistryPath.includes('localhost')) {
150
- (0, child_process_1.execSync)(`npm config set ${registryName} ${npmRegistryPaths[index]} --location ${options.location}`, { env });
150
+ (0, child_process_1.execSync)(`npm config set ${registryName} ${npmRegistryPaths[index]} --location ${options.location}`, { env, windowsHide: true });
151
151
  devkit_1.logger.info(`Reset npm ${registryName} to ${npmRegistryPaths[index]}`);
152
152
  }
153
153
  else {
154
154
  (0, child_process_1.execSync)(`npm config delete ${registryName} --location ${options.location}`, {
155
155
  env,
156
+ windowsHide: true,
156
157
  });
157
158
  devkit_1.logger.info('Cleared custom npm registry');
158
159
  }
159
160
  });
160
- (0, child_process_1.execSync)(`npm config delete //localhost:${options.port}/:_authToken --location ${options.location}`, { env });
161
+ (0, child_process_1.execSync)(`npm config delete //localhost:${options.port}/:_authToken --location ${options.location}`, { env, windowsHide: true });
161
162
  }
162
163
  catch (e) {
163
164
  throw new Error(`Failed to reset npm registry: ${e.message}`);
@@ -172,16 +173,17 @@ function getYarnUnsafeHttpWhitelist(isYarnV1) {
172
173
  return !isYarnV1
173
174
  ? new Set(JSON.parse((0, child_process_1.execSync)(`yarn config get unsafeHttpWhitelist --json`, {
174
175
  env,
176
+ windowsHide: true,
175
177
  }).toString()))
176
178
  : null;
177
179
  }
178
180
  function setYarnUnsafeHttpWhitelist(currentWhitelist, options) {
179
181
  if (currentWhitelist.size > 0) {
180
- (0, child_process_1.execSync)(`yarn config set unsafeHttpWhitelist --json '${JSON.stringify(Array.from(currentWhitelist))}'` + (options.location === 'user' ? ' --home' : ''), { env });
182
+ (0, child_process_1.execSync)(`yarn config set unsafeHttpWhitelist --json '${JSON.stringify(Array.from(currentWhitelist))}'` + (options.location === 'user' ? ' --home' : ''), { env, windowsHide: true });
181
183
  }
182
184
  else {
183
185
  (0, child_process_1.execSync)(`yarn config unset unsafeHttpWhitelist` +
184
- (options.location === 'user' ? ' --home' : ''), { env });
186
+ (options.location === 'user' ? ' --home' : ''), { env, windowsHide: true });
185
187
  }
186
188
  }
187
189
  function setupYarn(options) {
@@ -190,7 +192,7 @@ function setupYarn(options) {
190
192
  const scopes = ['', ...(options.scopes || [])];
191
193
  try {
192
194
  isYarnV1 =
193
- (0, semver_1.major)((0, child_process_1.execSync)('yarn --version', { env }).toString().trim()) === 1;
195
+ (0, semver_1.major)((0, child_process_1.execSync)('yarn --version', { env, windowsHide: true }).toString().trim()) === 1;
194
196
  }
195
197
  catch {
196
198
  // This would fail if yarn is not installed which is okay
@@ -202,13 +204,14 @@ function setupYarn(options) {
202
204
  const scopeName = scope ? `${scope}:` : '';
203
205
  yarnRegistryPaths.push((0, child_process_1.execSync)(`yarn config get ${scopeName}${registryConfigName}`, {
204
206
  env,
207
+ windowsHide: true,
205
208
  })
206
209
  ?.toString()
207
210
  ?.trim()
208
211
  ?.replace('\u001b[2K\u001b[1G', '') // strip out ansi codes
209
212
  );
210
213
  (0, child_process_1.execSync)(`yarn config set ${scopeName}${registryConfigName} http://localhost:${options.port}/` +
211
- (options.location === 'user' ? ' --home' : ''), { env });
214
+ (options.location === 'user' ? ' --home' : ''), { env, windowsHide: true });
212
215
  devkit_1.logger.info(`Set yarn ${scopeName}registry to http://localhost:${options.port}/`);
213
216
  });
214
217
  const currentWhitelist = getYarnUnsafeHttpWhitelist(isYarnV1);
@@ -221,7 +224,7 @@ function setupYarn(options) {
221
224
  }
222
225
  return () => {
223
226
  try {
224
- const currentYarnRegistryPath = (0, child_process_1.execSync)(`yarn config get ${registryConfigName}`, { env })
227
+ const currentYarnRegistryPath = (0, child_process_1.execSync)(`yarn config get ${registryConfigName}`, { env, windowsHide: true })
225
228
  ?.toString()
226
229
  ?.trim()
227
230
  ?.replace('\u001b[2K\u001b[1G', ''); // strip out ansi codes
@@ -232,12 +235,15 @@ function setupYarn(options) {
232
235
  if (yarnRegistryPaths[index] &&
233
236
  currentYarnRegistryPath.includes('localhost')) {
234
237
  (0, child_process_1.execSync)(`yarn config set ${registryName} ${yarnRegistryPaths[index]}` +
235
- (options.location === 'user' ? ' --home' : ''), { env });
238
+ (options.location === 'user' ? ' --home' : ''), {
239
+ env,
240
+ windowsHide: true,
241
+ });
236
242
  devkit_1.logger.info(`Reset yarn ${registryName} to ${yarnRegistryPaths[index]}`);
237
243
  }
238
244
  else {
239
245
  (0, child_process_1.execSync)(`yarn config ${isYarnV1 ? 'delete' : 'unset'} ${registryName}` +
240
- (options.location === 'user' ? ' --home' : ''), { env });
246
+ (options.location === 'user' ? ' --home' : ''), { env, windowsHide: true });
241
247
  devkit_1.logger.info(`Cleared custom yarn ${registryConfigName}`);
242
248
  }
243
249
  });
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.releaseVersionGenerator = releaseVersionGenerator;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const chalk = require("chalk");
6
+ const enquirer_1 = require("enquirer");
6
7
  const node_child_process_1 = require("node:child_process");
7
8
  const promises_1 = require("node:fs/promises");
8
9
  const node_path_1 = require("node:path");
@@ -118,7 +119,9 @@ To fix this you will either need to add a package.json file at that location, or
118
119
  try {
119
120
  // Must be non-blocking async to allow spinner to render
120
121
  currentVersion = await new Promise((resolve, reject) => {
121
- (0, node_child_process_1.exec)(`npm view ${packageName} version --"${registryConfigKey}=${registry}" --tag=${tag}`, (error, stdout, stderr) => {
122
+ (0, node_child_process_1.exec)(`npm view ${packageName} version --"${registryConfigKey}=${registry}" --tag=${tag}`, {
123
+ windowsHide: true,
124
+ }, (error, stdout, stderr) => {
122
125
  if (error) {
123
126
  return reject(error);
124
127
  }
@@ -134,9 +137,23 @@ To fix this you will either need to add a package.json file at that location, or
134
137
  catch (e) {
135
138
  spinner.stop();
136
139
  if (options.fallbackCurrentVersionResolver === 'disk') {
137
- logger.buffer(`📄 Unable to resolve the current version from the registry ${registry}. Falling back to the version on disk of ${currentVersionFromDisk}`);
138
- currentVersion = currentVersionFromDisk;
139
- currentVersionResolvedFromFallback = true;
140
+ if (!currentVersionFromDisk &&
141
+ (options.specifierSource === 'conventional-commits' ||
142
+ options.specifierSource === 'version-plans')) {
143
+ currentVersion = await handleNoAvailableDiskFallback({
144
+ logger,
145
+ projectName,
146
+ packageJsonPath,
147
+ specifierSource: options.specifierSource,
148
+ currentVersionSourceMessage: `from the registry ${registry}`,
149
+ resolutionSuggestion: `you should publish an initial version to the registry`,
150
+ });
151
+ }
152
+ else {
153
+ logger.buffer(`📄 Unable to resolve the current version from the registry ${registry}. Falling back to the version on disk of ${currentVersionFromDisk}`);
154
+ currentVersion = currentVersionFromDisk;
155
+ currentVersionResolvedFromFallback = true;
156
+ }
140
157
  }
141
158
  else {
142
159
  throw new Error(`Unable to resolve the current version from the registry ${registry}. Please ensure that the package exists in the registry in order to use the "registry" currentVersionResolver. Alternatively, you can use the --first-release option or set "release.version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when the registry lookup fails.`);
@@ -156,7 +173,7 @@ To fix this you will either need to add a package.json file at that location, or
156
173
  case 'disk':
157
174
  currentVersion = currentVersionFromDisk;
158
175
  if (!currentVersion) {
159
- throw new Error(`Unable to determine the current version for project "${project.name}" from ${packageJsonPath}`);
176
+ throw new Error(`Unable to determine the current version for project "${project.name}" from ${packageJsonPath}, please ensure that the "version" field is set within the file`);
160
177
  }
161
178
  logger.buffer(`📄 Resolved the current version as ${currentVersion} from ${packageJsonPath}`);
162
179
  break;
@@ -170,9 +187,23 @@ To fix this you will either need to add a package.json file at that location, or
170
187
  });
171
188
  if (!latestMatchingGitTag) {
172
189
  if (options.fallbackCurrentVersionResolver === 'disk') {
173
- logger.buffer(`📄 Unable to resolve the current version from git tag using pattern "${releaseTagPattern}". Falling back to the version on disk of ${currentVersionFromDisk}`);
174
- currentVersion = currentVersionFromDisk;
175
- currentVersionResolvedFromFallback = true;
190
+ if (!currentVersionFromDisk &&
191
+ (options.specifierSource === 'conventional-commits' ||
192
+ options.specifierSource === 'version-plans')) {
193
+ currentVersion = await handleNoAvailableDiskFallback({
194
+ logger,
195
+ projectName,
196
+ packageJsonPath,
197
+ specifierSource: options.specifierSource,
198
+ currentVersionSourceMessage: `from git tag using pattern "${releaseTagPattern}"`,
199
+ resolutionSuggestion: `you should set an initial git tag on a relevant commit`,
200
+ });
201
+ }
202
+ else {
203
+ logger.buffer(`📄 Unable to resolve the current version from git tag using pattern "${releaseTagPattern}". Falling back to the version on disk of ${currentVersionFromDisk}`);
204
+ currentVersion = currentVersionFromDisk;
205
+ currentVersionResolvedFromFallback = true;
206
+ }
176
207
  }
177
208
  else {
178
209
  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. Alternatively, you can use the --first-release option or set "release.version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when no matching git tags are found.`);
@@ -675,3 +706,35 @@ class ProjectLogger {
675
706
  });
676
707
  }
677
708
  }
709
+ /**
710
+ * Allow users to be unblocked when locally running releases for the very first time with certain combinations that require an initial
711
+ * version in order to function (e.g. a relative semver bump derived via conventional commits or version plans) by providing an interactive
712
+ * prompt to let them opt into using 0.0.0 as the implied current version.
713
+ */
714
+ async function handleNoAvailableDiskFallback({ logger, projectName, packageJsonPath, specifierSource, currentVersionSourceMessage, resolutionSuggestion, }) {
715
+ const unresolvableCurrentVersionError = new Error(`Unable to resolve the current version ${currentVersionSourceMessage} and there is no version on disk to fall back to. This is invalid with ${specifierSource} because the new version is determined by relatively bumping the current version. To resolve this, ${resolutionSuggestion}, or set an appropriate value for "version" in ${packageJsonPath}`);
716
+ if (process.env.CI === 'true') {
717
+ // We can't prompt in CI, so error immediately
718
+ throw unresolvableCurrentVersionError;
719
+ }
720
+ try {
721
+ const reply = await (0, enquirer_1.prompt)([
722
+ {
723
+ name: 'useZero',
724
+ message: `\n${chalk.yellow(`Warning: Unable to resolve the current version for "${projectName}" ${currentVersionSourceMessage} and there is no version on disk to fall back to. This is invalid with ${specifierSource} because the new version is determined by relatively bumping the current version.\n\nTo resolve this, ${resolutionSuggestion}, or set an appropriate value for "version" in ${packageJsonPath}`)}. \n\nAlternatively, would you like to continue now by using 0.0.0 as the current version?`,
725
+ type: 'confirm',
726
+ initial: false,
727
+ },
728
+ ]);
729
+ if (!reply.useZero) {
730
+ // Throw any error to skip the fallback to 0.0.0, may as well use the one we already have
731
+ throw unresolvableCurrentVersionError;
732
+ }
733
+ const currentVersion = '0.0.0';
734
+ logger.buffer(`📄 Forcibly resolved the current version as "${currentVersion}" based on your response to the prompt above.`);
735
+ return currentVersion;
736
+ }
737
+ catch {
738
+ throw unresolvableCurrentVersionError;
739
+ }
740
+ }
@@ -89,6 +89,7 @@ function execLockFileUpdate(command, cwd, env = {}) {
89
89
  ...process.env,
90
90
  ...env,
91
91
  },
92
+ windowsHide: true,
92
93
  });
93
94
  }
94
95
  catch (e) {
@@ -8,8 +8,11 @@ const child_process_1 = require("child_process");
8
8
  async function setupVerdaccio(tree, options) {
9
9
  if (!tree.exists('.verdaccio/config.yml')) {
10
10
  (0, devkit_1.generateFiles)(tree, path.join(__dirname, 'files'), '.verdaccio', {
11
- npmUplinkRegistry: (0, child_process_1.execSync)('npm config get registry')?.toString()?.trim() ??
12
- 'https://registry.npmjs.org',
11
+ npmUplinkRegistry: (0, child_process_1.execSync)('npm config get registry', {
12
+ windowsHide: true,
13
+ })
14
+ ?.toString()
15
+ ?.trim() ?? 'https://registry.npmjs.org',
13
16
  });
14
17
  }
15
18
  const verdaccioTarget = {
@@ -27,7 +27,9 @@ function startLocalRegistry({ localRegistryTarget, storage, verbose, clearStorag
27
27
  console.log('Local registry started on port ' + port);
28
28
  const registry = `http://localhost:${port}`;
29
29
  process.env.npm_config_registry = registry;
30
- (0, child_process_1.execSync)(`npm config set //localhost:${port}/:_authToken "secretVerdaccioToken"`);
30
+ (0, child_process_1.execSync)(`npm config set //localhost:${port}/:_authToken "secretVerdaccioToken"`, {
31
+ windowsHide: true,
32
+ });
31
33
  // yarnv1
32
34
  process.env.YARN_REGISTRY = registry;
33
35
  // yarnv2
@@ -36,7 +38,9 @@ function startLocalRegistry({ localRegistryTarget, storage, verbose, clearStorag
36
38
  console.log('Set npm and yarn config registry to ' + registry);
37
39
  resolve(() => {
38
40
  childProcess.kill();
39
- (0, child_process_1.execSync)(`npm config delete //localhost:${port}/:_authToken`);
41
+ (0, child_process_1.execSync)(`npm config delete //localhost:${port}/:_authToken`, {
42
+ windowsHide: true,
43
+ });
40
44
  });
41
45
  childProcess?.stdout?.off('data', listener);
42
46
  }
@@ -76,7 +76,7 @@ async function getNpmConfigValue(key, cwd) {
76
76
  async function execAsync(command, cwd) {
77
77
  // Must be non-blocking async to allow spinner to render
78
78
  return new Promise((resolve, reject) => {
79
- (0, child_process_1.exec)(command, { cwd }, (error, stdout, stderr) => {
79
+ (0, child_process_1.exec)(command, { cwd, windowsHide: true }, (error, stdout, stderr) => {
80
80
  if (error) {
81
81
  return reject(error);
82
82
  }
@@ -62,6 +62,7 @@ async function compileSwc(context, normalizedOptions, postCompilationCallback) {
62
62
  const swcCmdLog = (0, node_child_process_1.execSync)(getSwcCmd(normalizedOptions), {
63
63
  encoding: 'utf8',
64
64
  cwd: normalizedOptions.swcCliOptions.swcCwd,
65
+ windowsHide: true,
65
66
  });
66
67
  devkit_1.logger.log(swcCmdLog.replace(/\n/, ''));
67
68
  const isCompileSuccess = swcCmdLog.includes('Successfully compiled');
@@ -98,6 +99,7 @@ async function* compileSwcWatch(context, normalizedOptions, postCompilationCallb
98
99
  let watcherOnExit;
99
100
  const swcWatcher = (0, node_child_process_1.exec)(getSwcCmd(normalizedOptions, true), {
100
101
  cwd: normalizedOptions.swcCliOptions.swcCwd,
102
+ windowsHide: true,
101
103
  });
102
104
  processOnExit = () => {
103
105
  swcWatcher.kill();