@nx/js 21.0.0-beta.0 → 21.0.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.
Files changed (43) hide show
  1. package/migrations.json +18 -0
  2. package/package.json +7 -8
  3. package/src/executors/node/node.impl.js +2 -2
  4. package/src/executors/release-publish/release-publish.impl.js +58 -17
  5. package/src/generators/init/files/ts-solution/tsconfig.base.json__tmpl__ +2 -1
  6. package/src/generators/init/init.js +1 -2
  7. package/src/generators/library/library.js +29 -135
  8. package/src/generators/library/utils/add-release-config.d.ts +11 -0
  9. package/src/generators/library/utils/add-release-config.js +150 -0
  10. package/src/generators/release-version/release-version.d.ts +1 -1
  11. package/src/generators/release-version/release-version.js +16 -14
  12. package/src/generators/release-version/schema.d.ts +1 -1
  13. package/src/generators/release-version/schema.json +23 -4
  14. package/src/generators/setup-build/generator.js +4 -0
  15. package/src/plugins/jest/start-local-registry.js +7 -3
  16. package/src/plugins/typescript/plugin.js +433 -211
  17. package/src/plugins/typescript/util.d.ts +9 -0
  18. package/src/plugins/typescript/util.js +74 -0
  19. package/src/release/utils/update-lock-file.d.ts +10 -0
  20. package/src/{generators/release-version → release}/utils/update-lock-file.js +12 -9
  21. package/src/release/version-actions.d.ts +22 -0
  22. package/src/release/version-actions.js +189 -0
  23. package/src/utils/assets/copy-assets-handler.js +11 -5
  24. package/src/utils/buildable-libs-utils.d.ts +0 -2
  25. package/src/utils/buildable-libs-utils.js +12 -42
  26. package/src/utils/find-npm-dependencies.d.ts +1 -0
  27. package/src/utils/find-npm-dependencies.js +12 -2
  28. package/src/utils/npm-config.js +1 -4
  29. package/src/utils/package-json/update-package-json.d.ts +1 -0
  30. package/src/utils/package-json/update-package-json.js +42 -1
  31. package/src/utils/package-manager-workspaces.d.ts +1 -0
  32. package/src/utils/package-manager-workspaces.js +12 -7
  33. package/src/utils/swc/add-swc-config.d.ts +1 -1
  34. package/src/utils/swc/add-swc-config.js +3 -3
  35. package/src/utils/typescript/plugin.d.ts +1 -1
  36. package/src/utils/typescript/plugin.js +27 -16
  37. package/src/utils/typescript/ts-solution-setup.d.ts +3 -2
  38. package/src/utils/typescript/ts-solution-setup.js +32 -9
  39. package/src/utils/versions.d.ts +2 -2
  40. package/src/utils/versions.js +2 -2
  41. package/src/generators/release-version/utils/update-lock-file.d.ts +0 -5
  42. package/src/utils/typescript/tsnode-register.d.ts +0 -1
  43. package/src/utils/typescript/tsnode-register.js +0 -23
@@ -3,23 +3,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createNodes = exports.createNodesV2 = exports.PLUGIN_NAME = exports.createDependencies = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
6
- const minimatch_1 = require("minimatch");
7
6
  const node_fs_1 = require("node:fs");
8
7
  const node_path_1 = require("node:path");
8
+ const posix = require("node:path/posix");
9
9
  const file_hasher_1 = require("nx/src/hasher/file-hasher");
10
+ const picomatch = require("picomatch");
10
11
  // eslint-disable-next-line @typescript-eslint/no-restricted-imports
11
12
  const lock_file_1 = require("nx/src/plugins/js/lock-file/lock-file");
12
13
  const cache_directory_1 = require("nx/src/utils/cache-directory");
13
- const ts_config_1 = require("../../utils/typescript/ts-config");
14
14
  const util_1 = require("./util");
15
+ let ts;
15
16
  const pmc = (0, devkit_1.getPackageManagerCommand)();
16
- function readTargetsCache(cachePath) {
17
- return process.env.NX_CACHE_PROJECT_GRAPH !== 'false' && (0, node_fs_1.existsSync)(cachePath)
18
- ? (0, devkit_1.readJsonFile)(cachePath)
19
- : {};
17
+ let tsConfigCache;
18
+ const tsConfigCachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, 'tsconfig-files.hash');
19
+ let cache;
20
+ function readFromCache(cachePath) {
21
+ try {
22
+ return process.env.NX_CACHE_PROJECT_GRAPH !== 'false'
23
+ ? (0, devkit_1.readJsonFile)(cachePath)
24
+ : {};
25
+ }
26
+ catch {
27
+ return {};
28
+ }
20
29
  }
