@nx/js 21.0.0-beta.0 → 21.0.0-beta.10

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