nx 20.4.0 → 20.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +11 -11
- package/plugins/package-json.js +2 -1
- package/schemas/nx-schema.json +7 -0
- package/src/command-line/migrate/migrate.js +21 -18
- package/src/config/schema-utils.js +4 -4
- package/src/config/workspace-json-project-json.d.ts +2 -0
- package/src/daemon/server/project-graph-incremental-recomputation.js +1 -1
- package/src/devkit-exports.d.ts +1 -1
- package/src/devkit-exports.js +2 -1
- package/src/executors/run-commands/run-commands.impl.d.ts +1 -0
- package/src/executors/run-commands/run-commands.impl.js +10 -3
- package/src/executors/run-commands/schema.json +14 -0
- package/src/native/index.d.ts +9 -0
- package/src/native/native-bindings.js +1 -0
- package/src/native/nx.wasi-browser.js +11 -8
- package/src/native/nx.wasi.cjs +11 -8
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/native/tests/__fixtures__/file-lock.fixture.js +20 -0
- package/src/plugins/js/project-graph/build-dependencies/target-project-locator.d.ts +2 -1
- package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +11 -3
- package/src/plugins/js/utils/packages.d.ts +6 -1
- package/src/plugins/js/utils/packages.js +59 -12
- package/src/plugins/js/utils/register.d.ts +1 -1
- package/src/plugins/js/utils/register.js +1 -1
- package/src/plugins/js/utils/typescript.d.ts +1 -0
- package/src/plugins/js/utils/typescript.js +1 -0
- package/src/plugins/package-json/create-nodes.d.ts +3 -3
- package/src/plugins/package-json/create-nodes.js +8 -12
- package/src/project-graph/error-types.d.ts +6 -2
- package/src/project-graph/error-types.js +7 -1
- package/src/project-graph/file-utils.js +2 -1
- package/src/project-graph/nx-deps-cache.d.ts +6 -2
- package/src/project-graph/nx-deps-cache.js +66 -10
- package/src/project-graph/plugins/loaded-nx-plugin.js +6 -10
- package/src/project-graph/plugins/resolve-plugin.js +11 -2
- package/src/project-graph/plugins/transpiler.js +4 -4
- package/src/project-graph/project-graph.d.ts +3 -1
- package/src/project-graph/project-graph.js +75 -14
- package/src/tasks-runner/cache.js +3 -2
- package/src/utils/package-json.d.ts +1 -1
- package/src/utils/package-json.js +4 -2
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "nx",
|
3
|
-
"version": "20.4.
|
3
|
+
"version": "20.4.1",
|
4
4
|
"private": false,
|
5
5
|
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
6
6
|
"repository": {
|
@@ -82,16 +82,16 @@
|
|
82
82
|
}
|
83
83
|
},
|
84
84
|
"optionalDependencies": {
|
85
|
-
"@nx/nx-darwin-arm64": "20.4.
|
86
|
-
"@nx/nx-darwin-x64": "20.4.
|
87
|
-
"@nx/nx-freebsd-x64": "20.4.
|
88
|
-
"@nx/nx-linux-arm-gnueabihf": "20.4.
|
89
|
-
"@nx/nx-linux-arm64-gnu": "20.4.
|
90
|
-
"@nx/nx-linux-arm64-musl": "20.4.
|
91
|
-
"@nx/nx-linux-x64-gnu": "20.4.
|
92
|
-
"@nx/nx-linux-x64-musl": "20.4.
|
93
|
-
"@nx/nx-win32-arm64-msvc": "20.4.
|
94
|
-
"@nx/nx-win32-x64-msvc": "20.4.
|
85
|
+
"@nx/nx-darwin-arm64": "20.4.1",
|
86
|
+
"@nx/nx-darwin-x64": "20.4.1",
|
87
|
+
"@nx/nx-freebsd-x64": "20.4.1",
|
88
|
+
"@nx/nx-linux-arm-gnueabihf": "20.4.1",
|
89
|
+
"@nx/nx-linux-arm64-gnu": "20.4.1",
|
90
|
+
"@nx/nx-linux-arm64-musl": "20.4.1",
|
91
|
+
"@nx/nx-linux-x64-gnu": "20.4.1",
|
92
|
+
"@nx/nx-linux-x64-musl": "20.4.1",
|
93
|
+
"@nx/nx-win32-arm64-msvc": "20.4.1",
|
94
|
+
"@nx/nx-win32-x64-msvc": "20.4.1"
|
95
95
|
},
|
96
96
|
"nx-migrations": {
|
97
97
|
"migrations": "./migrations.json",
|
package/plugins/package-json.js
CHANGED
@@ -25,7 +25,8 @@ const plugin = {
|
|
25
25
|
'*/**/package.json',
|
26
26
|
(configFiles, options, context) => {
|
27
27
|
const cache = readPackageJsonConfigurationCache();
|
28
|
-
const
|
28
|
+
const isInPackageJsonWorkspaces = (0, package_json_1.buildPackageJsonWorkspacesMatcher)(context.workspaceRoot, (f) => (0, fileutils_1.readJsonFile)((0, path_1.join)(context.workspaceRoot, f)));
|
29
|
+
const result = (0, plugins_1.createNodesFromFiles)((packageJsonPath) => (0, package_json_1.createNodeFromPackageJson)(packageJsonPath, workspace_root_1.workspaceRoot, cache, isInPackageJsonWorkspaces(packageJsonPath)), configFiles, options, context);
|
29
30
|
writeCache(cache);
|
30
31
|
return result;
|
31
32
|
},
|
package/schemas/nx-schema.json
CHANGED
@@ -569,6 +569,13 @@
|
|
569
569
|
"cache": {
|
570
570
|
"type": "boolean",
|
571
571
|
"description": "Specifies if the given target should be cacheable"
|
572
|
+
},
|
573
|
+
"syncGenerators": {
|
574
|
+
"type": "array",
|
575
|
+
"items": {
|
576
|
+
"type": "string"
|
577
|
+
},
|
578
|
+
"description": "List of generators to run before the target to ensure the workspace is up to date"
|
572
579
|
}
|
573
580
|
},
|
574
581
|
"additionalProperties": false
|
@@ -118,10 +118,10 @@ class Migrator {
|
|
118
118
|
const packagesToCheck = await this.populatePackageJsonUpdatesAndGetPackagesToCheck(targetPackage, target);
|
119
119
|
for (const packageToCheck of packagesToCheck) {
|
120
120
|
const filteredUpdates = {};
|
121
|
-
for (const packageUpdate of packageToCheck.updates) {
|
121
|
+
for (const [packageUpdateKey, packageUpdate] of Object.entries(packageToCheck.updates)) {
|
122
122
|
if (this.areRequirementsMet(packageUpdate.requires) &&
|
123
123
|
(!this.interactive ||
|
124
|
-
(await this.runPackageJsonUpdatesConfirmationPrompt(packageUpdate)))) {
|
124
|
+
(await this.runPackageJsonUpdatesConfirmationPrompt(packageUpdate, packageUpdateKey, packageToCheck.package)))) {
|
125
125
|
Object.entries(packageUpdate.packages).forEach(([name, update]) => {
|
126
126
|
filteredUpdates[name] = update;
|
127
127
|
this.packageUpdates[name] = update;
|
@@ -166,15 +166,15 @@ class Migrator {
|
|
166
166
|
addToPackageJson: target.addToPackageJson || false,
|
167
167
|
});
|
168
168
|
const { packageJsonUpdates, packageGroupOrder } = this.getPackageJsonUpdatesFromMigrationConfig(targetPackage, targetVersion, migrationConfig);
|
169
|
-
if (!packageJsonUpdates.length) {
|
169
|
+
if (!Object.keys(packageJsonUpdates).length) {
|
170
170
|
return [];
|
171
171
|
}
|
172
|
-
const shouldCheckUpdates = packageJsonUpdates.some((packageJsonUpdate) => (this.interactive && packageJsonUpdate['x-prompt']) ||
|
172
|
+
const shouldCheckUpdates = Object.values(packageJsonUpdates).some((packageJsonUpdate) => (this.interactive && packageJsonUpdate['x-prompt']) ||
|
173
173
|
Object.keys(packageJsonUpdate.requires ?? {}).length);
|
174
174
|
if (shouldCheckUpdates) {
|
175
175
|
return [{ package: targetPackage, updates: packageJsonUpdates }];
|
176
176
|
}
|
177
|
-
const packageUpdatesToApply = packageJsonUpdates.reduce((m, c) => ({ ...m, ...c.packages }), {});
|
177
|
+
const packageUpdatesToApply = Object.values(packageJsonUpdates).reduce((m, c) => ({ ...m, ...c.packages }), {});
|
178
178
|
return (await Promise.all(Object.entries(packageUpdatesToApply).map(([packageName, packageUpdate]) => this.populatePackageJsonUpdatesAndGetPackagesToCheck(packageName, packageUpdate))))
|
179
179
|
.filter((pkgs) => pkgs.length)
|
180
180
|
.flat()
|
@@ -185,7 +185,7 @@ class Migrator {
|
|
185
185
|
const packageGroupOrder = this.getPackageJsonUpdatesFromPackageGroup(packageName, targetVersion, migrationConfig);
|
186
186
|
if (!migrationConfig.packageJsonUpdates ||
|
187
187
|
!this.getPkgVersion(packageName)) {
|
188
|
-
return { packageJsonUpdates:
|
188
|
+
return { packageJsonUpdates: {}, packageGroupOrder };
|
189
189
|
}
|
190
190
|
const packageJsonUpdates = this.filterPackageJsonUpdates(migrationConfig.packageJsonUpdates, packageName, targetVersion);
|
191
191
|
return { packageJsonUpdates, packageGroupOrder };
|
@@ -228,8 +228,8 @@ class Migrator {
|
|
228
228
|
return packageGroupOrder;
|
229
229
|
}
|
230
230
|
filterPackageJsonUpdates(packageJsonUpdates, packageName, targetVersion) {
|
231
|
-
const filteredPackageJsonUpdates =
|
232
|
-
for (const packageJsonUpdate of Object.
|
231
|
+
const filteredPackageJsonUpdates = {};
|
232
|
+
for (const [packageJsonUpdateKey, packageJsonUpdate] of Object.entries(packageJsonUpdates)) {
|
233
233
|
if (!packageJsonUpdate.packages ||
|
234
234
|
this.lt(packageJsonUpdate.version, this.getPkgVersion(packageName)) ||
|
235
235
|
this.gt(packageJsonUpdate.version, targetVersion)) {
|
@@ -254,7 +254,7 @@ class Migrator {
|
|
254
254
|
}
|
255
255
|
if (Object.keys(filtered).length) {
|
256
256
|
packageJsonUpdate.packages = filtered;
|
257
|
-
filteredPackageJsonUpdates
|
257
|
+
filteredPackageJsonUpdates[packageJsonUpdateKey] = packageJsonUpdate;
|
258
258
|
}
|
259
259
|
}
|
260
260
|
return filteredPackageJsonUpdates;
|
@@ -313,7 +313,7 @@ class Migrator {
|
|
313
313
|
includePrerelease: true,
|
314
314
|
}));
|
315
315
|
}
|
316
|
-
async runPackageJsonUpdatesConfirmationPrompt(packageUpdate) {
|
316
|
+
async runPackageJsonUpdatesConfirmationPrompt(packageUpdate, packageUpdateKey, packageName) {
|
317
317
|
if (!packageUpdate['x-prompt']) {
|
318
318
|
return Promise.resolve(true);
|
319
319
|
}
|
@@ -322,14 +322,17 @@ class Migrator {
|
|
322
322
|
// a same prompt was already answered, skip
|
323
323
|
return Promise.resolve(false);
|
324
324
|
}
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
325
|
+
const promptConfig = {
|
326
|
+
name: 'shouldApply',
|
327
|
+
type: 'confirm',
|
328
|
+
message: packageUpdate['x-prompt'],
|
329
|
+
initial: true,
|
330
|
+
};
|
331
|
+
if (packageName.startsWith('@nx/')) {
|
332
|
+
// @ts-expect-error -- enquirer types aren't correct, footer does exist
|
333
|
+
promptConfig.footer = () => chalk.dim(` View migration details at https://nx.dev/nx-api/${packageName.replace('@nx/', '')}#${packageUpdateKey.replace(/[-\.]/g, '')}packageupdates`);
|
334
|
+
}
|
335
|
+
return await (0, enquirer_1.prompt)([promptConfig]).then(({ shouldApply }) => {
|
333
336
|
this.promptAnswers[promptKey] = shouldApply;
|
334
337
|
if (!shouldApply &&
|
335
338
|
(!this.minVersionWithSkippedUpdates ||
|
@@ -79,11 +79,11 @@ function resolveSchema(schemaPath, directory, packageName, projects) {
|
|
79
79
|
paths: [directory],
|
80
80
|
});
|
81
81
|
}
|
82
|
-
let
|
82
|
+
let packageToProjectMap;
|
83
83
|
function tryResolveFromSource(path, directory, packageName, projects) {
|
84
|
-
|
85
|
-
(0, packages_1.
|
86
|
-
const localProject =
|
84
|
+
packageToProjectMap ??=
|
85
|
+
(0, packages_1.getWorkspacePackagesMetadata)(projects).packageToProjectMap;
|
86
|
+
const localProject = packageToProjectMap[packageName];
|
87
87
|
if (!localProject) {
|
88
88
|
// it doesn't match any of the package names from the local projects
|
89
89
|
return null;
|
@@ -189,6 +189,7 @@ async function processFilesAndCreateAndSerializeProjectGraph(plugins) {
|
|
189
189
|
};
|
190
190
|
}
|
191
191
|
}
|
192
|
+
(0, nx_deps_cache_1.writeCache)(g.projectFileMapCache, g.projectGraph, projectConfigurationsResult.sourceMaps, errors);
|
192
193
|
if (errors.length > 0) {
|
193
194
|
return {
|
194
195
|
error: new error_types_1.DaemonProjectGraphError(errors, g.projectGraph, projectConfigurationsResult.sourceMaps),
|
@@ -202,7 +203,6 @@ async function processFilesAndCreateAndSerializeProjectGraph(plugins) {
|
|
202
203
|
};
|
203
204
|
}
|
204
205
|
else {
|
205
|
-
(0, nx_deps_cache_1.writeCache)(g.projectFileMapCache, g.projectGraph);
|
206
206
|
return g;
|
207
207
|
}
|
208
208
|
}
|
package/src/devkit-exports.d.ts
CHANGED
@@ -16,7 +16,7 @@ export type { WorkspaceJsonConfiguration, ProjectsConfigurations, TargetDependen
|
|
16
16
|
export type { Generator, GeneratorCallback, PromiseExecutor, AsyncIteratorExecutor, Executor, ExecutorContext, TaskGraphExecutor, GeneratorsJson, ExecutorsJson, MigrationsJson, CustomHasher, HasherContext, } from './config/misc-interfaces';
|
17
17
|
export { workspaceLayout } from './config/configuration';
|
18
18
|
export type { NxPlugin, NxPluginV2, CreateNodes, CreateNodesFunction, CreateNodesResult, CreateNodesContext, CreateNodesContextV2, CreateNodesFunctionV2, CreateNodesResultV2, CreateNodesV2, CreateDependencies, CreateDependenciesContext, CreateMetadata, CreateMetadataContext, ProjectsMetadata, PreTasksExecution, PreTasksExecutionContext, PostTasksExecution, PostTasksExecutionContext, } from './project-graph/plugins';
|
19
|
-
export { AggregateCreateNodesError } from './project-graph/error-types';
|
19
|
+
export { AggregateCreateNodesError, StaleProjectGraphCacheError, } from './project-graph/error-types';
|
20
20
|
export { createNodesFromFiles } from './project-graph/plugins';
|
21
21
|
/**
|
22
22
|
* @category Tasks
|
package/src/devkit-exports.js
CHANGED
@@ -4,11 +4,12 @@
|
|
4
4
|
* Try hard to not add to this API to reduce the surface area we need to maintain.
|
5
5
|
*/
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
7
|
-
exports.isDaemonEnabled = exports.createProjectFileMapUsingProjectGraph = exports.cacheDir = exports.hashArray = exports.defaultTasksRunner = exports.getOutputsForTargetAndConfiguration = exports.readProjectsConfigurationFromProjectGraph = exports.readCachedProjectGraph = exports.createProjectGraphAsync = exports.reverse = exports.workspaceRoot = exports.normalizePath = exports.joinPathFragments = exports.stripIndents = exports.writeJsonFile = exports.readJsonFile = exports.stripJsonComments = exports.serializeJson = exports.parseJson = exports.updateJson = exports.writeJson = exports.readJson = exports.validateDependency = exports.DependencyType = exports.updateNxJson = exports.readNxJson = exports.globAsync = exports.glob = exports.getProjects = exports.updateProjectConfiguration = exports.removeProjectConfiguration = exports.readProjectConfiguration = exports.addProjectConfiguration = exports.runExecutor = exports.isWorkspacesEnabled = exports.getPackageManagerVersion = exports.detectPackageManager = exports.getPackageManagerCommand = exports.output = exports.logger = exports.createNodesFromFiles = exports.AggregateCreateNodesError = exports.workspaceLayout = void 0;
|
7
|
+
exports.isDaemonEnabled = exports.createProjectFileMapUsingProjectGraph = exports.cacheDir = exports.hashArray = exports.defaultTasksRunner = exports.getOutputsForTargetAndConfiguration = exports.readProjectsConfigurationFromProjectGraph = exports.readCachedProjectGraph = exports.createProjectGraphAsync = exports.reverse = exports.workspaceRoot = exports.normalizePath = exports.joinPathFragments = exports.stripIndents = exports.writeJsonFile = exports.readJsonFile = exports.stripJsonComments = exports.serializeJson = exports.parseJson = exports.updateJson = exports.writeJson = exports.readJson = exports.validateDependency = exports.DependencyType = exports.updateNxJson = exports.readNxJson = exports.globAsync = exports.glob = exports.getProjects = exports.updateProjectConfiguration = exports.removeProjectConfiguration = exports.readProjectConfiguration = exports.addProjectConfiguration = exports.runExecutor = exports.isWorkspacesEnabled = exports.getPackageManagerVersion = exports.detectPackageManager = exports.getPackageManagerCommand = exports.output = exports.logger = exports.createNodesFromFiles = exports.StaleProjectGraphCacheError = exports.AggregateCreateNodesError = exports.workspaceLayout = void 0;
|
8
8
|
var configuration_1 = require("./config/configuration");
|
9
9
|
Object.defineProperty(exports, "workspaceLayout", { enumerable: true, get: function () { return configuration_1.workspaceLayout; } });
|
10
10
|
var error_types_1 = require("./project-graph/error-types");
|
11
11
|
Object.defineProperty(exports, "AggregateCreateNodesError", { enumerable: true, get: function () { return error_types_1.AggregateCreateNodesError; } });
|
12
|
+
Object.defineProperty(exports, "StaleProjectGraphCacheError", { enumerable: true, get: function () { return error_types_1.StaleProjectGraphCacheError; } });
|
12
13
|
var plugins_1 = require("./project-graph/plugins");
|
13
14
|
Object.defineProperty(exports, "createNodesFromFiles", { enumerable: true, get: function () { return plugins_1.createNodesFromFiles; } });
|
14
15
|
/**
|
@@ -46,9 +46,9 @@ async function default_1(options, context) {
|
|
46
46
|
if (normalized.readyWhenStatus.length && !normalized.parallel) {
|
47
47
|
throw new Error('ERROR: Bad executor config for run-commands - "readyWhen" can only be used when "parallel=true".');
|
48
48
|
}
|
49
|
-
if (options.commands.find((c) => c.prefix || c.color || c.bgColor) &&
|
49
|
+
if (options.commands.find((c) => c.prefix || c.prefixColor || c.color || c.bgColor) &&
|
50
50
|
!options.parallel) {
|
51
|
-
throw new Error('ERROR: Bad executor config for run-commands - "prefix", "color" and "bgColor" can only be set when "parallel=true".');
|
51
|
+
throw new Error('ERROR: Bad executor config for run-commands - "prefix", "prefixColor", "color" and "bgColor" can only be set when "parallel=true".');
|
52
52
|
}
|
53
53
|
try {
|
54
54
|
const result = options.parallel
|
@@ -263,7 +263,14 @@ function addColorAndPrefix(out, config) {
|
|
263
263
|
if (config.prefix) {
|
264
264
|
out = out
|
265
265
|
.split('\n')
|
266
|
-
.map((l) =>
|
266
|
+
.map((l) => {
|
267
|
+
let prefixText = config.prefix;
|
268
|
+
if (config.prefixColor && chalk[config.prefixColor]) {
|
269
|
+
prefixText = chalk[config.prefixColor](prefixText);
|
270
|
+
}
|
271
|
+
prefixText = chalk.bold(prefixText);
|
272
|
+
return l.trim().length > 0 ? `${prefixText} ${l}` : l;
|
273
|
+
})
|
267
274
|
.join('\n');
|
268
275
|
}
|
269
276
|
if (config.color && chalk[config.color]) {
|
@@ -40,6 +40,20 @@
|
|
40
40
|
"type": "string",
|
41
41
|
"description": "Prefix in front of every line out of the output"
|
42
42
|
},
|
43
|
+
"prefixColor": {
|
44
|
+
"type": "string",
|
45
|
+
"description": "Color of the prefix",
|
46
|
+
"enum": [
|
47
|
+
"black",
|
48
|
+
"red",
|
49
|
+
"green",
|
50
|
+
"yellow",
|
51
|
+
"blue",
|
52
|
+
"magenta",
|
53
|
+
"cyan",
|
54
|
+
"white"
|
55
|
+
]
|
56
|
+
},
|
43
57
|
"color": {
|
44
58
|
"type": "string",
|
45
59
|
"description": "Color of the output",
|
package/src/native/index.d.ts
CHANGED
@@ -13,6 +13,15 @@ export declare class ChildProcess {
|
|
13
13
|
onOutput(callback: (message: string) => void): void
|
14
14
|
}
|
15
15
|
|
16
|
+
export declare class FileLock {
|
17
|
+
locked: boolean
|
18
|
+
constructor(lockFilePath: string)
|
19
|
+
unlock(): void
|
20
|
+
check(): boolean
|
21
|
+
wait(): Promise<void>
|
22
|
+
lock(): void
|
23
|
+
}
|
24
|
+
|
16
25
|
export declare class HashPlanner {
|
17
26
|
constructor(nxJson: NxJson, projectGraph: ExternalObject<ProjectGraph>)
|
18
27
|
getPlans(taskIds: Array<string>, taskGraph: TaskGraph): Record<string, string[]>
|
@@ -362,6 +362,7 @@ if (!nativeBinding) {
|
|
362
362
|
}
|
363
363
|
|
364
364
|
module.exports.ChildProcess = nativeBinding.ChildProcess
|
365
|
+
module.exports.FileLock = nativeBinding.FileLock
|
365
366
|
module.exports.HashPlanner = nativeBinding.HashPlanner
|
366
367
|
module.exports.ImportResult = nativeBinding.ImportResult
|
367
368
|
module.exports.NxCache = nativeBinding.NxCache
|
@@ -85,15 +85,18 @@ function __napi_rs_initialize_modules(__napiInstance) {
|
|
85
85
|
__napiInstance.exports['__napi_register__ExternalDependenciesInput_struct_36']?.()
|
86
86
|
__napiInstance.exports['__napi_register__DepsOutputsInput_struct_37']?.()
|
87
87
|
__napiInstance.exports['__napi_register__NxJson_struct_38']?.()
|
88
|
-
__napiInstance.exports['
|
89
|
-
__napiInstance.exports['
|
90
|
-
__napiInstance.exports['
|
91
|
-
__napiInstance.exports['
|
92
|
-
__napiInstance.exports['
|
93
|
-
__napiInstance.exports['
|
94
|
-
__napiInstance.exports['
|
95
|
-
__napiInstance.exports['
|
88
|
+
__napiInstance.exports['__napi_register__FileLock_struct_39']?.()
|
89
|
+
__napiInstance.exports['__napi_register__FileLock_impl_41']?.()
|
90
|
+
__napiInstance.exports['__napi_register__WorkspaceContext_struct_42']?.()
|
91
|
+
__napiInstance.exports['__napi_register__WorkspaceContext_impl_51']?.()
|
92
|
+
__napiInstance.exports['__napi_register__WorkspaceErrors_52']?.()
|
93
|
+
__napiInstance.exports['__napi_register__NxWorkspaceFiles_struct_53']?.()
|
94
|
+
__napiInstance.exports['__napi_register__NxWorkspaceFilesExternals_struct_54']?.()
|
95
|
+
__napiInstance.exports['__napi_register__UpdatedWorkspaceFiles_struct_55']?.()
|
96
|
+
__napiInstance.exports['__napi_register__FileMap_struct_56']?.()
|
97
|
+
__napiInstance.exports['__napi_register____test_only_transfer_file_map_57']?.()
|
96
98
|
}
|
99
|
+
export const FileLock = __napiModule.exports.FileLock
|
97
100
|
export const HashPlanner = __napiModule.exports.HashPlanner
|
98
101
|
export const ImportResult = __napiModule.exports.ImportResult
|
99
102
|
export const TaskHasher = __napiModule.exports.TaskHasher
|
package/src/native/nx.wasi.cjs
CHANGED
@@ -116,15 +116,18 @@ function __napi_rs_initialize_modules(__napiInstance) {
|
|
116
116
|
__napiInstance.exports['__napi_register__ExternalDependenciesInput_struct_36']?.()
|
117
117
|
__napiInstance.exports['__napi_register__DepsOutputsInput_struct_37']?.()
|
118
118
|
__napiInstance.exports['__napi_register__NxJson_struct_38']?.()
|
119
|
-
__napiInstance.exports['
|
120
|
-
__napiInstance.exports['
|
121
|
-
__napiInstance.exports['
|
122
|
-
__napiInstance.exports['
|
123
|
-
__napiInstance.exports['
|
124
|
-
__napiInstance.exports['
|
125
|
-
__napiInstance.exports['
|
126
|
-
__napiInstance.exports['
|
119
|
+
__napiInstance.exports['__napi_register__FileLock_struct_39']?.()
|
120
|
+
__napiInstance.exports['__napi_register__FileLock_impl_41']?.()
|
121
|
+
__napiInstance.exports['__napi_register__WorkspaceContext_struct_42']?.()
|
122
|
+
__napiInstance.exports['__napi_register__WorkspaceContext_impl_51']?.()
|
123
|
+
__napiInstance.exports['__napi_register__WorkspaceErrors_52']?.()
|
124
|
+
__napiInstance.exports['__napi_register__NxWorkspaceFiles_struct_53']?.()
|
125
|
+
__napiInstance.exports['__napi_register__NxWorkspaceFilesExternals_struct_54']?.()
|
126
|
+
__napiInstance.exports['__napi_register__UpdatedWorkspaceFiles_struct_55']?.()
|
127
|
+
__napiInstance.exports['__napi_register__FileMap_struct_56']?.()
|
128
|
+
__napiInstance.exports['__napi_register____test_only_transfer_file_map_57']?.()
|
127
129
|
}
|
130
|
+
module.exports.FileLock = __napiModule.exports.FileLock
|
128
131
|
module.exports.HashPlanner = __napiModule.exports.HashPlanner
|
129
132
|
module.exports.ImportResult = __napiModule.exports.ImportResult
|
130
133
|
module.exports.TaskHasher = __napiModule.exports.TaskHasher
|
Binary file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
const { FileLock } = require('../../native-bindings.js');
|
2
|
+
const ora = require('ora');
|
3
|
+
const tmp = require('os').tmpdir();
|
4
|
+
|
5
|
+
(async () => {
|
6
|
+
const lock = new FileLock(
|
7
|
+
require('path').join(tmp, 'nx-unit-tests', 'file-lock-fixture')
|
8
|
+
);
|
9
|
+
if (lock.locked) {
|
10
|
+
const s = ora('Waiting for lock').start();
|
11
|
+
await lock.wait();
|
12
|
+
s.stop();
|
13
|
+
console.log('waited for lock');
|
14
|
+
} else {
|
15
|
+
await lock.lock();
|
16
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
17
|
+
console.log('ran with lock');
|
18
|
+
await lock.unlock();
|
19
|
+
}
|
20
|
+
})();
|
@@ -15,7 +15,7 @@ export declare class TargetProjectLocator {
|
|
15
15
|
private tsConfig;
|
16
16
|
private paths;
|
17
17
|
private typescriptResolutionCache;
|
18
|
-
private
|
18
|
+
private packagesMetadata;
|
19
19
|
constructor(nodes: Record<string, ProjectGraphProjectNode>, externalNodes?: Record<string, ProjectGraphExternalNode>, npmResolutionCache?: NpmResolutionCache);
|
20
20
|
/**
|
21
21
|
* Resolve any workspace or external project that matches the given import expression,
|
@@ -39,6 +39,7 @@ export declare class TargetProjectLocator {
|
|
39
39
|
* @returns
|
40
40
|
*/
|
41
41
|
findPaths(normalizedImportExpr: string): string[] | undefined;
|
42
|
+
findImportInWorkspaceProjects(importPath: string): string | null;
|
42
43
|
findDependencyInWorkspaceProjects(dep: string): string | null;
|
43
44
|
private resolveImportWithTypescript;
|
44
45
|
private resolveImportWithRequire;
|
@@ -101,7 +101,7 @@ class TargetProjectLocator {
|
|
101
101
|
catch { }
|
102
102
|
// fall back to see if it's a locally linked workspace project where the
|
103
103
|
// output might not exist yet
|
104
|
-
const localProject = this.
|
104
|
+
const localProject = this.findImportInWorkspaceProjects(importExpr);
|
105
105
|
if (localProject) {
|
106
106
|
return localProject;
|
107
107
|
}
|
@@ -189,9 +189,17 @@ class TargetProjectLocator {
|
|
189
189
|
}
|
190
190
|
return undefined;
|
191
191
|
}
|
192
|
+
findImportInWorkspaceProjects(importPath) {
|
193
|
+
this.packagesMetadata ??= (0, packages_1.getWorkspacePackagesMetadata)(this.nodes);
|
194
|
+
if (this.packagesMetadata.entryPointsToProjectMap[importPath]) {
|
195
|
+
return this.packagesMetadata.entryPointsToProjectMap[importPath].name;
|
196
|
+
}
|
197
|
+
const project = (0, packages_1.matchImportToWildcardEntryPointsToProjectMap)(this.packagesMetadata.wildcardEntryPointsToProjectMap, importPath);
|
198
|
+
return project?.name;
|
199
|
+
}
|
192
200
|
findDependencyInWorkspaceProjects(dep) {
|
193
|
-
this.
|
194
|
-
return this.
|
201
|
+
this.packagesMetadata ??= (0, packages_1.getWorkspacePackagesMetadata)(this.nodes);
|
202
|
+
return this.packagesMetadata.packageToProjectMap[dep]?.name;
|
195
203
|
}
|
196
204
|
resolveImportWithTypescript(normalizedImportExpr, filePath) {
|
197
205
|
let resolvedModule;
|
@@ -1,3 +1,8 @@
|
|
1
1
|
import type { ProjectGraphProjectNode } from '../../../config/project-graph';
|
2
2
|
import type { ProjectConfiguration } from '../../../config/workspace-json-project-json';
|
3
|
-
export declare function
|
3
|
+
export declare function getWorkspacePackagesMetadata<T extends ProjectGraphProjectNode | ProjectConfiguration>(projects: Record<string, T>): {
|
4
|
+
entryPointsToProjectMap: Record<string, T>;
|
5
|
+
wildcardEntryPointsToProjectMap: Record<string, T>;
|
6
|
+
packageToProjectMap: Record<string, T>;
|
7
|
+
};
|
8
|
+
export declare function matchImportToWildcardEntryPointsToProjectMap<T extends ProjectGraphProjectNode | ProjectConfiguration>(wildcardEntryPointsToProjectMap: Record<string, T>, importPath: string): T | null;
|
@@ -1,25 +1,72 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.getWorkspacePackagesMetadata = getWorkspacePackagesMetadata;
|
4
|
+
exports.matchImportToWildcardEntryPointsToProjectMap = matchImportToWildcardEntryPointsToProjectMap;
|
5
|
+
const minimatch_1 = require("minimatch");
|
4
6
|
const posix_1 = require("node:path/posix");
|
5
|
-
function
|
6
|
-
const
|
7
|
+
function getWorkspacePackagesMetadata(projects) {
|
8
|
+
const entryPointsToProjectMap = {};
|
9
|
+
const wildcardEntryPointsToProjectMap = {};
|
10
|
+
const packageToProjectMap = {};
|
7
11
|
for (const project of Object.values(projects)) {
|
8
12
|
const metadata = 'data' in project ? project.data.metadata : project.metadata;
|
9
13
|
if (!metadata?.js) {
|
10
14
|
continue;
|
11
15
|
}
|
12
|
-
const { packageName, packageExports } = metadata.js;
|
13
|
-
|
14
|
-
|
15
|
-
//
|
16
|
-
|
16
|
+
const { packageName, packageExports, packageMain, isInPackageManagerWorkspaces, } = metadata.js;
|
17
|
+
packageToProjectMap[packageName] = project;
|
18
|
+
if (!isInPackageManagerWorkspaces) {
|
19
|
+
// it is not included in the package manager workspaces config, so we
|
20
|
+
// skip it since the exports information wouldn't be used by the Node.js
|
21
|
+
// resolution
|
22
|
+
continue;
|
17
23
|
}
|
18
|
-
|
19
|
-
|
20
|
-
|
24
|
+
if (packageExports) {
|
25
|
+
if (typeof packageExports === 'string') {
|
26
|
+
// it points to a file, which would be the equivalent of an '.' export,
|
27
|
+
// in which case the package name is the entry point
|
28
|
+
entryPointsToProjectMap[packageName] = project;
|
29
|
+
}
|
30
|
+
else {
|
31
|
+
for (const entryPoint of Object.keys(packageExports)) {
|
32
|
+
if (packageExports[entryPoint] === null) {
|
33
|
+
// if the entry point is restricted, we skip it
|
34
|
+
continue;
|
35
|
+
}
|
36
|
+
if (entryPoint.startsWith('.')) {
|
37
|
+
// it is a relative subpath export
|
38
|
+
if (entryPoint.includes('*')) {
|
39
|
+
wildcardEntryPointsToProjectMap[(0, posix_1.join)(packageName, entryPoint)] =
|
40
|
+
project;
|
41
|
+
}
|
42
|
+
else {
|
43
|
+
entryPointsToProjectMap[(0, posix_1.join)(packageName, entryPoint)] = project;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
else {
|
47
|
+
// it's a conditional export, so we use the package name as the entry point
|
48
|
+
// https://nodejs.org/api/packages.html#conditional-exports
|
49
|
+
entryPointsToProjectMap[packageName] = project;
|
50
|
+
}
|
51
|
+
}
|
21
52
|
}
|
22
53
|
}
|
54
|
+
else if (packageMain) {
|
55
|
+
// if there is no exports, but there is a main, the package name is the
|
56
|
+
// entry point
|
57
|
+
entryPointsToProjectMap[packageName] = project;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
return {
|
61
|
+
entryPointsToProjectMap,
|
62
|
+
wildcardEntryPointsToProjectMap,
|
63
|
+
packageToProjectMap,
|
64
|
+
};
|
65
|
+
}
|
66
|
+
function matchImportToWildcardEntryPointsToProjectMap(wildcardEntryPointsToProjectMap, importPath) {
|
67
|
+
if (!Object.keys(wildcardEntryPointsToProjectMap).length) {
|
68
|
+
return null;
|
23
69
|
}
|
24
|
-
|
70
|
+
const matchingPair = Object.entries(wildcardEntryPointsToProjectMap).find(([key]) => (0, minimatch_1.minimatch)(importPath, key));
|
71
|
+
return matchingPair?.[1];
|
25
72
|
}
|
@@ -33,7 +33,7 @@ export declare function getTranspiler(compilerOptions: CompilerOptions, tsConfig
|
|
33
33
|
*
|
34
34
|
* @returns cleanup method
|
35
35
|
*/
|
36
|
-
export declare function registerTranspiler(compilerOptions: CompilerOptions
|
36
|
+
export declare function registerTranspiler(compilerOptions: CompilerOptions): () => void;
|
37
37
|
/**
|
38
38
|
* @param tsConfigPath Adds the paths from a tsconfig file into node resolutions
|
39
39
|
* @returns cleanup function
|
@@ -203,7 +203,7 @@ function getTranspiler(compilerOptions, tsConfigRaw) {
|
|
203
203
|
*
|
204
204
|
* @returns cleanup method
|
205
205
|
*/
|
206
|
-
function registerTranspiler(compilerOptions
|
206
|
+
function registerTranspiler(compilerOptions) {
|
207
207
|
// Function to register transpiler that returns cleanup function
|
208
208
|
const transpiler = getTranspiler(compilerOptions);
|
209
209
|
if (!transpiler) {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import type * as ts from 'typescript';
|
2
2
|
import type { Node, SyntaxKind } from 'typescript';
|
3
3
|
export declare function readTsConfig(tsConfigPath: string): ts.ParsedCommandLine;
|
4
|
+
export declare function readTsConfigOptions(tsConfigPath: string): ts.CompilerOptions;
|
4
5
|
/**
|
5
6
|
* Find a module based on its import
|
6
7
|
*
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.readTsConfig = readTsConfig;
|
4
|
+
exports.readTsConfigOptions = readTsConfigOptions;
|
4
5
|
exports.resolveModuleByImport = resolveModuleByImport;
|
5
6
|
exports.getRootTsConfigFileName = getRootTsConfigFileName;
|
6
7
|
exports.getRootTsConfigPath = getRootTsConfigPath;
|
@@ -4,13 +4,13 @@ import { PackageJson } from '../../utils/package-json';
|
|
4
4
|
import { CreateNodesV2 } from '../../project-graph/plugins';
|
5
5
|
import { PackageJsonConfigurationCache } from '../../../plugins/package-json';
|
6
6
|
export declare const createNodesV2: CreateNodesV2;
|
7
|
-
export declare function buildPackageJsonWorkspacesMatcher(workspaceRoot: string, readJson: (
|
8
|
-
export declare function createNodeFromPackageJson(pkgJsonPath: string, workspaceRoot: string, cache: PackageJsonConfigurationCache): {
|
7
|
+
export declare function buildPackageJsonWorkspacesMatcher(workspaceRoot: string, readJson: (path: string) => any): (p: string) => boolean;
|
8
|
+
export declare function createNodeFromPackageJson(pkgJsonPath: string, workspaceRoot: string, cache: PackageJsonConfigurationCache, isInPackageManagerWorkspaces: boolean): {
|
9
9
|
projects: {
|
10
10
|
[x: string]: ProjectConfiguration;
|
11
11
|
};
|
12
12
|
};
|
13
|
-
export declare function buildProjectConfigurationFromPackageJson(packageJson: PackageJson, workspaceRoot: string, packageJsonPath: string, nxJson: NxJsonConfiguration): ProjectConfiguration & {
|
13
|
+
export declare function buildProjectConfigurationFromPackageJson(packageJson: PackageJson, workspaceRoot: string, packageJsonPath: string, nxJson: NxJsonConfiguration, isInPackageManagerWorkspaces: boolean): ProjectConfiguration & {
|
14
14
|
name: string;
|
15
15
|
};
|
16
16
|
/**
|
@@ -31,12 +31,13 @@ exports.createNodesV2 = [
|
|
31
31
|
};
|
32
32
|
const cache = (0, package_json_2.readPackageJsonConfigurationCache)();
|
33
33
|
return (0, plugins_1.createNodesFromFiles)((packageJsonPath, options, context) => {
|
34
|
-
|
34
|
+
const isInPackageManagerWorkspaces = isInPackageJsonWorkspaces(packageJsonPath);
|
35
|
+
if (!isInPackageManagerWorkspaces &&
|
35
36
|
!isNextToProjectJson(packageJsonPath)) {
|
36
37
|
// Skip if package.json is not part of the package.json workspaces and not next to a project.json.
|
37
38
|
return null;
|
38
39
|
}
|
39
|
-
return createNodeFromPackageJson(packageJsonPath, context.workspaceRoot, cache);
|
40
|
+
return createNodeFromPackageJson(packageJsonPath, context.workspaceRoot, cache, isInPackageManagerWorkspaces);
|
40
41
|
}, packageJsons, _, context);
|
41
42
|
},
|
42
43
|
];
|
@@ -78,18 +79,13 @@ function buildPackageJsonWorkspacesMatcher(workspaceRoot, readJson) {
|
|
78
79
|
*/
|
79
80
|
negativePatterns.every((negative) => (0, minimatch_1.minimatch)(p, negative));
|
80
81
|
}
|
81
|
-
function createNodeFromPackageJson(pkgJsonPath, workspaceRoot, cache) {
|
82
|
+
function createNodeFromPackageJson(pkgJsonPath, workspaceRoot, cache, isInPackageManagerWorkspaces) {
|
82
83
|
const json = (0, fileutils_1.readJsonFile)((0, node_path_1.join)(workspaceRoot, pkgJsonPath));
|
83
84
|
const projectRoot = (0, node_path_1.dirname)(pkgJsonPath);
|
84
85
|
const hash = (0, file_hasher_1.hashObject)({
|
85
86
|
...json,
|
86
87
|
root: projectRoot,
|
87
|
-
|
88
|
-
* Increment this number to force processing the package.json again. Do it
|
89
|
-
* when the implementation of this plugin is changed and results in different
|
90
|
-
* results for the same package.json contents.
|
91
|
-
*/
|
92
|
-
bust: 1,
|
88
|
+
isInPackageManagerWorkspaces,
|
93
89
|
});
|
94
90
|
const cached = cache[hash];
|
95
91
|
if (cached) {
|
@@ -99,7 +95,7 @@ function createNodeFromPackageJson(pkgJsonPath, workspaceRoot, cache) {
|
|
99
95
|
},
|
100
96
|
};
|
101
97
|
}
|
102
|
-
const project = buildProjectConfigurationFromPackageJson(json, workspaceRoot, pkgJsonPath, (0, nx_json_1.readNxJson)(workspaceRoot));
|
98
|
+
const project = buildProjectConfigurationFromPackageJson(json, workspaceRoot, pkgJsonPath, (0, nx_json_1.readNxJson)(workspaceRoot), isInPackageManagerWorkspaces);
|
103
99
|
cache[hash] = project;
|
104
100
|
return {
|
105
101
|
projects: {
|
@@ -107,7 +103,7 @@ function createNodeFromPackageJson(pkgJsonPath, workspaceRoot, cache) {
|
|
107
103
|
},
|
108
104
|
};
|
109
105
|
}
|
110
|
-
function buildProjectConfigurationFromPackageJson(packageJson, workspaceRoot, packageJsonPath, nxJson) {
|
106
|
+
function buildProjectConfigurationFromPackageJson(packageJson, workspaceRoot, packageJsonPath, nxJson, isInPackageManagerWorkspaces) {
|
111
107
|
const normalizedPath = packageJsonPath.split('\\').join('/');
|
112
108
|
const projectRoot = (0, node_path_1.dirname)(normalizedPath);
|
113
109
|
const siblingProjectJson = tryReadJson((0, node_path_1.join)(workspaceRoot, projectRoot, 'project.json'));
|
@@ -135,7 +131,7 @@ function buildProjectConfigurationFromPackageJson(packageJson, workspaceRoot, pa
|
|
135
131
|
...packageJson.nx,
|
136
132
|
targets: (0, package_json_1.readTargetsFromPackageJson)(packageJson, nxJson),
|
137
133
|
tags: (0, package_json_1.getTagsFromPackageJson)(packageJson),
|
138
|
-
metadata: (0, package_json_1.getMetadataFromPackageJson)(packageJson),
|
134
|
+
metadata: (0, package_json_1.getMetadataFromPackageJson)(packageJson, isInPackageManagerWorkspaces),
|
139
135
|
};
|
140
136
|
if (nxJson?.workspaceLayout?.appsDir != nxJson?.workspaceLayout?.libsDir &&
|
141
137
|
nxJson?.workspaceLayout?.appsDir &&
|
@@ -2,10 +2,14 @@ import { ConfigurationResult, ConfigurationSourceMaps } from './utils/project-co
|
|
2
2
|
import { ProjectConfiguration } from '../config/workspace-json-project-json';
|
3
3
|
import { ProjectGraph } from '../config/project-graph';
|
4
4
|
import { CreateNodesFunctionV2 } from './plugins/public-api';
|
5
|
+
export type ProjectGraphErrorTypes = AggregateCreateNodesError | MergeNodesError | CreateMetadataError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError | ProcessDependenciesError | WorkspaceValidityError;
|
6
|
+
export declare class StaleProjectGraphCacheError extends Error {
|
7
|
+
constructor();
|
8
|
+
}
|
5
9
|
export declare class ProjectGraphError extends Error {
|
6
10
|
#private;
|
7
11
|
private readonly errors;
|
8
|
-
constructor(errors: Array<
|
12
|
+
constructor(errors: Array<ProjectGraphErrorTypes>, partialProjectGraph: ProjectGraph, partialSourceMaps: ConfigurationSourceMaps | null);
|
9
13
|
/**
|
10
14
|
* The daemon cannot throw errors which contain methods as they are not serializable.
|
11
15
|
*
|
@@ -19,7 +23,7 @@ export declare class ProjectGraphError extends Error {
|
|
19
23
|
*/
|
20
24
|
getPartialProjectGraph(): ProjectGraph;
|
21
25
|
getPartialSourcemaps(): ConfigurationSourceMaps;
|
22
|
-
getErrors():
|
26
|
+
getErrors(): ProjectGraphErrorTypes[];
|
23
27
|
}
|
24
28
|
export declare class MultipleProjectsWithSameNameError extends Error {
|
25
29
|
conflicts: Map<string, string[]>;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
var _ProjectGraphError_partialProjectGraph, _ProjectGraphError_partialSourceMaps;
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
4
|
-
exports.LoadPluginError = exports.DaemonProjectGraphError = exports.AggregateProjectGraphError = exports.WorkspaceValidityError = exports.ProcessDependenciesError = exports.CreateMetadataError = exports.MergeNodesError = exports.AggregateCreateNodesError = exports.ProjectConfigurationsError = exports.ProjectWithNoNameError = exports.ProjectsWithNoNameError = exports.ProjectWithExistingNameError = exports.MultipleProjectsWithSameNameError = exports.ProjectGraphError = void 0;
|
4
|
+
exports.LoadPluginError = exports.DaemonProjectGraphError = exports.AggregateProjectGraphError = exports.WorkspaceValidityError = exports.ProcessDependenciesError = exports.CreateMetadataError = exports.MergeNodesError = exports.AggregateCreateNodesError = exports.ProjectConfigurationsError = exports.ProjectWithNoNameError = exports.ProjectsWithNoNameError = exports.ProjectWithExistingNameError = exports.MultipleProjectsWithSameNameError = exports.ProjectGraphError = exports.StaleProjectGraphCacheError = void 0;
|
5
5
|
exports.isProjectWithExistingNameError = isProjectWithExistingNameError;
|
6
6
|
exports.isMultipleProjectsWithSameNameError = isMultipleProjectsWithSameNameError;
|
7
7
|
exports.isProjectsWithNoNameError = isProjectsWithNoNameError;
|
@@ -14,6 +14,12 @@ exports.isCreateMetadataError = isCreateMetadataError;
|
|
14
14
|
exports.isAggregateCreateNodesError = isAggregateCreateNodesError;
|
15
15
|
exports.isMergeNodesError = isMergeNodesError;
|
16
16
|
const tslib_1 = require("tslib");
|
17
|
+
class StaleProjectGraphCacheError extends Error {
|
18
|
+
constructor() {
|
19
|
+
super('The project graph cache was stale. Ensure that it has been recently created before using `readCachedProjectGraph`.');
|
20
|
+
}
|
21
|
+
}
|
22
|
+
exports.StaleProjectGraphCacheError = StaleProjectGraphCacheError;
|
17
23
|
class ProjectGraphError extends Error {
|
18
24
|
constructor(errors, partialProjectGraph, partialSourceMaps) {
|
19
25
|
const messageFragments = ['Failed to process project graph.'];
|
@@ -154,6 +154,7 @@ function getProjectsSync(root, nxJson) {
|
|
154
154
|
...(0, package_json_1.getGlobPatternsFromPackageManagerWorkspaces)(root, fileutils_1.readJsonFile),
|
155
155
|
];
|
156
156
|
const projectFiles = (0, workspace_context_1.globWithWorkspaceContextSync)(root, patterns);
|
157
|
+
const isInPackageJsonWorkspaces = (0, package_json_1.buildPackageJsonWorkspacesMatcher)(root, (f) => (0, fileutils_1.readJsonFile)((0, path_1.join)(root, f)));
|
157
158
|
const rootMap = {};
|
158
159
|
for (const projectFile of projectFiles) {
|
159
160
|
if ((0, path_1.basename)(projectFile) === 'project.json') {
|
@@ -163,7 +164,7 @@ function getProjectsSync(root, nxJson) {
|
|
163
164
|
}
|
164
165
|
else if ((0, path_1.basename)(projectFile) === 'package.json') {
|
165
166
|
const packageJson = (0, fileutils_1.readJsonFile)(projectFile);
|
166
|
-
const config = (0, package_json_1.buildProjectConfigurationFromPackageJson)(packageJson, root, projectFile, nxJson);
|
167
|
+
const config = (0, package_json_1.buildProjectConfigurationFromPackageJson)(packageJson, root, projectFile, nxJson, isInPackageJsonWorkspaces(projectFile));
|
167
168
|
if (!rootMap[config.root]) {
|
168
169
|
(0, project_configuration_utils_1.mergeProjectConfigurationIntoRootMap)(rootMap,
|
169
170
|
// Inferred targets, tags, etc don't show up when running generators
|
@@ -1,6 +1,8 @@
|
|
1
1
|
import { NxJsonConfiguration } from '../config/nx-json';
|
2
2
|
import { FileData, FileMap, ProjectGraph } from '../config/project-graph';
|
3
3
|
import { ProjectConfiguration } from '../config/workspace-json-project-json';
|
4
|
+
import { ConfigurationSourceMaps } from './utils/project-configuration-utils';
|
5
|
+
import { ProjectGraphErrorTypes } from './error-types';
|
4
6
|
export interface FileMapCache {
|
5
7
|
version: string;
|
6
8
|
nxVersion: string;
|
@@ -11,9 +13,11 @@ export interface FileMapCache {
|
|
11
13
|
}
|
12
14
|
export declare const nxProjectGraph: string;
|
13
15
|
export declare const nxFileMap: string;
|
16
|
+
export declare const nxSourceMaps: string;
|
14
17
|
export declare function ensureCacheDirectory(): void;
|
15
18
|
export declare function readFileMapCache(): null | FileMapCache;
|
16
|
-
export declare function readProjectGraphCache(): null | ProjectGraph;
|
19
|
+
export declare function readProjectGraphCache(minimumComputedAt?: number): null | ProjectGraph;
|
20
|
+
export declare function readSourceMapsCache(): null | ConfigurationSourceMaps;
|
17
21
|
export declare function createProjectFileMapCache(nxJson: NxJsonConfiguration<'*' | string[]>, packageJsonDeps: Record<string, string>, fileMap: FileMap, tsConfig: {
|
18
22
|
compilerOptions?: {
|
19
23
|
paths?: {
|
@@ -21,7 +25,7 @@ export declare function createProjectFileMapCache(nxJson: NxJsonConfiguration<'*
|
|
21
25
|
};
|
22
26
|
};
|
23
27
|
}): FileMapCache;
|
24
|
-
export declare function writeCache(cache: FileMapCache, projectGraph: ProjectGraph): void;
|
28
|
+
export declare function writeCache(cache: FileMapCache, projectGraph: ProjectGraph, sourceMaps: ConfigurationSourceMaps, errors: ProjectGraphErrorTypes[]): void;
|
25
29
|
export declare function shouldRecomputeWholeGraph(cache: FileMapCache, packageJsonDeps: Record<string, string>, projects: Record<string, ProjectConfiguration>, nxJson: NxJsonConfiguration, tsConfig: {
|
26
30
|
compilerOptions: {
|
27
31
|
paths: {
|
@@ -1,9 +1,10 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.nxFileMap = exports.nxProjectGraph = void 0;
|
3
|
+
exports.nxSourceMaps = exports.nxFileMap = exports.nxProjectGraph = void 0;
|
4
4
|
exports.ensureCacheDirectory = ensureCacheDirectory;
|
5
5
|
exports.readFileMapCache = readFileMapCache;
|
6
6
|
exports.readProjectGraphCache = readProjectGraphCache;
|
7
|
+
exports.readSourceMapsCache = readSourceMapsCache;
|
7
8
|
exports.createProjectFileMapCache = createProjectFileMapCache;
|
8
9
|
exports.writeCache = writeCache;
|
9
10
|
exports.shouldRecomputeWholeGraph = shouldRecomputeWholeGraph;
|
@@ -14,8 +15,10 @@ const perf_hooks_1 = require("perf_hooks");
|
|
14
15
|
const cache_directory_1 = require("../utils/cache-directory");
|
15
16
|
const fileutils_1 = require("../utils/fileutils");
|
16
17
|
const versions_1 = require("../utils/versions");
|
18
|
+
const error_types_1 = require("./error-types");
|
17
19
|
exports.nxProjectGraph = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, 'project-graph.json');
|
18
20
|
exports.nxFileMap = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, 'file-map.json');
|
21
|
+
exports.nxSourceMaps = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, 'source-maps.json');
|
19
22
|
function ensureCacheDirectory() {
|
20
23
|
try {
|
21
24
|
if (!(0, node_fs_1.existsSync)(cache_directory_1.workspaceDataDirectory)) {
|
@@ -55,21 +58,62 @@ function readFileMapCache() {
|
|
55
58
|
perf_hooks_1.performance.measure('read cache', 'read cache:start', 'read cache:end');
|
56
59
|
return data ?? null;
|
57
60
|
}
|
58
|
-
function readProjectGraphCache() {
|
61
|
+
function readProjectGraphCache(minimumComputedAt) {
|
59
62
|
perf_hooks_1.performance.mark('read project-graph:start');
|
60
63
|
ensureCacheDirectory();
|
61
|
-
let data = null;
|
62
64
|
try {
|
63
65
|
if ((0, fileutils_1.fileExists)(exports.nxProjectGraph)) {
|
64
|
-
|
66
|
+
const { computedAt, errors, ...projectGraphCache } = (0, fileutils_1.readJsonFile)(exports.nxProjectGraph);
|
67
|
+
if (minimumComputedAt &&
|
68
|
+
(!computedAt || computedAt < minimumComputedAt)) {
|
69
|
+
throw new error_types_1.StaleProjectGraphCacheError();
|
70
|
+
}
|
71
|
+
if (errors && errors.length > 0) {
|
72
|
+
if (!minimumComputedAt) {
|
73
|
+
// If you didn't pass minimum computed at, we do not know if
|
74
|
+
// the errors on the cached graph would be relevant to what you
|
75
|
+
// are running. Prior to adding error handling here, the graph
|
76
|
+
// would not have been written to the cache. As such, this matches
|
77
|
+
// existing behavior of the public API.
|
78
|
+
return null;
|
79
|
+
}
|
80
|
+
throw new error_types_1.ProjectGraphError(errors, projectGraphCache, readSourceMapsCache());
|
81
|
+
}
|
82
|
+
return projectGraphCache;
|
83
|
+
}
|
84
|
+
else {
|
85
|
+
return null;
|
65
86
|
}
|
66
87
|
}
|
67
88
|
catch (error) {
|
89
|
+
if (error instanceof error_types_1.StaleProjectGraphCacheError ||
|
90
|
+
error instanceof error_types_1.ProjectGraphError) {
|
91
|
+
throw error;
|
92
|
+
}
|
68
93
|
console.log(`Error reading '${exports.nxProjectGraph}'. Continue the process without the cache.`);
|
69
94
|
console.log(error);
|
95
|
+
return null;
|
96
|
+
}
|
97
|
+
finally {
|
98
|
+
perf_hooks_1.performance.mark('read project-graph:end');
|
99
|
+
perf_hooks_1.performance.measure('read cache', 'read project-graph:start', 'read project-graph:end');
|
70
100
|
}
|
71
|
-
|
72
|
-
|
101
|
+
}
|
102
|
+
function readSourceMapsCache() {
|
103
|
+
perf_hooks_1.performance.mark('read source-maps:start');
|
104
|
+
ensureCacheDirectory();
|
105
|
+
let data = null;
|
106
|
+
try {
|
107
|
+
if ((0, fileutils_1.fileExists)(exports.nxSourceMaps)) {
|
108
|
+
data = (0, fileutils_1.readJsonFile)(exports.nxSourceMaps);
|
109
|
+
}
|
110
|
+
}
|
111
|
+
catch (error) {
|
112
|
+
console.log(`Error reading '${exports.nxSourceMaps}'. Continue the process without the cache.`);
|
113
|
+
console.log(error);
|
114
|
+
}
|
115
|
+
perf_hooks_1.performance.mark('read source-maps:end');
|
116
|
+
perf_hooks_1.performance.measure('read cache', 'read source-maps:start', 'read source-maps:end');
|
73
117
|
return data ?? null;
|
74
118
|
}
|
75
119
|
function createProjectFileMapCache(nxJson, packageJsonDeps, fileMap, tsConfig) {
|
@@ -85,7 +129,7 @@ function createProjectFileMapCache(nxJson, packageJsonDeps, fileMap, tsConfig) {
|
|
85
129
|
};
|
86
130
|
return newValue;
|
87
131
|
}
|
88
|
-
function writeCache(cache, projectGraph) {
|
132
|
+
function writeCache(cache, projectGraph, sourceMaps, errors) {
|
89
133
|
perf_hooks_1.performance.mark('write cache:start');
|
90
134
|
let retry = 1;
|
91
135
|
let done = false;
|
@@ -98,11 +142,23 @@ function writeCache(cache, projectGraph) {
|
|
98
142
|
const unique = (Math.random().toString(16) + '0000000').slice(2, 10);
|
99
143
|
const tmpProjectGraphPath = `${exports.nxProjectGraph}~${unique}`;
|
100
144
|
const tmpFileMapPath = `${exports.nxFileMap}~${unique}`;
|
145
|
+
const tmpSourceMapPath = `${exports.nxSourceMaps}~${unique}`;
|
101
146
|
try {
|
102
|
-
(0, fileutils_1.writeJsonFile)(tmpProjectGraphPath,
|
147
|
+
(0, fileutils_1.writeJsonFile)(tmpProjectGraphPath, {
|
148
|
+
...projectGraph,
|
149
|
+
errors,
|
150
|
+
computedAt: Date.now(),
|
151
|
+
});
|
103
152
|
(0, node_fs_1.renameSync)(tmpProjectGraphPath, exports.nxProjectGraph);
|
104
|
-
(0, fileutils_1.writeJsonFile)(
|
105
|
-
(0, node_fs_1.renameSync)(
|
153
|
+
(0, fileutils_1.writeJsonFile)(tmpSourceMapPath, sourceMaps);
|
154
|
+
(0, node_fs_1.renameSync)(tmpSourceMapPath, exports.nxSourceMaps);
|
155
|
+
// only write the file map if there are no errors
|
156
|
+
// if there were errors, the errors make the filemap invalid
|
157
|
+
// TODO: We should be able to keep the valid part of the filemap if the errors being thrown told us which parts of the filemap were invalid
|
158
|
+
if (errors.length === 0) {
|
159
|
+
(0, fileutils_1.writeJsonFile)(tmpFileMapPath, cache);
|
160
|
+
(0, node_fs_1.renameSync)(tmpFileMapPath, exports.nxFileMap);
|
161
|
+
}
|
106
162
|
done = true;
|
107
163
|
}
|
108
164
|
catch (err) {
|
@@ -57,27 +57,23 @@ class LoadedNxPlugin {
|
|
57
57
|
if (plugin.preTasksExecution) {
|
58
58
|
this.preTasksExecution = async (context) => {
|
59
59
|
const updates = {};
|
60
|
-
let
|
60
|
+
let originalEnv = process.env;
|
61
61
|
if ((0, enabled_1.isIsolationEnabled)() || (0, client_1.isDaemonEnabled)()) {
|
62
|
-
|
62
|
+
process.env = new Proxy(originalEnv, {
|
63
63
|
set: (target, key, value) => {
|
64
64
|
target[key] = value;
|
65
65
|
updates[key] = value;
|
66
66
|
return true;
|
67
67
|
},
|
68
68
|
});
|
69
|
-
process.env = proxy;
|
70
|
-
revokeFn = revoke;
|
71
69
|
}
|
72
70
|
await plugin.preTasksExecution(this.options, context);
|
73
|
-
|
74
|
-
revokeFn();
|
75
|
-
}
|
71
|
+
process.env = originalEnv;
|
76
72
|
return updates;
|
77
73
|
};
|
78
|
-
|
79
|
-
|
80
|
-
|
74
|
+
}
|
75
|
+
if (plugin.postTasksExecution) {
|
76
|
+
this.postTasksExecution = async (context) => plugin.postTasksExecution(this.options, context);
|
81
77
|
}
|
82
78
|
}
|
83
79
|
}
|
@@ -83,6 +83,7 @@ function lookupLocalPlugin(importPath, projects, root = workspace_root_1.workspa
|
|
83
83
|
return { path: path.join(root, projectConfig.root), projectConfig };
|
84
84
|
}
|
85
85
|
let packageEntryPointsToProjectMap;
|
86
|
+
let wildcardEntryPointsToProjectMap;
|
86
87
|
function findNxProjectForImportPath(importPath, projects, root = workspace_root_1.workspaceRoot) {
|
87
88
|
const tsConfigPaths = readTsConfigPaths(root);
|
88
89
|
const possibleTsPaths = tsConfigPaths[importPath]?.map((p) => (0, path_1.normalizePath)(path.relative(root, path.join(root, p)))) ?? [];
|
@@ -101,11 +102,19 @@ function findNxProjectForImportPath(importPath, projects, root = workspace_root_
|
|
101
102
|
}
|
102
103
|
}
|
103
104
|
}
|
104
|
-
packageEntryPointsToProjectMap
|
105
|
-
(
|
105
|
+
if (!packageEntryPointsToProjectMap && !wildcardEntryPointsToProjectMap) {
|
106
|
+
({
|
107
|
+
entryPointsToProjectMap: packageEntryPointsToProjectMap,
|
108
|
+
wildcardEntryPointsToProjectMap,
|
109
|
+
} = (0, packages_1.getWorkspacePackagesMetadata)(projects));
|
110
|
+
}
|
106
111
|
if (packageEntryPointsToProjectMap[importPath]) {
|
107
112
|
return packageEntryPointsToProjectMap[importPath];
|
108
113
|
}
|
114
|
+
const project = (0, packages_1.matchImportToWildcardEntryPointsToProjectMap)(wildcardEntryPointsToProjectMap, importPath);
|
115
|
+
if (project) {
|
116
|
+
return project;
|
117
|
+
}
|
109
118
|
logger_1.logger.verbose('Unable to find local plugin', possibleTsPaths, projectRootMappings);
|
110
119
|
throw new Error('Unable to resolve local plugin with import path ' + importPath);
|
111
120
|
}
|
@@ -23,16 +23,16 @@ function registerPluginTSTranspiler() {
|
|
23
23
|
if (!tsConfigName) {
|
24
24
|
return;
|
25
25
|
}
|
26
|
-
const
|
27
|
-
? (0, typescript_1.
|
26
|
+
const tsConfigOptions = tsConfigName
|
27
|
+
? (0, typescript_1.readTsConfigOptions)(tsConfigName)
|
28
28
|
: {};
|
29
29
|
const cleanupFns = [
|
30
30
|
(0, register_1.registerTsConfigPaths)(tsConfigName),
|
31
31
|
(0, register_1.registerTranspiler)({
|
32
32
|
experimentalDecorators: true,
|
33
33
|
emitDecoratorMetadata: true,
|
34
|
-
...
|
35
|
-
}
|
34
|
+
...tsConfigOptions,
|
35
|
+
}),
|
36
36
|
];
|
37
37
|
exports.unregisterPluginTSTranspiler = () => {
|
38
38
|
cleanupFns.forEach((fn) => fn?.());
|
@@ -2,9 +2,11 @@ import { ProjectGraph } from '../config/project-graph';
|
|
2
2
|
import { ProjectConfiguration, ProjectsConfigurations } from '../config/workspace-json-project-json';
|
3
3
|
/**
|
4
4
|
* Synchronously reads the latest cached copy of the workspace's ProjectGraph.
|
5
|
+
*
|
6
|
+
* @param {number} [minimumComputedAt] - The minimum timestamp that the cached ProjectGraph must have been computed at.
|
5
7
|
* @throws {Error} if there is no cached ProjectGraph to read from
|
6
8
|
*/
|
7
|
-
export declare function readCachedProjectGraph(): ProjectGraph;
|
9
|
+
export declare function readCachedProjectGraph(minimumComputedAt?: number): ProjectGraph;
|
8
10
|
export declare function readCachedProjectConfiguration(projectName: string): ProjectConfiguration;
|
9
11
|
/**
|
10
12
|
* Get the {@link ProjectsConfigurations} from the {@link ProjectGraph}
|
@@ -21,12 +21,18 @@ const nx_deps_cache_1 = require("./nx-deps-cache");
|
|
21
21
|
const retrieve_workspace_files_1 = require("./utils/retrieve-workspace-files");
|
22
22
|
const get_plugins_1 = require("./plugins/get-plugins");
|
23
23
|
const logger_1 = require("../utils/logger");
|
24
|
+
const native_1 = require("../native");
|
25
|
+
const path_1 = require("path");
|
26
|
+
const cache_directory_1 = require("../utils/cache-directory");
|
27
|
+
const delayed_spinner_1 = require("../utils/delayed-spinner");
|
24
28
|
/**
|
25
29
|
* Synchronously reads the latest cached copy of the workspace's ProjectGraph.
|
30
|
+
*
|
31
|
+
* @param {number} [minimumComputedAt] - The minimum timestamp that the cached ProjectGraph must have been computed at.
|
26
32
|
* @throws {Error} if there is no cached ProjectGraph to read from
|
27
33
|
*/
|
28
|
-
function readCachedProjectGraph() {
|
29
|
-
const projectGraphCache = (0, nx_deps_cache_1.readProjectGraphCache)();
|
34
|
+
function readCachedProjectGraph(minimumComputedAt) {
|
35
|
+
const projectGraphCache = (0, nx_deps_cache_1.readProjectGraphCache)(minimumComputedAt);
|
30
36
|
if (!projectGraphCache) {
|
31
37
|
const angularSpecificError = (0, fileutils_1.fileExists)(`${workspace_root_1.workspaceRoot}/angular.json`)
|
32
38
|
? (0, strip_indents_1.stripIndents) `
|
@@ -120,13 +126,13 @@ async function buildProjectGraphAndSourceMapsWithoutDaemon() {
|
|
120
126
|
...(projectConfigurationsError?.errors ?? []),
|
121
127
|
...(projectGraphError?.errors ?? []),
|
122
128
|
];
|
129
|
+
if (cacheEnabled) {
|
130
|
+
(0, nx_deps_cache_1.writeCache)(projectFileMapCache, projectGraph, sourceMaps, errors);
|
131
|
+
}
|
123
132
|
if (errors.length > 0) {
|
124
133
|
throw new error_types_1.ProjectGraphError(errors, projectGraph, sourceMaps);
|
125
134
|
}
|
126
135
|
else {
|
127
|
-
if (cacheEnabled) {
|
128
|
-
(0, nx_deps_cache_1.writeCache)(projectFileMapCache, projectGraph);
|
129
|
-
}
|
130
136
|
return { projectGraph, sourceMaps };
|
131
137
|
}
|
132
138
|
}
|
@@ -143,7 +149,7 @@ function handleProjectGraphError(opts, e) {
|
|
143
149
|
bodyLines: bodyLines,
|
144
150
|
});
|
145
151
|
}
|
146
|
-
else {
|
152
|
+
else if (typeof e.message === 'string') {
|
147
153
|
const lines = e.message.split('\n');
|
148
154
|
output_1.output.error({
|
149
155
|
title: lines[0],
|
@@ -153,12 +159,25 @@ function handleProjectGraphError(opts, e) {
|
|
153
159
|
console.error(e);
|
154
160
|
}
|
155
161
|
}
|
162
|
+
else {
|
163
|
+
console.error(e);
|
164
|
+
}
|
156
165
|
process.exit(1);
|
157
166
|
}
|
158
167
|
else {
|
159
168
|
throw e;
|
160
169
|
}
|
161
170
|
}
|
171
|
+
async function readCachedGraphAndHydrateFileMap(minimumComputedAt) {
|
172
|
+
const graph = readCachedProjectGraph(minimumComputedAt);
|
173
|
+
const projectRootMap = Object.fromEntries(Object.entries(graph.nodes).map(([project, { data }]) => [
|
174
|
+
data.root,
|
175
|
+
project,
|
176
|
+
]));
|
177
|
+
const { allWorkspaceFiles, fileMap, rustReferences } = await (0, retrieve_workspace_files_1.retrieveWorkspaceFiles)(workspace_root_1.workspaceRoot, projectRootMap);
|
178
|
+
(0, build_project_graph_1.hydrateFileMap)(fileMap, allWorkspaceFiles, rustReferences);
|
179
|
+
return graph;
|
180
|
+
}
|
162
181
|
/**
|
163
182
|
* Computes and returns a ProjectGraph.
|
164
183
|
*
|
@@ -186,17 +205,14 @@ async function createProjectGraphAsync(opts = {
|
|
186
205
|
}) {
|
187
206
|
if (process.env.NX_FORCE_REUSE_CACHED_GRAPH === 'true') {
|
188
207
|
try {
|
189
|
-
const graph = readCachedProjectGraph();
|
190
|
-
const projectRootMap = Object.fromEntries(Object.entries(graph.nodes).map(([project, { data }]) => [
|
191
|
-
data.root,
|
192
|
-
project,
|
193
|
-
]));
|
194
|
-
const { allWorkspaceFiles, fileMap, rustReferences } = await (0, retrieve_workspace_files_1.retrieveWorkspaceFiles)(workspace_root_1.workspaceRoot, projectRootMap);
|
195
|
-
(0, build_project_graph_1.hydrateFileMap)(fileMap, allWorkspaceFiles, rustReferences);
|
196
|
-
return graph;
|
197
208
|
// If no cached graph is found, we will fall through to the normal flow
|
209
|
+
const graph = await readCachedGraphAndHydrateFileMap();
|
210
|
+
return graph;
|
198
211
|
}
|
199
212
|
catch (e) {
|
213
|
+
if (e instanceof error_types_1.ProjectGraphError) {
|
214
|
+
throw e;
|
215
|
+
}
|
200
216
|
logger_1.logger.verbose('Unable to use cached project graph', e);
|
201
217
|
}
|
202
218
|
}
|
@@ -209,6 +225,48 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
|
|
209
225
|
}) {
|
210
226
|
perf_hooks_1.performance.mark('create-project-graph-async:start');
|
211
227
|
if (!client_1.daemonClient.enabled()) {
|
228
|
+
const lock = !native_1.IS_WASM
|
229
|
+
? new native_1.FileLock((0, path_1.join)(cache_directory_1.workspaceDataDirectory, 'project-graph.lock'))
|
230
|
+
: null;
|
231
|
+
let locked = lock?.locked;
|
232
|
+
while (locked) {
|
233
|
+
logger_1.logger.verbose('Waiting for graph construction in another process to complete');
|
234
|
+
const spinner = new delayed_spinner_1.DelayedSpinner('Waiting for graph construction in another process to complete');
|
235
|
+
const start = Date.now();
|
236
|
+
await lock.wait();
|
237
|
+
spinner.cleanup();
|
238
|
+
// Note: This will currently throw if any of the caches are missing...
|
239
|
+
// It would be nice if one of the processes that was waiting for the lock
|
240
|
+
// could pick up the slack and build the graph if it's missing, but
|
241
|
+
// we wouldn't want either of the below to happen:
|
242
|
+
// - All of the waiting processes to build the graph
|
243
|
+
// - Even one of the processes building the graph on a legitimate error
|
244
|
+
try {
|
245
|
+
// Ensuring that computedAt was after this process started
|
246
|
+
// waiting for the graph to complete, means that the graph
|
247
|
+
// was computed by the process was already working.
|
248
|
+
const graph = await readCachedGraphAndHydrateFileMap(start);
|
249
|
+
const sourceMaps = (0, nx_deps_cache_1.readSourceMapsCache)();
|
250
|
+
if (!sourceMaps) {
|
251
|
+
throw new Error('The project graph was computed in another process, but the source maps are missing.');
|
252
|
+
}
|
253
|
+
return {
|
254
|
+
projectGraph: graph,
|
255
|
+
sourceMaps,
|
256
|
+
};
|
257
|
+
}
|
258
|
+
catch (e) {
|
259
|
+
// If the error is that the cached graph is stale after unlock,
|
260
|
+
// the process that was working on the graph must have been canceled,
|
261
|
+
// so we will fall through to the normal flow to ensure
|
262
|
+
// its created by one of the processes that was waiting
|
263
|
+
if (!(e instanceof error_types_1.StaleProjectGraphCacheError)) {
|
264
|
+
throw e;
|
265
|
+
}
|
266
|
+
}
|
267
|
+
locked = lock.check();
|
268
|
+
}
|
269
|
+
lock?.lock();
|
212
270
|
try {
|
213
271
|
const res = await buildProjectGraphAndSourceMapsWithoutDaemon();
|
214
272
|
perf_hooks_1.performance.measure('create-project-graph-async >> retrieve-project-configurations', 'retrieve-project-configurations:start', 'retrieve-project-configurations:end');
|
@@ -221,6 +279,9 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
|
|
221
279
|
catch (e) {
|
222
280
|
handleProjectGraphError(opts, e);
|
223
281
|
}
|
282
|
+
finally {
|
283
|
+
lock.unlock();
|
284
|
+
}
|
224
285
|
}
|
225
286
|
else {
|
226
287
|
try {
|
@@ -437,18 +437,19 @@ function tryAndRetry(fn) {
|
|
437
437
|
let attempts = 0;
|
438
438
|
// Generate a random number between 2 and 4 to raise to the power of attempts
|
439
439
|
const baseExponent = Math.random() * 2 + 2;
|
440
|
+
const baseTimeout = 15;
|
440
441
|
const _try = async () => {
|
441
442
|
try {
|
442
443
|
attempts++;
|
443
444
|
return await fn();
|
444
445
|
}
|
445
446
|
catch (e) {
|
446
|
-
// Max time is
|
447
|
+
// Max time is 15 * (4 + 4² + 4³ + 4⁴ + 4⁵) = 20460ms
|
447
448
|
if (attempts === 6) {
|
448
449
|
// After enough attempts, throw the error
|
449
450
|
throw e;
|
450
451
|
}
|
451
|
-
await new Promise((res) => setTimeout(res, baseExponent ** attempts));
|
452
|
+
await new Promise((res) => setTimeout(res, baseTimeout * baseExponent ** attempts));
|
452
453
|
return await _try();
|
453
454
|
}
|
454
455
|
};
|
@@ -72,7 +72,7 @@ export declare function readNxMigrateConfig(json: Partial<PackageJson>): NxMigra
|
|
72
72
|
packageGroup?: ArrayPackageGroup;
|
73
73
|
};
|
74
74
|
export declare function buildTargetFromScript(script: string, scripts: Record<string, string>, packageManagerCommand: PackageManagerCommands): TargetConfiguration;
|
75
|
-
export declare function getMetadataFromPackageJson(packageJson: PackageJson): ProjectMetadata;
|
75
|
+
export declare function getMetadataFromPackageJson(packageJson: PackageJson, isInPackageManagerWorkspaces: boolean): ProjectMetadata;
|
76
76
|
export declare function getTagsFromPackageJson(packageJson: PackageJson): string[];
|
77
77
|
export declare function readTargetsFromPackageJson(packageJson: PackageJson, nxJson: NxJsonConfiguration): Record<string, TargetConfiguration<any>>;
|
78
78
|
/**
|
@@ -57,8 +57,8 @@ function buildTargetFromScript(script, scripts = {}, packageManagerCommand) {
|
|
57
57
|
};
|
58
58
|
}
|
59
59
|
let packageManagerCommand;
|
60
|
-
function getMetadataFromPackageJson(packageJson) {
|
61
|
-
const { scripts, nx, description, name, exports } = packageJson;
|
60
|
+
function getMetadataFromPackageJson(packageJson, isInPackageManagerWorkspaces) {
|
61
|
+
const { scripts, nx, description, name, exports, main } = packageJson;
|
62
62
|
const includedScripts = nx?.includedScripts || Object.keys(scripts ?? {});
|
63
63
|
return {
|
64
64
|
targetGroups: {
|
@@ -68,6 +68,8 @@ function getMetadataFromPackageJson(packageJson) {
|
|
68
68
|
js: {
|
69
69
|
packageName: name,
|
70
70
|
packageExports: exports,
|
71
|
+
packageMain: main,
|
72
|
+
isInPackageManagerWorkspaces,
|
71
73
|
},
|
72
74
|
};
|
73
75
|
}
|