@nx/js 20.0.4 → 20.0.6

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": "20.0.4",
3
+ "version": "20.0.6",
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": "20.0.4",
43
- "@nx/workspace": "20.0.4",
42
+ "@nx/devkit": "20.0.6",
43
+ "@nx/workspace": "20.0.6",
44
44
  "@zkochan/js-yaml": "0.0.7",
45
45
  "babel-plugin-const-enum": "^1.0.1",
46
46
  "babel-plugin-macros": "^2.8.0",
@@ -2,7 +2,7 @@ export interface VerdaccioExecutorSchema {
2
2
  location: 'global' | 'user' | 'project' | 'none';
3
3
  storage?: string;
4
4
  port?: number;
5
- listenAddress?: string;
5
+ listenAddress: string; // default is 'localhost'
6
6
  config?: string;
7
7
  clear?: boolean;
8
8
  scopes?: string[];
@@ -22,7 +22,8 @@
22
22
  },
23
23
  "listenAddress": {
24
24
  "type": "string",
25
- "description": "Listen address that Verdaccio should listen to"
25
+ "description": "Listen address that Verdaccio should listen to",
26
+ "default": "localhost"
26
27
  },
27
28
  "config": {
28
29
  "type": "string",
@@ -129,12 +129,12 @@ function setupNpm(options) {
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, windowsHide: false });
133
- (0, child_process_1.execSync)(`npm config set //localhost:${options.port}/:_authToken="secretVerdaccioToken" --location ${options.location}`, { env, windowsHide: false });
134
- devkit_1.logger.info(`Set npm ${registryName} to http://localhost:${options.port}/`);
132
+ (0, child_process_1.execSync)(`npm config set ${registryName} http://${options.listenAddress}:${options.port}/ --location ${options.location}`, { env, windowsHide: false });
133
+ (0, child_process_1.execSync)(`npm config set //${options.listenAddress}:${options.port}/:_authToken="secretVerdaccioToken" --location ${options.location}`, { env, windowsHide: false });
134
+ devkit_1.logger.info(`Set npm ${registryName} to http://${options.listenAddress}:${options.port}/`);
135
135
  }
136
136
  catch (e) {
137
- throw new Error(`Failed to set npm ${registryName} to http://localhost:${options.port}/: ${e.message}`);
137
+ throw new Error(`Failed to set npm ${registryName} to http://${options.listenAddress}:${options.port}/: ${e.message}`);
138
138
  }
139
139
  });
140
140
  return () => {
@@ -146,7 +146,7 @@ function setupNpm(options) {
146
146
  scopes.forEach((scope, index) => {
147
147
  const registryName = scope ? `${scope}:registry` : 'registry';
148
148
  if (npmRegistryPaths[index] &&
149
- currentNpmRegistryPath.includes('localhost')) {
149
+ currentNpmRegistryPath.includes(options.listenAddress)) {
150
150
  (0, child_process_1.execSync)(`npm config set ${registryName} ${npmRegistryPaths[index]} --location ${options.location}`, { env, windowsHide: false });
151
151
  devkit_1.logger.info(`Reset npm ${registryName} to ${npmRegistryPaths[index]}`);
152
152
  }
@@ -158,7 +158,7 @@ function setupNpm(options) {
158
158
  devkit_1.logger.info('Cleared custom npm registry');
159
159
  }
160
160
  });
161
- (0, child_process_1.execSync)(`npm config delete //localhost:${options.port}/:_authToken --location ${options.location}`, { env, windowsHide: false });
161
+ (0, child_process_1.execSync)(`npm config delete //${options.listenAddress}:${options.port}/:_authToken --location ${options.location}`, { env, windowsHide: false });
162
162
  }
163
163
  catch (e) {
164
164
  throw new Error(`Failed to reset npm registry: ${e.message}`);
@@ -166,7 +166,7 @@ function setupNpm(options) {
166
166
  };
167
167
  }
168
168
  catch (e) {
169
- throw new Error(`Failed to set npm registry to http://localhost:${options.port}/: ${e.message}`);
169
+ throw new Error(`Failed to set npm registry to http://${options.listenAddress}:${options.port}/: ${e.message}`);
170
170
  }
171
171
  }