21
- function writeTargetsToCache(cachePath, results) {
22
- (0, devkit_1.writeJsonFile)(cachePath, results);
30
+ function writeToCache(cachePath, data) {
31
+ (0, devkit_1.writeJsonFile)(cachePath, data, { spaces: 0 });
23
32
  }
24
33
  /**
25
34
  * @deprecated The 'createDependencies' function is now a no-op. This functionality is included in 'createNodesV2'.
@@ -34,15 +43,32 @@ exports.createNodesV2 = [
34
43
  tsConfigGlob,
35
44
  async (configFilePaths, options, context) => {
36
45
  const optionsHash = (0, file_hasher_1.hashObject)(options);
37
- const cachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, `tsc-${optionsHash}.hash`);
38
- const targetsCache = readTargetsCache(cachePath);
46
+ const targetsCachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, `tsc-${optionsHash}.hash`);
47
+ const targetsCache = readFromCache(targetsCachePath);
48
+ cache = { fileHashes: {}, rawFiles: {}, isExternalProjectReference: {} };
49
+ initializeTsConfigCache(configFilePaths, context.workspaceRoot);
39
50
  const normalizedOptions = normalizePluginOptions(options);
40
- const lockFileName = (0, lock_file_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot));
51
+ const { configFilePaths: validConfigFilePaths, hashes, projectRoots, } = await resolveValidConfigFilesAndHashes(configFilePaths, optionsHash, context);
41
52
  try {
42
- return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => createNodesInternal(configFile, options, context, lockFileName, targetsCache), configFilePaths, normalizedOptions, context);
53
+ return await (0, devkit_1.createNodesFromFiles)((configFilePath, options, context, idx) => {
54
+ const projectRoot = projectRoots[idx];
55
+ const hash = hashes[idx];
56
+ const cacheKey = `${hash}_${configFilePath}`;
57
+ targetsCache[cacheKey] ??= buildTscTargets((0, node_path_1.join)(context.workspaceRoot, configFilePath), projectRoot, options, context);
58
+ const { targets } = targetsCache[cacheKey];
59
+ return {
60
+ projects: {
61
+ [projectRoot]: {
62
+ projectType: 'library',
63
+ targets,
64
+ },
65
+ },
66
+ };
67
+ }, validConfigFilePaths, normalizedOptions, context);
43
68
  }
44
69
  finally {
45
- writeTargetsToCache(cachePath, targetsCache);
70
+ writeToCache(targetsCachePath, targetsCache);
71
+ writeToCache(tsConfigCachePath, toRelativePaths(tsConfigCache, context.workspaceRoot));
46
72
  }
47
73
  },
48
74
  ];
@@ -50,28 +76,95 @@ exports.createNodes = [
50
76
  tsConfigGlob,
51
77
  async (configFilePath, options, context) => {
52
78
  devkit_1.logger.warn('`createNodes` is deprecated. Update your plugin to utilize createNodesV2 instead. In Nx 20, this will change to the createNodesV2 API.');
79
+ const projectRoot = (0, node_path_1.dirname)(configFilePath);
80
+ if (!checkIfConfigFileShouldBeProject(configFilePath, projectRoot, context)) {
81
+ return {};
82
+ }
53
83
  const normalizedOptions = normalizePluginOptions(options);
54
- const lockFileName = (0, lock_file_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot));
55
- return createNodesInternal(configFilePath, normalizedOptions, context, lockFileName, {});
84
+ cache = { fileHashes: {}, rawFiles: {}, isExternalProjectReference: {} };
85
+ initializeTsConfigCache([configFilePath], context.workspaceRoot);
86
+ const { targets } = buildTscTargets((0, node_path_1.join)(context.workspaceRoot, configFilePath), projectRoot, normalizedOptions, context);
87
+ writeToCache(tsConfigCachePath, toRelativePaths(tsConfigCache, context.workspaceRoot));
88
+ return {
89
+ projects: {
90
+ [projectRoot]: {
91
+ projectType: 'library',
92
+ targets,
93
+ },
94
+ },
95
+ };
56
96
  },
57
97
  ];
58
- async function createNodesInternal(configFilePath, options, context, lockFileName, targetsCache) {
59
- const projectRoot = (0, node_path_1.dirname)(configFilePath);
60
- const fullConfigPath = (0, devkit_1.joinPathFragments)(context.workspaceRoot, configFilePath);
98
+ async function resolveValidConfigFilesAndHashes(configFilePaths, optionsHash, context) {
99
+ const lockFileHash = (0, file_hasher_1.hashFile)((0, node_path_1.join)(context.workspaceRoot, (0, lock_file_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot)))) ?? '';
100
+ const validConfigFilePaths = [];
101
+ const hashes = [];
102
+ const projectRoots = [];
103
+ for await (const configFilePath of configFilePaths) {
104
+ const projectRoot = (0, node_path_1.dirname)(configFilePath);
105
+ if (!checkIfConfigFileShouldBeProject(configFilePath, projectRoot, context)) {
106
+ continue;
107
+ }
108
+ projectRoots.push(projectRoot);
109
+ validConfigFilePaths.push(configFilePath);
110
+ hashes.push(await getConfigFileHash(configFilePath, context.workspaceRoot, projectRoot, optionsHash, lockFileHash));
111
+ }
112
+ return { configFilePaths: validConfigFilePaths, hashes, projectRoots };
113
+ }
114
+ /**
115
+ * The cache key is composed by:
116
+ * - hashes of the content of the relevant files that can affect what's inferred by the plugin:
117
+ * - current config file
118
+ * - config files extended by the current config file (recursively up to the root config file)
119
+ * - referenced config files that are internal to the owning Nx project of the current config file,
120
+ * or is a shallow external reference of the owning Nx project
121
+ * - lock file
122
+ * - project's package.json
123
+ * - hash of the plugin options
124
+ * - current config file path
125
+ */
126
+ async function getConfigFileHash(configFilePath, workspaceRoot, projectRoot, optionsHash, lockFileHash) {
127
+ const fullConfigPath = (0, node_path_1.join)(workspaceRoot, configFilePath);
128
+ const tsConfig = retrieveTsConfigFromCache(fullConfigPath, workspaceRoot);
129
+ const extendedConfigFiles = getExtendedConfigFiles(tsConfig, workspaceRoot);
130
+ const internalReferencedFiles = resolveInternalProjectReferences(tsConfig, workspaceRoot, projectRoot);
131
+ const externalProjectReferences = resolveShallowExternalProjectReferences(tsConfig, workspaceRoot, projectRoot);
132
+ let packageJson = null;
133
+ try {
134
+ packageJson = (0, devkit_1.readJsonFile)((0, node_path_1.join)(workspaceRoot, projectRoot, 'package.json'));
135
+ }
136
+ catch { }
137
+ return (0, file_hasher_1.hashArray)([
138
+ ...[
139
+ fullConfigPath,
140
+ ...extendedConfigFiles.files.sort(),
141
+ ...Object.keys(internalReferencedFiles).sort(),
142
+ ...Object.keys(externalProjectReferences).sort(),
143
+ ].map((file) => getFileHash(file, workspaceRoot)),
144
+ ...extendedConfigFiles.packages.sort(),
145
+ lockFileHash,
146
+ optionsHash,
147
+ ...(packageJson ? [(0, file_hasher_1.hashObject)(packageJson)] : []),
148
+ // change this to bust the cache when making changes that would yield
149
+ // different results for the same hash
150
+ (0, file_hasher_1.hashObject)({ bust: 2 }),
151
+ ]);
152
+ }
153
+ function checkIfConfigFileShouldBeProject(configFilePath, projectRoot, context) {
61
154
  // Do not create a project for the workspace root tsconfig files.
62
155
  if (projectRoot === '.') {
63
- return {};
156
+ return false;
64
157
  }
65
158
  // Do not create a project if package.json and project.json isn't there.
66
159
  const siblingFiles = (0, node_fs_1.readdirSync)((0, node_path_1.join)(context.workspaceRoot, projectRoot));
67
160
  if (!siblingFiles.includes('package.json') &&
68
161
  !siblingFiles.includes('project.json')) {
69
- return {};
162
+ return false;
70
163
  }
71
164
  // Do not create a project if it's not a tsconfig.json and there is no tsconfig.json in the same directory
72
165
  if ((0, node_path_1.basename)(configFilePath) !== 'tsconfig.json' &&
73
166
  !siblingFiles.includes('tsconfig.json')) {
74
- return {};
167
+ return false;
75
168
  }
76
169
  // Do not create project for Next.js projects since they are not compatible with
77
170
  // project references and typecheck will fail.
@@ -79,56 +172,19 @@ async function createNodesInternal(configFilePath, options, context, lockFileNam
79
172
  siblingFiles.includes('next.config.cjs') ||
80
173
  siblingFiles.includes('next.config.mjs') ||
81
174
  siblingFiles.includes('next.config.ts')) {
82
- return {};
175
+ return false;
83
176
  }
84
- /**
85
- * The cache key is composed by:
86
- * - hashes of the content of the relevant files that can affect what's inferred by the plugin:
87
- * - current config file
88
- * - config files extended by the current config file (recursively up to the root config file)
89
- * - referenced config files that are internal to the owning Nx project of the current config file, or is a shallow external reference of the owning Nx project
90
- * - lock file
91
- * - hash of the plugin options
92
- * - current config file path
93
- */
94
- const tsConfig = readCachedTsConfig(fullConfigPath);
95
- const extendedConfigFiles = getExtendedConfigFiles(fullConfigPath, tsConfig);
96
- const internalReferencedFiles = resolveInternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
97
- const externalProjectReferences = resolveShallowExternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
98
- const packageJsonPath = (0, devkit_1.joinPathFragments)(projectRoot, 'package.json');
99
- const packageJson = (0, node_fs_1.existsSync)(packageJsonPath)
100
- ? (0, devkit_1.readJsonFile)(packageJsonPath)
101
- : null;
102
- const nodeHash = (0, file_hasher_1.hashArray)([
103
- ...[
104
- fullConfigPath,
105
- ...extendedConfigFiles.files,
106
- ...Object.keys(internalReferencedFiles),
107
- ...Object.keys(externalProjectReferences),
108
- (0, node_path_1.join)(context.workspaceRoot, lockFileName),
109
- ].map(file_hasher_1.hashFile),
110
- (0, file_hasher_1.hashObject)(options),
111
- ...(packageJson ? [(0, file_hasher_1.hashObject)(packageJson)] : []),
112
- ]);
113
- const cacheKey = `${nodeHash}_${configFilePath}`;
114
- targetsCache[cacheKey] ??= buildTscTargets(fullConfigPath, projectRoot, options, context);
115
- const { targets } = targetsCache[cacheKey];
116
- return {
117
- projects: {
118
- [projectRoot]: {
119
- projectType: 'library',
120
- targets,
121
- },
122
- },
123
- };
177
+ return true;
124
178
  }
125
179
  function buildTscTargets(configFilePath, projectRoot, options, context) {
126
180
  const targets = {};
127
181
  const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
128
- const tsConfig = readCachedTsConfig(configFilePath);
182
+ const tsConfig = retrieveTsConfigFromCache(configFilePath, context.workspaceRoot);
129
183
  let internalProjectReferences;
130
184
  // Typecheck target
131
- if ((0, node_path_1.basename)(configFilePath) === 'tsconfig.json' && options.typecheck) {
185
+ if ((0, node_path_1.basename)(configFilePath) === 'tsconfig.json' &&
186
+ options.typecheck &&
187
+ tsConfig.raw?.['nx']?.addTypecheckTarget !== false) {
132
188
  internalProjectReferences = resolveInternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
133
189
  const externalProjectReferences = resolveShallowExternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
134
190
  const targetName = options.typecheck.targetName;
@@ -140,13 +196,27 @@ function buildTscTargets(configFilePath, projectRoot, options, context) {
140
196
  // `tsc --build` does not work with `noEmit: true`
141
197
  command = `echo "The 'typecheck' target is disabled because one or more project references set 'noEmit: true' in their tsconfig. Remove this property to resolve this issue."`;
142
198
  }
199
+ const dependsOn = [`^${targetName}`];
200
+ if (options.build && targets[options.build.targetName]) {
201
+ // we already processed and have a build target
202
+ dependsOn.unshift(options.build.targetName);
203
+ }
204
+ else if (options.build) {
205
+ // check if the project will have a build target
206
+ const buildConfigPath = (0, devkit_1.joinPathFragments)(projectRoot, options.build.configName);
207
+ if (context.configFiles.some((f) => f === buildConfigPath) &&
208
+ (0, util_1.isValidPackageJsonBuildConfig)(retrieveTsConfigFromCache(buildConfigPath, context.workspaceRoot), context.workspaceRoot, projectRoot)) {
209
+ dependsOn.unshift(options.build.targetName);
210
+ }
211
+ }
143
212
  targets[targetName] = {
144
- dependsOn: [`^${targetName}`],
213
+ dependsOn,
145
214
  command,
146
215
  options: { cwd: projectRoot },
147
216
  cache: true,
148
217
  inputs: getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferences, context.workspaceRoot, projectRoot),
149
- outputs: getOutputs(configFilePath, tsConfig, internalProjectReferences, context.workspaceRoot, projectRoot),
218
+ outputs: getOutputs(configFilePath, tsConfig, internalProjectReferences, context.workspaceRoot, projectRoot,
219
+ /* emitDeclarationOnly */ true),
150
220
  syncGenerators: ['@nx/js:typescript-sync'],
151
221
  metadata: {
152
222
  technologies: ['typescript'],
@@ -164,7 +234,7 @@ function buildTscTargets(configFilePath, projectRoot, options, context) {
164
234
  // Build target
165
235
  if (options.build &&
166
236
  (0, node_path_1.basename)(configFilePath) === options.build.configName &&
167
- isValidPackageJsonBuildConfig(tsConfig, context.workspaceRoot, projectRoot)) {
237
+ (0, util_1.isValidPackageJsonBuildConfig)(tsConfig, context.workspaceRoot, projectRoot)) {
168
238
  internalProjectReferences ??= resolveInternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
169
239
  const targetName = options.build.targetName;
170
240
  targets[targetName] = {
@@ -173,7 +243,9 @@ function buildTscTargets(configFilePath, projectRoot, options, context) {
173
243
  options: { cwd: projectRoot },
174
244
  cache: true,
175
245
  inputs: getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferences, context.workspaceRoot, projectRoot),
176
- outputs: getOutputs(configFilePath, tsConfig, internalProjectReferences, context.workspaceRoot, projectRoot),
246
+ outputs: getOutputs(configFilePath, tsConfig, internalProjectReferences, context.workspaceRoot, projectRoot,
247
+ // should be false for build target, but providing it just in case is set to true
248
+ tsConfig.options.emitDeclarationOnly),
177
249
  syncGenerators: ['@nx/js:typescript-sync'],
178
250
  metadata: {
179
251
  technologies: ['typescript'],
@@ -196,7 +268,7 @@ function buildTscTargets(configFilePath, projectRoot, options, context) {
196
268
  function getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferences, workspaceRoot, projectRoot) {
197
269
  const configFiles = new Set();
198
270
  const externalDependencies = ['typescript'];
199
- const extendedConfigFiles = getExtendedConfigFiles(configFilePath, tsConfig);
271
+ const extendedConfigFiles = getExtendedConfigFiles(tsConfig, workspaceRoot);
200
272
  extendedConfigFiles.files.forEach((configPath) => {
201
273
  configFiles.add(configPath);
202
274
  });
@@ -208,10 +280,57 @@ function getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferen
208
280
  ...Object.entries(internalProjectReferences),
209
281
  ];
210
282
  const absoluteProjectRoot = (0, node_path_1.join)(workspaceRoot, projectRoot);
283
+ if (!ts) {
284
+ ts = require('typescript');
285
+ }
286
+ // https://github.com/microsoft/TypeScript/blob/19b777260b26aac5707b1efd34202054164d4a9d/src/compiler/utilities.ts#L9869
287
+ const supportedTSExtensions = [
288
+ ts.Extension.Ts,
289
+ ts.Extension.Tsx,
290
+ ts.Extension.Dts,
291
+ ts.Extension.Cts,
292
+ ts.Extension.Dcts,
293
+ ts.Extension.Mts,
294
+ ts.Extension.Dmts,
295
+ ];
296
+ // https://github.com/microsoft/TypeScript/blob/19b777260b26aac5707b1efd34202054164d4a9d/src/compiler/utilities.ts#L9878
297
+ const allSupportedExtensions = [
298
+ ts.Extension.Ts,
299
+ ts.Extension.Tsx,
300
+ ts.Extension.Dts,
301
+ ts.Extension.Js,
302
+ ts.Extension.Jsx,
303
+ ts.Extension.Cts,
304
+ ts.Extension.Dcts,
305
+ ts.Extension.Cjs,
306
+ ts.Extension.Mts,
307
+ ts.Extension.Dmts,
308
+ ts.Extension.Mjs,
309
+ ];
310
+ const normalizeInput = (input, config) => {
311
+ const extensions = config.options.allowJs
312
+ ? [...allSupportedExtensions]
313
+ : [...supportedTSExtensions];
314
+ if (config.options.resolveJsonModule) {
315
+ extensions.push(ts.Extension.Json);
316
+ }
317
+ const segments = input.split('/');
318
+ // An "includes" path "foo" is implicitly a glob "foo/**/*" if its last
319
+ // segment has no extension, and does not contain any glob characters
320
+ // itself.
321
+ // https://github.com/microsoft/TypeScript/blob/19b777260b26aac5707b1efd34202054164d4a9d/src/compiler/utilities.ts#L9577-L9585
322
+ if (!/[.*?]/.test(segments.at(-1))) {
323
+ return extensions.map((ext) => `${segments.join('/')}/**/*${ext}`);
324
+ }
325
+ return [input];
326
+ };
211
327
  projectTsConfigFiles.forEach(([configPath, config]) => {
212
328
  configFiles.add(configPath);
213
329
  const offset = (0, node_path_1.relative)(absoluteProjectRoot, (0, node_path_1.dirname)(configPath));
214
- (config.raw?.include ?? []).forEach((p) => includePaths.add((0, node_path_1.join)(offset, p)));
330
+ (config.raw?.include ?? []).forEach((p) => {
331
+ const normalized = normalizeInput((0, node_path_1.join)(offset, p), config);
332
+ normalized.forEach((input) => includePaths.add(input));
333
+ });
215
334
  if (config.raw?.exclude) {
216
335
  /**
217
336
  * We need to filter out the exclude paths that are already included in
@@ -226,8 +345,8 @@ function getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferen
226
345
  });
227
346
  const normalize = (p) => (p.startsWith('./') ? p.slice(2) : p);
228
347
  config.raw.exclude.forEach((excludePath) => {
229
- if (!otherFilesInclude.some((includePath) => (0, minimatch_1.minimatch)(normalize(includePath), normalize(excludePath)) ||
230
- (0, minimatch_1.minimatch)(normalize(excludePath), normalize(includePath)))) {
348
+ if (!otherFilesInclude.some((includePath) => picomatch(normalize(excludePath))(normalize(includePath)) ||
349
+ picomatch(normalize(includePath))(normalize(excludePath)))) {
231
350
  excludePaths.add(excludePath);
232
351
  }
233
352
  });
@@ -259,7 +378,7 @@ function getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferen
259
378
  inputs.push({ externalDependencies });
260
379
  return inputs;
261
380
  }
262
- function getOutputs(configFilePath, tsConfig, internalProjectReferences, workspaceRoot, projectRoot) {
381
+ function getOutputs(configFilePath, tsConfig, internalProjectReferences, workspaceRoot, projectRoot, emitDeclarationOnly) {
263
382
  const outputs = new Set();
264
383
  // We could have more surgical outputs based on the tsconfig options, but the
265
384
  // user could override them through the command line and that wouldn't be
@@ -281,9 +400,18 @@ function getOutputs(configFilePath, tsConfig, internalProjectReferences, workspa
281
400
  : pathToInputOrOutput((0, devkit_1.joinPathFragments)(outDir, `${outFileName}.tsbuildinfo`), workspaceRoot, projectRoot));
282
401
  }
283
402
  else if (config.options.outDir) {
284
- outputs.add(pathToInputOrOutput(config.options.outDir, workspaceRoot, projectRoot));
403
+ if (emitDeclarationOnly) {
404
+ outputs.add(pathToInputOrOutput((0, devkit_1.joinPathFragments)(config.options.outDir, '**/*.d.ts'), workspaceRoot, projectRoot));
405
+ if (tsConfig.options.declarationMap) {
406
+ outputs.add(pathToInputOrOutput((0, devkit_1.joinPathFragments)(config.options.outDir, '**/*.d.ts.map'), workspaceRoot, projectRoot));
407
+ }
408
+ }
409
+ else {
410
+ outputs.add(pathToInputOrOutput(config.options.outDir, workspaceRoot, projectRoot));
411
+ }
285
412
  if (config.options.tsBuildInfoFile) {
286
- if (!(0, node_path_1.normalize)(config.options.tsBuildInfoFile).startsWith(`${(0, node_path_1.normalize)(config.options.outDir)}${node_path_1.sep}`)) {
413
+ if (emitDeclarationOnly ||
414
+ !(0, node_path_1.normalize)(config.options.tsBuildInfoFile).startsWith(`${(0, node_path_1.normalize)(config.options.outDir)}${node_path_1.sep}`)) {
287
415
  // https://www.typescriptlang.org/tsconfig#tsBuildInfoFile
288
416
  outputs.add(pathToInputOrOutput(config.options.tsBuildInfoFile, workspaceRoot, projectRoot));
289
417
  }
@@ -293,8 +421,15 @@ function getOutputs(configFilePath, tsConfig, internalProjectReferences, workspa
293
421
  const relativeRootDir = (0, node_path_1.relative)(config.options.rootDir, (0, node_path_1.join)(workspaceRoot, projectRoot));
294
422
  outputs.add(pathToInputOrOutput((0, devkit_1.joinPathFragments)(config.options.outDir, relativeRootDir, `*.tsbuildinfo`), workspaceRoot, projectRoot));
295
423
  }
424
+ else if (emitDeclarationOnly) {
425
+ // https://www.typescriptlang.org/tsconfig#tsBuildInfoFile
426
+ const name = (0, node_path_1.basename)(configFilePath, '.json');
427
+ outputs.add(pathToInputOrOutput((0, devkit_1.joinPathFragments)(config.options.outDir, `${name}.tsbuildinfo`), workspaceRoot, projectRoot));
428
+ }
296
429
  }
297
- else if (config.fileNames.length) {
430
+ else if (config.raw?.include?.length ||
431
+ config.raw?.files?.length ||
432
+ (!config.raw?.include && !config.raw?.files)) {
298
433
  // tsc produce files in place when no outDir or outFile is set
299
434
  outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.js'));
300
435
  outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.cjs'));
@@ -317,87 +452,6 @@ function getOutputs(configFilePath, tsConfig, internalProjectReferences, workspa
317
452
  });
318
453
  return Array.from(outputs);
319
454
  }
320
- /**
321
- * Validates the build configuration of a `package.json` file by ensuring that paths in the `exports`, `module`,
322
- * and `main` fields reference valid output paths within the `outDir` defined in the TypeScript configuration.
323
- * Priority is given to the `exports` field, specifically the `.` export if defined. If `exports` is not defined,
324
- * the function falls back to validating `main` and `module` fields. If `outFile` is specified, it validates that the file
325
- * is located within the output directory.
326
- * If no `package.json` file exists, it assumes the configuration is valid.
327
- *
328
- * @param tsConfig The TypeScript configuration object.
329
- * @param workspaceRoot The workspace root path.
330
- * @param projectRoot The project root path.
331
- * @returns `true` if the package has a valid build configuration; otherwise, `false`.
332
- */
333
- function isValidPackageJsonBuildConfig(tsConfig, workspaceRoot, projectRoot) {
334
- const packageJsonPath = (0, node_path_1.join)(workspaceRoot, projectRoot, 'package.json');
335
- if (!(0, node_fs_1.existsSync)(packageJsonPath)) {
336
- // If the package.json file does not exist.
337
- // Assume it's valid because it would be using `project.json` instead.
338
- return true;
339
- }
340
- const packageJson = (0, devkit_1.readJsonFile)(packageJsonPath);
341
- const outDir = tsConfig.options.outFile
342
- ? (0, node_path_1.dirname)(tsConfig.options.outFile)
343
- : tsConfig.options.outDir;
344
- const resolvedOutDir = outDir
345
- ? (0, node_path_1.resolve)(workspaceRoot, projectRoot, outDir)
346
- : undefined;
347
- const isPathSourceFile = (path) => {
348
- if (resolvedOutDir) {
349
- const pathToCheck = (0, node_path_1.resolve)(workspaceRoot, projectRoot, path);
350
- return !pathToCheck.startsWith(resolvedOutDir);
351
- }
352
- const ext = (0, node_path_1.extname)(path);
353
- // Check that the file extension is a TS file extension. As the source files are in the same directory as the output files.
354
- return ['.ts', '.tsx', '.cts', '.mts'].includes(ext);
355
- };
356
- // Checks if the value is a path within the `src` directory.
357
- const containsInvalidPath = (value) => {
358
- if (typeof value === 'string') {
359
- return isPathSourceFile(value);
360
- }
361
- else if (typeof value === 'object') {
362
- return Object.entries(value).some(([currentKey, subValue]) => {
363
- // Skip types field
364
- if (currentKey === 'types') {
365
- return false;
366
- }
367
- if (typeof subValue === 'string') {
368
- return isPathSourceFile(subValue);
369
- }
370
- return false;
371
- });
372
- }
373
- return false;
374
- };
375
- const exports = packageJson?.exports;
376
- // Check the `.` export if `exports` is defined.
377
- if (exports) {
378
- if (typeof exports === 'string') {
379
- return !isPathSourceFile(exports);
380
- }
381
- if (typeof exports === 'object' && '.' in exports) {
382
- return !containsInvalidPath(exports['.']);
383
- }
384
- // Check other exports if `.` is not defined or valid.
385
- for (const key in exports) {
386
- if (key !== '.' && containsInvalidPath(exports[key])) {
387
- return false;
388
- }
389
- }
390
- return true;
391
- }
392
- // If `exports` is not defined, fallback to `main` and `module` fields.
393
- const buildPaths = ['main', 'module'];
394
- for (const field of buildPaths) {
395
- if (packageJson[field] && isPathSourceFile(packageJson[field])) {
396
- return false;
397
- }
398
- }
399
- return true;
400
- }
401
455
  function pathToInputOrOutput(path, workspaceRoot, projectRoot) {
402
456
  const fullProjectRoot = (0, node_path_1.resolve)(workspaceRoot, projectRoot);
403
457
  const fullPath = (0, node_path_1.resolve)(workspaceRoot, path);
@@ -407,23 +461,15 @@ function pathToInputOrOutput(path, workspaceRoot, projectRoot) {
407
461
  }
408
462
  return (0, devkit_1.joinPathFragments)('{projectRoot}', pathRelativeToProjectRoot);
409
463
  }
410
- function getExtendedConfigFiles(tsConfigPath, tsConfig) {
411
- const extendedConfigFiles = new Set();
412
- const extendedExternalPackages = new Set();
413
- let currentConfigPath = tsConfigPath;
414
- let currentConfig = tsConfig;
415
- while (currentConfig.raw?.extends) {
416
- const extendedConfigPath = resolveExtendedTsConfigPath(currentConfig.raw.extends, (0, node_path_1.dirname)(currentConfigPath));
417
- if (!extendedConfigPath) {
418
- break;
419
- }
420
- if (extendedConfigPath.externalPackage) {
421
- extendedExternalPackages.add(extendedConfigPath.externalPackage);
422
- break;
423
- }
424
- extendedConfigFiles.add(extendedConfigPath.filePath);
425
- currentConfig = readCachedTsConfig(extendedConfigPath.filePath);
426
- currentConfigPath = extendedConfigPath.filePath;
464
+ function getExtendedConfigFiles(tsConfig, workspaceRoot, extendedConfigFiles = new Set(), extendedExternalPackages = new Set()) {
465
+ for (const extendedConfigFile of tsConfig.extendedConfigFiles) {
466
+ if (extendedConfigFile.externalPackage) {
467
+ extendedExternalPackages.add(extendedConfigFile.externalPackage);
468
+ }
469
+ else if (extendedConfigFile.filePath) {
470
+ extendedConfigFiles.add(extendedConfigFile.filePath);
471
+ getExtendedConfigFiles(retrieveTsConfigFromCache(extendedConfigFile.filePath, workspaceRoot), workspaceRoot, extendedConfigFiles, extendedExternalPackages);
472
+ }
427
473
  }
428
474
  return {
429
475
  files: Array.from(extendedConfigFiles),
@@ -431,27 +477,31 @@ function getExtendedConfigFiles(tsConfigPath, tsConfig) {
431
477
  };
432
478
  }
433
479
  function resolveInternalProjectReferences(tsConfig, workspaceRoot, projectRoot, projectReferences = {}) {
434
- walkProjectReferences(tsConfig, workspaceRoot, projectRoot, (configPath, config) => {
435
- if (isExternalProjectReference(configPath, workspaceRoot, projectRoot)) {
436
- return false;
480
+ if (!tsConfig.projectReferences?.length) {
481
+ return {};
482
+ }
483
+ for (const ref of tsConfig.projectReferences) {
484
+ let refConfigPath = ref.path;
485
+ if (projectReferences[refConfigPath]) {
486
+ // Already resolved
487
+ continue;
437
488
  }
438
- else {
439
- projectReferences[configPath] = config;
489
+ if (!(0, node_fs_1.existsSync)(refConfigPath)) {
490
+ // the referenced tsconfig doesn't exist, ignore it
491
+ continue;
440
492
  }
441
- });
442
- return projectReferences;
443
- }
444
- function resolveShallowExternalProjectReferences(tsConfig, workspaceRoot, projectRoot, projectReferences = {}) {
445
- walkProjectReferences(tsConfig, workspaceRoot, projectRoot, (configPath, config) => {
446
- if (isExternalProjectReference(configPath, workspaceRoot, projectRoot)) {
447
- projectReferences[configPath] = config;
493
+ if (isExternalProjectReference(refConfigPath, workspaceRoot, projectRoot)) {
494
+ continue;
448
495
  }
449
- return false;
450
- });
496
+ if (!refConfigPath.endsWith('.json')) {
497
+ refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
498
+ }
499
+ projectReferences[refConfigPath] = retrieveTsConfigFromCache(refConfigPath, workspaceRoot);
500
+ resolveInternalProjectReferences(projectReferences[refConfigPath], workspaceRoot, projectRoot, projectReferences);
501
+ }
451
502
  return projectReferences;
452
503
  }
453
- function walkProjectReferences(tsConfig, workspaceRoot, projectRoot, visitor, // false stops recursion
454
- projectReferences = {}) {
504
+ function resolveShallowExternalProjectReferences(tsConfig, workspaceRoot, projectRoot, projectReferences = {}) {
455
505
  if (!tsConfig.projectReferences?.length) {
456
506
  return projectReferences;
457
507
  }
@@ -465,13 +515,11 @@ projectReferences = {}) {
465
515
  // the referenced tsconfig doesn't exist, ignore it
466
516
  continue;
467
517
  }
468
- if (!refConfigPath.endsWith('.json')) {
469
- refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
470
- }
471
- const refTsConfig = readCachedTsConfig(refConfigPath);
472
- const result = visitor(refConfigPath, refTsConfig);
473
- if (result !== false) {
474
- walkProjectReferences(refTsConfig, workspaceRoot, projectRoot, visitor);
518
+ if (isExternalProjectReference(refConfigPath, workspaceRoot, projectRoot)) {
519
+ if (!refConfigPath.endsWith('.json')) {
520
+ refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
521
+ }
522
+ projectReferences[refConfigPath] = retrieveTsConfigFromCache(refConfigPath, workspaceRoot);
475
523
  }
476
524
  }
477
525
  return projectReferences;
@@ -497,7 +545,7 @@ function hasExternalProjectReferences(tsConfigPath, tsConfig, workspaceRoot, pro
497
545
  if (!refConfigPath.endsWith('.json')) {
498
546
  refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
499
547
  }
500
- const refTsConfig = readCachedTsConfig(refConfigPath);
548
+ const refTsConfig = retrieveTsConfigFromCache(refConfigPath, workspaceRoot);
501
549
  const result = hasExternalProjectReferences(refConfigPath, refTsConfig, workspaceRoot, projectRoot, seen);
502
550
  if (result) {
503
551
  return true;
@@ -506,21 +554,28 @@ function hasExternalProjectReferences(tsConfigPath, tsConfig, workspaceRoot, pro
506
554
  return false;
507
555
  }
508
556
  function isExternalProjectReference(refTsConfigPath, workspaceRoot, projectRoot) {
557
+ const relativePath = posixRelative(workspaceRoot, refTsConfigPath);
558
+ if (cache.isExternalProjectReference[relativePath] !== undefined) {
559
+ return cache.isExternalProjectReference[relativePath];
560
+ }
509
561
  const absoluteProjectRoot = (0, node_path_1.join)(workspaceRoot, projectRoot);
510
562
  let currentPath = getTsConfigDirName(refTsConfigPath);
511
563
  if ((0, node_path_1.relative)(absoluteProjectRoot, currentPath).startsWith('..')) {
512
564
  // it's outside of the project root, so it's an external project reference
565
+ cache.isExternalProjectReference[relativePath] = true;
513
566
  return true;
514
567
  }
515
568
  while (currentPath !== absoluteProjectRoot) {
516
569
  if ((0, node_fs_1.existsSync)((0, node_path_1.join)(currentPath, 'package.json')) ||
517
570
  (0, node_fs_1.existsSync)((0, node_path_1.join)(currentPath, 'project.json'))) {
518
571
  // it's inside a nested project root, so it's and external project reference
572
+ cache.isExternalProjectReference[relativePath] = true;
519
573
  return true;
520
574
  }
521
575
  currentPath = (0, node_path_1.dirname)(currentPath);
522
576
  }
523
577
  // it's inside the project root, so it's an internal project reference
578
+ cache.isExternalProjectReference[relativePath] = false;
524
579
  return false;
525
580
  }
526
581
  function getTsConfigDirName(tsConfigPath) {
@@ -528,19 +583,89 @@ function getTsConfigDirName(tsConfigPath) {
528
583
  ? (0, node_path_1.dirname)(tsConfigPath)
529
584
  : (0, node_path_1.normalize)(tsConfigPath);
530
585
  }
531
- const tsConfigCache = new Map();
532
- function readCachedTsConfig(tsConfigPath) {
533
- const cacheKey = getTsConfigCacheKey(tsConfigPath);
534
- if (tsConfigCache.has(cacheKey)) {
535
- return tsConfigCache.get(cacheKey);
536
- }
537
- const tsConfig = (0, ts_config_1.readTsConfig)(tsConfigPath);
538
- tsConfigCache.set(cacheKey, tsConfig);
539
- return tsConfig;
586
+ function retrieveTsConfigFromCache(tsConfigPath, workspaceRoot) {
587
+ const relativePath = posixRelative(workspaceRoot, tsConfigPath);
588
+ // we don't need to check the hash if it's in the cache, because we've already
589
+ // checked it when we initially populated the cache
590
+ return tsConfigCache[relativePath]
591
+ ? tsConfigCache[relativePath].data
592
+ : readTsConfigAndCache(tsConfigPath, workspaceRoot);
593
+ }
594
+ function initializeTsConfigCache(configFilePaths, workspaceRoot) {
595
+ tsConfigCache = toAbsolutePaths(readFromCache(tsConfigCachePath), workspaceRoot);
596
+ // ensure hashes are checked and the cache is invalidated and populated as needed
597
+ for (const configFilePath of configFilePaths) {
598
+ const fullConfigPath = (0, node_path_1.join)(workspaceRoot, configFilePath);
599
+ readTsConfigAndCache(fullConfigPath, workspaceRoot);
600
+ }
601
+ }
602
+ function readTsConfigAndCache(tsConfigPath, workspaceRoot) {
603
+ const relativePath = posixRelative(workspaceRoot, tsConfigPath);
604
+ const hash = getFileHash(tsConfigPath, workspaceRoot);
605
+ let extendedFilesHash;
606
+ if (tsConfigCache[relativePath] &&
607
+ tsConfigCache[relativePath].hash === hash) {
608
+ extendedFilesHash = getExtendedFilesHash(tsConfigCache[relativePath].data.extendedConfigFiles, workspaceRoot);
609
+ if (tsConfigCache[relativePath].extendedFilesHash === extendedFilesHash) {
610
+ return tsConfigCache[relativePath].data;
611
+ }
612
+ }
613
+ const tsConfig = readTsConfig(tsConfigPath, workspaceRoot);
614
+ const extendedConfigFiles = [];
615
+ if (tsConfig.raw?.extends) {
616
+ const extendsArray = typeof tsConfig.raw.extends === 'string'
617
+ ? [tsConfig.raw.extends]
618
+ : tsConfig.raw.extends;
619
+ for (const extendsPath of extendsArray) {
620
+ const extendedConfigFile = resolveExtendedTsConfigPath(extendsPath, (0, node_path_1.dirname)(tsConfigPath));
621
+ if (extendedConfigFile) {
622
+ extendedConfigFiles.push(extendedConfigFile);
623
+ }
624
+ }
625
+ }
626
+ extendedFilesHash ??= getExtendedFilesHash(extendedConfigFiles, workspaceRoot);
627
+ tsConfigCache[relativePath] = {
628
+ data: {
629
+ options: tsConfig.options,
630
+ projectReferences: tsConfig.projectReferences,
631
+ raw: tsConfig.raw,
632
+ extendedConfigFiles,
633
+ },
634
+ hash,
635
+ extendedFilesHash,
636
+ };
637
+ return tsConfigCache[relativePath].data;
638
+ }
639
+ function getExtendedFilesHash(extendedConfigFiles, workspaceRoot) {
640
+ const hashes = [];
641
+ if (!extendedConfigFiles.length) {
642
+ return '';
643
+ }
644
+ for (const extendedConfigFile of extendedConfigFiles) {
645
+ if (extendedConfigFile.externalPackage) {
646
+ hashes.push(extendedConfigFile.externalPackage);
647
+ }
648
+ else if (extendedConfigFile.filePath) {
649
+ hashes.push(getFileHash(extendedConfigFile.filePath, workspaceRoot));
650
+ hashes.push(getExtendedFilesHash(readTsConfigAndCache(extendedConfigFile.filePath, workspaceRoot)
651
+ .extendedConfigFiles, workspaceRoot));
652
+ }
653
+ }
654
+ return hashes.join('|');
540
655
  }
541
- function getTsConfigCacheKey(tsConfigPath) {
542
- const timestamp = (0, node_fs_1.statSync)(tsConfigPath).mtimeMs;
543
- return `${tsConfigPath}-${timestamp}`;
656
+ function readTsConfig(tsConfigPath, workspaceRoot) {
657
+ if (!ts) {
658
+ ts = require('typescript');
659
+ }
660
+ const tsSys = {
661
+ ...ts.sys,
662
+ readFile: (path) => readFile(path, workspaceRoot),
663
+ readDirectory: () => [],
664
+ };
665
+ const readResult = ts.readConfigFile(tsConfigPath, tsSys.readFile);
666
+ // read with a custom host that won't read directories which is only used
667
+ // to identify the filenames included in the program, which we won't use
668
+ return ts.parseJsonConfigFileContent(readResult.config, tsSys, (0, node_path_1.dirname)(tsConfigPath));
544
669
  }
545
670
  function normalizePluginOptions(pluginOptions = {}) {
546
671
  const defaultTypecheckTargetName = 'typecheck';
@@ -587,7 +712,8 @@ function resolveExtendedTsConfigPath(tsConfigPath, directory) {
587
712
  const resolvedPath = require.resolve(tsConfigPath, {
588
713
  paths: directory ? [directory] : undefined,
589
714
  });
590
- if (tsConfigPath.startsWith('.')) {
715
+ if (tsConfigPath.startsWith('.') ||
716
+ !resolvedPath.includes('/node_modules/')) {
591
717
  return { filePath: resolvedPath };
592
718
  }
593
719
  // parse the package from the tsconfig path
@@ -600,3 +726,99 @@ function resolveExtendedTsConfigPath(tsConfigPath, directory) {
600
726
  return null;
601
727
  }
602
728
  }
729
+ function getFileHash(filePath, workspaceRoot) {
730
+ const relativePath = posixRelative(workspaceRoot, filePath);
731
+ if (!cache.fileHashes[relativePath]) {
732
+ const content = readFile(filePath, workspaceRoot);
733
+ cache.fileHashes[relativePath] = (0, file_hasher_1.hashArray)([content]);
734
+ }
735
+ return cache.fileHashes[relativePath];
736
+ }
737
+ function readFile(filePath, workspaceRoot) {
738
+ const relativePath = posixRelative(workspaceRoot, filePath);
739
+ if (!cache.rawFiles[relativePath]) {
740
+ const content = (0, node_fs_1.readFileSync)(filePath, 'utf8');
741
+ cache.rawFiles[relativePath] = content;
742
+ }
743
+ return cache.rawFiles[relativePath];
744
+ }
745
+ function toAbsolutePaths(cache, workspaceRoot) {
746
+ const updatedCache = {};
747
+ for (const [key, { data, extendedFilesHash, hash }] of Object.entries(cache)) {
748
+ updatedCache[key] = {
749
+ data: {
750
+ options: { noEmit: data.options.noEmit },
751
+ raw: {
752
+ nx: { addTypecheckTarget: data.raw?.['nx']?.addTypecheckTarget },
753
+ },
754
+ extendedConfigFiles: data.extendedConfigFiles,
755
+ },
756
+ extendedFilesHash,
757
+ hash,
758
+ };
759
+ if (data.options.rootDir) {
760
+ updatedCache[key].data.options.rootDir = (0, node_path_1.join)(workspaceRoot, data.options.rootDir);
761
+ }
762
+ if (data.options.outDir) {
763
+ updatedCache[key].data.options.outDir = (0, node_path_1.join)(workspaceRoot, data.options.outDir);
764
+ }
765
+ if (data.options.outFile) {
766
+ updatedCache[key].data.options.outFile = (0, node_path_1.join)(workspaceRoot, data.options.outFile);
767
+ }
768
+ if (data.options.tsBuildInfoFile) {
769
+ updatedCache[key].data.options.tsBuildInfoFile = (0, node_path_1.join)(workspaceRoot, data.options.tsBuildInfoFile);
770
+ }
771
+ if (data.extendedConfigFiles.length) {
772
+ updatedCache[key].data.extendedConfigFiles.forEach((file) => {
773
+ file.filePath = (0, node_path_1.join)(workspaceRoot, file.filePath);
774
+ });
775
+ }
776
+ if (data.projectReferences) {
777
+ updatedCache[key].data.projectReferences = data.projectReferences.map((ref) => ({ ...ref, path: (0, node_path_1.join)(workspaceRoot, ref.path) }));
778
+ }
779
+ }
780
+ return updatedCache;
781
+ }
782
+ function toRelativePaths(cache, workspaceRoot) {
783
+ const updatedCache = {};
784
+ for (const [key, { data, extendedFilesHash, hash }] of Object.entries(cache)) {
785
+ updatedCache[key] = {
786
+ data: {
787
+ options: { noEmit: data.options.noEmit },
788
+ raw: {
789
+ nx: { addTypecheckTarget: data.raw?.['nx']?.addTypecheckTarget },
790
+ },
791
+ extendedConfigFiles: data.extendedConfigFiles,
792
+ },
793
+ extendedFilesHash,
794
+ hash,
795
+ };
796
+ if (data.options.rootDir) {
797
+ updatedCache[key].data.options.rootDir = posixRelative(workspaceRoot, data.options.rootDir);
798
+ }
799
+ if (data.options.outDir) {
800
+ updatedCache[key].data.options.outDir = posixRelative(workspaceRoot, data.options.outDir);
801
+ }
802
+ if (data.options.outFile) {
803
+ updatedCache[key].data.options.outFile = posixRelative(workspaceRoot, data.options.outFile);
804
+ }
805
+ if (data.options.tsBuildInfoFile) {
806
+ updatedCache[key].data.options.tsBuildInfoFile = posixRelative(workspaceRoot, data.options.tsBuildInfoFile);
807
+ }
808
+ if (data.extendedConfigFiles.length) {
809
+ updatedCache[key].data.extendedConfigFiles.forEach((file) => {
810
+ file.filePath = posixRelative(workspaceRoot, file.filePath);
811
+ });
812
+ }
813
+ if (data.projectReferences) {
814
+ updatedCache[key].data.projectReferences = data.projectReferences.map((ref) => ({
815
+ ...ref,
816
+ path: posixRelative(workspaceRoot, ref.path),
817
+ }));
818
+ }
819
+ }
820
+ return updatedCache;
821
+ }
822
+ function posixRelative(workspaceRoot, path) {
823
+ return posix.normalize((0, node_path_1.relative)(workspaceRoot, path));
824
+ }