172
172
  function getYarnUnsafeHttpWhitelist(isYarnV1) {
@@ -212,17 +212,17 @@ function setupYarn(options) {
212
212
  ?.trim()
213
213
  ?.replace('\u001b[2K\u001b[1G', '') // strip out ansi codes
214
214
  );
215
- (0, child_process_1.execSync)(`yarn config set ${scopeName}${registryConfigName} http://localhost:${options.port}/` +
215
+ (0, child_process_1.execSync)(`yarn config set ${scopeName}${registryConfigName} http://${options.listenAddress}:${options.port}/` +
216
216
  (options.location === 'user' ? ' --home' : ''), { env, windowsHide: false });
217
- devkit_1.logger.info(`Set yarn ${scopeName}registry to http://localhost:${options.port}/`);
217
+ devkit_1.logger.info(`Set yarn ${scopeName}registry to http://${options.listenAddress}:${options.port}/`);
218
218
  });
219
219
  const currentWhitelist = getYarnUnsafeHttpWhitelist(isYarnV1);
220
220
  let whitelistedLocalhost = false;
221
- if (!isYarnV1 && !currentWhitelist.has('localhost')) {
221
+ if (!isYarnV1 && !currentWhitelist.has(options.listenAddress)) {
222
222
  whitelistedLocalhost = true;
223
- currentWhitelist.add('localhost');
223
+ currentWhitelist.add(options.listenAddress);
224
224
  setYarnUnsafeHttpWhitelist(currentWhitelist, options);
225
- devkit_1.logger.info(`Whitelisted http://localhost:${options.port}/ as an unsafe http server`);
225
+ devkit_1.logger.info(`Whitelisted http://${options.listenAddress}:${options.port}/ as an unsafe http server`);
226
226
  }
227
227
  return () => {
228
228
  try {
@@ -235,7 +235,7 @@ function setupYarn(options) {
235
235
  ? `${scope}:${registryConfigName}`
236
236
  : registryConfigName;
237
237
  if (yarnRegistryPaths[index] &&
238
- currentYarnRegistryPath.includes('localhost')) {
238
+ currentYarnRegistryPath.includes(options.listenAddress)) {
239
239
  (0, child_process_1.execSync)(`yarn config set ${registryName} ${yarnRegistryPaths[index]}` +
240
240
  (options.location === 'user' ? ' --home' : ''), {
241
241
  env,
@@ -251,10 +251,10 @@ function setupYarn(options) {
251
251
  });
252
252
  if (whitelistedLocalhost) {
253
253
  const currentWhitelist = getYarnUnsafeHttpWhitelist(isYarnV1);
254
- if (currentWhitelist.has('localhost')) {
255
- currentWhitelist.delete('localhost');
254
+ if (currentWhitelist.has(options.listenAddress)) {
255
+ currentWhitelist.delete(options.listenAddress);
256
256
  setYarnUnsafeHttpWhitelist(currentWhitelist, options);
257
- devkit_1.logger.info(`Removed http://localhost:${options.port}/ as an unsafe http server`);
257
+ devkit_1.logger.info(`Removed http://${options.listenAddress}:${options.port}/ as an unsafe http server`);
258
258
  }
259
259
  }
260
260
  }
@@ -264,7 +264,7 @@ function setupYarn(options) {
264
264
  };
265
265
  }
266
266
  catch (e) {
267
- throw new Error(`Failed to set yarn registry to http://localhost:${options.port}/: ${e.message}`);
267
+ throw new Error(`Failed to set yarn registry to http://${options.listenAddress}:${options.port}/: ${e.message}`);
268
268
  }
269
269
  }
270
270
  exports.default = verdaccioExecutor;
@@ -77,13 +77,21 @@ async function createNodesInternal(configFilePath, options, context, lockFileNam
77
77
  * - hashes of the content of the relevant files that can affect what's inferred by the plugin:
78
78
  * - current config file
79
79
  * - config files extended by the current config file (recursively up to the root config file)
80
+ * - referenced config files that are internal to the owning Nx project of the current config file
80
81
  * - lock file
81
82
  * - hash of the plugin options
82
83
  * - current config file path
83
84
  */
84
- const extendedConfigFiles = getExtendedConfigFiles(fullConfigPath, readCachedTsConfig(fullConfigPath));
85
+ const tsConfig = readCachedTsConfig(fullConfigPath);
86
+ const extendedConfigFiles = getExtendedConfigFiles(fullConfigPath, tsConfig);
87
+ const internalReferencedFiles = resolveInternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
85
88
  const nodeHash = (0, file_hasher_1.hashArray)([
86
- ...[configFilePath, ...extendedConfigFiles, lockFileName].map(file_hasher_1.hashFile),
89
+ ...[
90
+ configFilePath,
91
+ ...extendedConfigFiles.files,
92
+ ...Object.keys(internalReferencedFiles),
93
+ lockFileName,
94
+ ].map(file_hasher_1.hashFile),
87
95
  (0, file_hasher_1.hashObject)(options),
88
96
  ]);
89
97
  const cacheKey = `${nodeHash}_${configFilePath}`;
@@ -169,12 +177,14 @@ function buildTscTargets(configFilePath, projectRoot, options, context) {
169
177
  }
170
178
  function getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferences, workspaceRoot, projectRoot) {
171
179
  const configFiles = new Set();
172
- const includePaths = new Set();
173
- const excludePaths = new Set();
180
+ const externalDependencies = ['typescript'];
174
181
  const extendedConfigFiles = getExtendedConfigFiles(configFilePath, tsConfig);
175
- extendedConfigFiles.forEach((configPath) => {
182
+ extendedConfigFiles.files.forEach((configPath) => {
176
183
  configFiles.add(configPath);
177
184
  });
185
+ externalDependencies.push(...extendedConfigFiles.packages);
186
+ const includePaths = new Set();
187
+ const excludePaths = new Set();
178
188
  const projectTsConfigFiles = [
179
189
  [configFilePath, tsConfig],
180
190
  ...Object.entries(internalProjectReferences),
@@ -225,7 +235,7 @@ function getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferen
225
235
  else {
226
236
  inputs.push('production' in namedInputs ? '^production' : '^default');
227
237
  }
228
- inputs.push({ externalDependencies: ['typescript'] });
238
+ inputs.push({ externalDependencies });
229
239
  return inputs;
230
240
  }
231
241
  function getOutputs(configFilePath, tsConfig, internalProjectReferences, workspaceRoot, projectRoot) {
@@ -238,19 +248,24 @@ function getOutputs(configFilePath, tsConfig, internalProjectReferences, workspa
238
248
  if (config.options.outFile) {
239
249
  const outFileName = (0, node_path_1.basename)(config.options.outFile, '.js');
240
250
  const outFileDir = (0, node_path_1.dirname)(config.options.outFile);
241
- outputs.add((0, devkit_1.joinPathFragments)('{workspaceRoot}', (0, node_path_1.relative)(workspaceRoot, config.options.outFile)));
251
+ outputs.add(pathToInputOrOutput(config.options.outFile, workspaceRoot, projectRoot));
242
252
  // outFile is not be used with .cjs, .mjs, .jsx, so the list is simpler
243
253
  const outDir = (0, node_path_1.relative)(workspaceRoot, outFileDir);
244
- outputs.add((0, devkit_1.joinPathFragments)('{workspaceRoot}', outDir, `${outFileName}.js.map`));
245
- outputs.add((0, devkit_1.joinPathFragments)('{workspaceRoot}', outDir, `${outFileName}.d.ts`));
246
- outputs.add((0, devkit_1.joinPathFragments)('{workspaceRoot}', outDir, `${outFileName}.d.ts.map`));
254
+ outputs.add(pathToInputOrOutput((0, devkit_1.joinPathFragments)(outDir, `${outFileName}.js.map`), workspaceRoot, projectRoot));
255
+ outputs.add(pathToInputOrOutput((0, devkit_1.joinPathFragments)(outDir, `${outFileName}.d.ts`), workspaceRoot, projectRoot));
256
+ outputs.add(pathToInputOrOutput((0, devkit_1.joinPathFragments)(outDir, `${outFileName}.d.ts.map`), workspaceRoot, projectRoot));
247
257
  // https://www.typescriptlang.org/tsconfig#tsBuildInfoFile
248
258
  outputs.add(tsConfig.options.tsBuildInfoFile
249
259
  ? pathToInputOrOutput(tsConfig.options.tsBuildInfoFile, workspaceRoot, projectRoot)
250
- : (0, devkit_1.joinPathFragments)('{workspaceRoot}', outDir, `${outFileName}.tsbuildinfo`));
260
+ : pathToInputOrOutput((0, devkit_1.joinPathFragments)(outDir, `${outFileName}.tsbuildinfo`), workspaceRoot, projectRoot));
251
261
  }
252
262
  else if (config.options.outDir) {
253
- outputs.add((0, devkit_1.joinPathFragments)('{workspaceRoot}', (0, node_path_1.relative)(workspaceRoot, config.options.outDir)));
263
+ outputs.add(pathToInputOrOutput(config.options.outDir, workspaceRoot, projectRoot));
264
+ if (config.options.tsBuildInfoFile &&
265
+ !(0, node_path_1.normalize)(config.options.tsBuildInfoFile).startsWith(`${(0, node_path_1.normalize)(config.options.outDir)}${node_path_1.sep}`)) {
266
+ // https://www.typescriptlang.org/tsconfig#tsBuildInfoFile
267
+ outputs.add(pathToInputOrOutput(config.options.tsBuildInfoFile, workspaceRoot, projectRoot));
268
+ }
254
269
  }
255
270
  else if (config.fileNames.length) {
256
271
  // tsc produce files in place when no outDir or outFile is set
@@ -284,16 +299,26 @@ function pathToInputOrOutput(path, workspaceRoot, projectRoot) {
284
299
  }
285
300
  function getExtendedConfigFiles(tsConfigPath, tsConfig) {
286
301
  const extendedConfigFiles = new Set();
302
+ const extendedExternalPackages = new Set();
287
303
  let currentConfigPath = tsConfigPath;
288
304
  let currentConfig = tsConfig;
289
305
  while (currentConfig.raw?.extends) {
290
- const extendedConfigPath = (0, node_path_1.join)((0, node_path_1.dirname)(currentConfigPath), currentConfig.raw.extends);
291
- extendedConfigFiles.add(extendedConfigPath);
292
- const extendedConfig = readCachedTsConfig(extendedConfigPath);
293
- currentConfigPath = extendedConfigPath;
294
- currentConfig = extendedConfig;
306
+ const extendedConfigPath = resolveExtendedTsConfigPath(currentConfig.raw.extends, (0, node_path_1.dirname)(currentConfigPath));
307
+ if (!extendedConfigPath) {
308
+ break;
309
+ }
310
+ if (extendedConfigPath.externalPackage) {
311
+ extendedExternalPackages.add(extendedConfigPath.externalPackage);
312
+ break;
313
+ }
314
+ extendedConfigFiles.add(extendedConfigPath.filePath);
315
+ currentConfig = readCachedTsConfig(extendedConfigPath.filePath);
316
+ currentConfigPath = extendedConfigPath.filePath;
295
317
  }
296
- return Array.from(extendedConfigFiles);
318
+ return {
319
+ files: Array.from(extendedConfigFiles),
320
+ packages: Array.from(extendedExternalPackages),
321
+ };
297
322
  }
298
323
  function resolveInternalProjectReferences(tsConfig, workspaceRoot, projectRoot, projectReferences = {}) {
299
324
  if (!tsConfig.projectReferences?.length) {
@@ -422,3 +447,21 @@ function normalizePluginOptions(pluginOptions = {}) {
422
447
  build,
423
448
  };
424
449
  }
450
+ function resolveExtendedTsConfigPath(tsConfigPath, directory) {
451
+ try {
452
+ const resolvedPath = require.resolve(tsConfigPath, {
453
+ paths: directory ? [directory] : undefined,
454
+ });
455
+ if (tsConfigPath.startsWith('.')) {
456
+ return { filePath: resolvedPath };
457
+ }
458
+ // parse the package from the tsconfig path
459
+ const packageName = tsConfigPath.startsWith('@')
460
+ ? tsConfigPath.split('/').slice(0, 2).join('/')
461
+ : tsConfigPath.split('/')[0];
462
+ return { filePath: resolvedPath, externalPackage: packageName };
463
+ }
464
+ catch {
465
+ return null;
466
+ }
467
+ }