@nx/devkit 23.3.0-beta.0 → 23.3.0-beta.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.
@@ -13,8 +13,8 @@ export { determineProjectNameAndRootOptions, ensureRootProjectName, resolveImpor
13
13
  export { isInteractive } from './src/generators/prompt';
14
14
  export { addBuildTargetDefaults, addE2eCiTargetDefaults, findTargetDefault, readTargetDefaultsForTarget, updateTargetDefault, upsertTargetDefault, } from './src/generators/target-defaults-utils';
15
15
  export { addPlugin } from './src/utils/add-plugin';
16
- export { getDeclaredPackageVersion, getInstalledPackageVersion, } from './src/utils/installed-version';
17
- export { assertSupportedInstalledPackageVersion, assertSupportedPackageVersion, } from './src/utils/version-floor';
16
+ export { getDeclaredPackageVersion, getInstalledPackageVersion, getInstalledPackageVersionFromTree, } from './src/utils/installed-version';
17
+ export { assertSupportedInstalledPackageVersion, assertSupportedPackageVersion, getResolvedPackageVersion, getSatisfyingInstalledPackageVersion, } from './src/utils/version-floor';
18
18
  export { createAsyncIterable, combineAsyncIterables, mapAsyncIterable, } from './src/utils/async-iterable';
19
19
  export { calculateHashForCreateNodes, calculateHashesForCreateNodes, } from './src/utils/calculate-hash-for-create-nodes';
20
20
  export { loadConfigFile, clearRequireCache } from './src/utils/config-utils';
package/dist/internal.js CHANGED
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createAsyncIterable = exports.assertSupportedPackageVersion = exports.assertSupportedInstalledPackageVersion = exports.getInstalledPackageVersion = exports.getDeclaredPackageVersion = exports.addPlugin = exports.upsertTargetDefault = exports.updateTargetDefault = exports.readTargetDefaultsForTarget = exports.findTargetDefault = exports.addE2eCiTargetDefaults = exports.addBuildTargetDefaults = exports.isInteractive = exports.resolveImportPath = exports.ensureRootProjectName = exports.determineProjectNameAndRootOptions = exports.toProjectRelativePath = exports.deleteMatchingProperties = exports.processTargetOutputs = exports.NoTargetsToMigrateError = exports.migrateProjectExecutorsToPluginV1 = exports.migrateProjectExecutorsToPlugin = exports.openBatchConversionSession = exports.finalizeBatchConversion = exports.AggregatedLog = exports.forEachExecutorOptions = exports.getE2EWebServerInfo = exports.getRelativeCwd = exports.determineArtifactNameAndDirectoryOptions = exports.oxfmtConfigFiles = exports.prettierConfigFiles = exports.detectFormatterInTree = exports.hashDaemonClientEnv = exports.getGraphTimeDotEnvForTask = exports.applyDaemonEnvFromClient = exports.getAppliedDaemonClientEnv = exports.getDaemonClientEnvGeneration = exports.getCatalogManager = exports.acknowledgeBuildScripts = exports.PromptResolutionError = exports.resolvePrompt = exports.SchemaResolutionError = exports.ImplementationResolutionError = exports.resolveSchema = exports.resolveImplementation = exports.emitPluginWorkerLog = exports.safeWriteFileCache = exports.PluginCache = exports.createProjectRootMappingsFromProjectConfigurations = exports.signalToCode = void 0;
4
- exports.deduceDefaultBase = exports.daemonClient = exports.createTaskId = exports.createTargetDefaultsResults = exports.createRunManyDynamicOutputRenderer = exports.createProjectRootMappings = exports.createProjectGraphAndSourceMapsAsync = exports.createPackageJson = exports.createNxCloudOnboardingURLForWelcomeApp = exports.createNxCloudOnboardingURL = exports.createLockFile = exports.createDirectory = exports.connectToNxCloud = exports.combineGlobPatterns = exports.codeFrameColumns = exports.calculateReverseDeps = exports.calculateFileChanges = exports.buildProjectGraphAndSourceMapsWithoutDaemon = exports.buildPackageJsonWorkspacesMatcher = exports.buildPackageJsonPatterns = exports.WholeFileChange = exports.TargetProjectLocator = exports.TEN_MEGABYTES = exports.SyncError = exports.RemoteCacheV2 = exports.NX_PREFIX = exports.LockFileChange = exports.LARGE_BUFFER = exports.FsTree = exports.confirmationPrompt = exports.DeletedFileChange = exports.CompositeLifeCycle = exports.Cache = exports.BatchFunctionRunner = exports.runCommandsExecutor = exports.dasherize = exports.classify = exports.capitalize = exports.camelize = exports.checkAndCleanWithSemver = exports.eachValueFrom = exports.logShowProjectCommand = exports.getNamedInputs = exports.findPluginForConfigFile = exports.clearRequireCache = exports.loadConfigFile = exports.calculateHashesForCreateNodes = exports.calculateHashForCreateNodes = exports.mapAsyncIterable = exports.combineAsyncIterables = void 0;
5
- exports.hashFile = exports.handleProjectGraphError = exports.handleImport = exports.globWithWorkspaceContext = exports.getWorkspacePackagesFromGraph = exports.getUnparsedOverrideArgs = exports.getTargetInputs = exports.getTargetConfigurationForTask = exports.getSourceDirOfDependentProjects = exports.getSerializedArgsForTask = exports.getRelativeProjectJsonSchemaPath = exports.getPrintableCommandArgsForTask = exports.getOutputs = exports.getNxRequirePaths = exports.getNxCloudUrl = exports.getNxCloudAppOnBoardingUrl = exports.getLockFileName = exports.getLatestCommitSha = exports.getLastValueFromAsyncIterableIterator = exports.getGlobPatternsFromPackageManagerWorkspaces = exports.getGeneratorInformation = exports.getFilesInDirectoryUsingContext = exports.getExecutorNameForTask = exports.getExecutorInformation = exports.getExecutorForTask = exports.getEnvPathsForTask = exports.getEnvFilesForTask = exports.getDependencyConfigs = exports.getCustomHasher = exports.getCliPath = exports.generatePrunedDeployOutput = exports.forceRegisterEsmLoader = exports.findProjectsNpmDependencies = exports.findProjectForPath = exports.findMatchingTargetNames = exports.findMatchingProjects = exports.findMatchingConfigFiles = exports.findInstalledPlugins = exports.findAllProjectNodeDependencies = exports.filterUsingGlobPatterns = exports.fileExists = exports.fileDataDepType = exports.fileDataDepTarget = exports.expandWildcardTargetConfiguration = exports.expandInitiatingTasksThroughNoop = exports.expandDependencyConfigSyntaxSugar = exports.dropEmptyPeerDependencySections = exports.directoryExists = exports.deriveGroupNameFromTarget = exports.defaultFileRead = void 0;
6
- exports.setupAiAgentsGenerator = exports.setWorkspaceRoot = exports.selectPrompt = exports.safeSpawn = exports.safeExecFileSync = exports.runNxSync = exports.resolveCommandSyntacticSugar = exports.resetWorkspaceContext = exports.requireWithTsconfigFallback = exports.removeTasksFromTaskGraph = exports.relocatePrunedLocalPathSpec = exports.registerTsProject = exports.registerTsConfigPaths = exports.readProjectAndTargetFromTargetString = exports.readPackageJson = exports.readNxMigrateConfig = exports.readNxJsonFromDisk = exports.readModulePackageJson = exports.readFileMapCache = exports.readFileIfExisting = exports.readCachedProjectConfiguration = exports.quoteShellArg = exports.preventRecursionInGraphConstruction = exports.parseVersionFromPackageManagerField = exports.parseExecutor = exports.orange = exports.nxVersion = exports.normalizeTargetDependencyWithStringProjects = exports.normalizeDependencyConfigProjects = exports.normalizeDependencyConfigDefinition = exports.multiselectPrompt = exports.movePeerDependencyToDependencies = exports.mergeTargetConfigurations = exports.loadTsFile = exports.killProcessTreeGraceful = exports.killChildOnHostExit = exports.isWholeFileChange = exports.isRelativePath = exports.isProjectGraphProjectNode = exports.isProjectGraphExternalNode = exports.isNxCloudUsed = exports.isNpmProject = exports.isLockFileChange = exports.isDeletedFileChange = exports.isCacheableTask = exports.isCI = exports.isBuiltinModuleImport = exports.interpolate = exports.hashWithWorkspaceContext = exports.hashObject = void 0;
7
- exports.workspaceRootInner = exports.workspaceDataDirectory = exports.warnUnshippableLocalPathSpec = exports.validateOutputs = exports.unparse = exports.textPrompt = exports.transformLegacyOutputs = exports.toOldFormat = exports.toNewFormat = exports.shouldStreamOutput = exports.setupWorkspaceContext = void 0;
3
+ exports.assertSupportedPackageVersion = exports.assertSupportedInstalledPackageVersion = exports.getInstalledPackageVersionFromTree = exports.getInstalledPackageVersion = exports.getDeclaredPackageVersion = exports.addPlugin = exports.upsertTargetDefault = exports.updateTargetDefault = exports.readTargetDefaultsForTarget = exports.findTargetDefault = exports.addE2eCiTargetDefaults = exports.addBuildTargetDefaults = exports.isInteractive = exports.resolveImportPath = exports.ensureRootProjectName = exports.determineProjectNameAndRootOptions = exports.toProjectRelativePath = exports.deleteMatchingProperties = exports.processTargetOutputs = exports.NoTargetsToMigrateError = exports.migrateProjectExecutorsToPluginV1 = exports.migrateProjectExecutorsToPlugin = exports.openBatchConversionSession = exports.finalizeBatchConversion = exports.AggregatedLog = exports.forEachExecutorOptions = exports.getE2EWebServerInfo = exports.getRelativeCwd = exports.determineArtifactNameAndDirectoryOptions = exports.oxfmtConfigFiles = exports.prettierConfigFiles = exports.detectFormatterInTree = exports.hashDaemonClientEnv = exports.getGraphTimeDotEnvForTask = exports.applyDaemonEnvFromClient = exports.getAppliedDaemonClientEnv = exports.getDaemonClientEnvGeneration = exports.getCatalogManager = exports.acknowledgeBuildScripts = exports.PromptResolutionError = exports.resolvePrompt = exports.SchemaResolutionError = exports.ImplementationResolutionError = exports.resolveSchema = exports.resolveImplementation = exports.emitPluginWorkerLog = exports.safeWriteFileCache = exports.PluginCache = exports.createProjectRootMappingsFromProjectConfigurations = exports.signalToCode = void 0;
4
+ exports.createTargetDefaultsResults = exports.createRunManyDynamicOutputRenderer = exports.createProjectRootMappings = exports.createProjectGraphAndSourceMapsAsync = exports.createPackageJson = exports.createNxCloudOnboardingURLForWelcomeApp = exports.createNxCloudOnboardingURL = exports.createLockFile = exports.createDirectory = exports.connectToNxCloud = exports.combineGlobPatterns = exports.codeFrameColumns = exports.calculateReverseDeps = exports.calculateFileChanges = exports.buildProjectGraphAndSourceMapsWithoutDaemon = exports.buildPackageJsonWorkspacesMatcher = exports.buildPackageJsonPatterns = exports.WholeFileChange = exports.TargetProjectLocator = exports.TEN_MEGABYTES = exports.SyncError = exports.RemoteCacheV2 = exports.NX_PREFIX = exports.LockFileChange = exports.LARGE_BUFFER = exports.FsTree = exports.confirmationPrompt = exports.DeletedFileChange = exports.CompositeLifeCycle = exports.Cache = exports.BatchFunctionRunner = exports.runCommandsExecutor = exports.dasherize = exports.classify = exports.capitalize = exports.camelize = exports.checkAndCleanWithSemver = exports.eachValueFrom = exports.logShowProjectCommand = exports.getNamedInputs = exports.findPluginForConfigFile = exports.clearRequireCache = exports.loadConfigFile = exports.calculateHashesForCreateNodes = exports.calculateHashForCreateNodes = exports.mapAsyncIterable = exports.combineAsyncIterables = exports.createAsyncIterable = exports.getSatisfyingInstalledPackageVersion = exports.getResolvedPackageVersion = void 0;
5
+ exports.globWithWorkspaceContext = exports.getWorkspacePackagesFromGraph = exports.getUnparsedOverrideArgs = exports.getTargetInputs = exports.getTargetConfigurationForTask = exports.getSourceDirOfDependentProjects = exports.getSerializedArgsForTask = exports.getRelativeProjectJsonSchemaPath = exports.getPrintableCommandArgsForTask = exports.getOutputs = exports.getNxRequirePaths = exports.getNxCloudUrl = exports.getNxCloudAppOnBoardingUrl = exports.getLockFileName = exports.getLatestCommitSha = exports.getLastValueFromAsyncIterableIterator = exports.getGlobPatternsFromPackageManagerWorkspaces = exports.getGeneratorInformation = exports.getFilesInDirectoryUsingContext = exports.getExecutorNameForTask = exports.getExecutorInformation = exports.getExecutorForTask = exports.getEnvPathsForTask = exports.getEnvFilesForTask = exports.getDependencyConfigs = exports.getCustomHasher = exports.getCliPath = exports.generatePrunedDeployOutput = exports.forceRegisterEsmLoader = exports.findProjectsNpmDependencies = exports.findProjectForPath = exports.findMatchingTargetNames = exports.findMatchingProjects = exports.findMatchingConfigFiles = exports.findInstalledPlugins = exports.findAllProjectNodeDependencies = exports.filterUsingGlobPatterns = exports.fileExists = exports.fileDataDepType = exports.fileDataDepTarget = exports.expandWildcardTargetConfiguration = exports.expandInitiatingTasksThroughNoop = exports.expandDependencyConfigSyntaxSugar = exports.dropEmptyPeerDependencySections = exports.directoryExists = exports.deriveGroupNameFromTarget = exports.defaultFileRead = exports.deduceDefaultBase = exports.daemonClient = exports.createTaskId = void 0;
6
+ exports.safeSpawn = exports.safeExecFileSync = exports.runNxSync = exports.resolveCommandSyntacticSugar = exports.resetWorkspaceContext = exports.requireWithTsconfigFallback = exports.removeTasksFromTaskGraph = exports.relocatePrunedLocalPathSpec = exports.registerTsProject = exports.registerTsConfigPaths = exports.readProjectAndTargetFromTargetString = exports.readPackageJson = exports.readNxMigrateConfig = exports.readNxJsonFromDisk = exports.readModulePackageJson = exports.readFileMapCache = exports.readFileIfExisting = exports.readCachedProjectConfiguration = exports.quoteShellArg = exports.preventRecursionInGraphConstruction = exports.parseVersionFromPackageManagerField = exports.parseExecutor = exports.orange = exports.nxVersion = exports.normalizeTargetDependencyWithStringProjects = exports.normalizeDependencyConfigProjects = exports.normalizeDependencyConfigDefinition = exports.multiselectPrompt = exports.movePeerDependencyToDependencies = exports.mergeTargetConfigurations = exports.loadTsFile = exports.killProcessTreeGraceful = exports.killChildOnHostExit = exports.isWholeFileChange = exports.isRelativePath = exports.isProjectGraphProjectNode = exports.isProjectGraphExternalNode = exports.isNxCloudUsed = exports.isNpmProject = exports.isLockFileChange = exports.isDeletedFileChange = exports.isCacheableTask = exports.isCI = exports.isBuiltinModuleImport = exports.interpolate = exports.hashWithWorkspaceContext = exports.hashObject = exports.hashFile = exports.handleProjectGraphError = exports.handleImport = void 0;
7
+ exports.workspaceRootInner = exports.workspaceDataDirectory = exports.warnUnshippableLocalPathSpec = exports.validateOutputs = exports.unparse = exports.textPrompt = exports.transformLegacyOutputs = exports.toOldFormat = exports.toNewFormat = exports.shouldStreamOutput = exports.setupWorkspaceContext = exports.setupAiAgentsGenerator = exports.setWorkspaceRoot = exports.selectPrompt = void 0;
8
8
  var devkit_internals_1 = require("nx/src/devkit-internals");
9
9
  Object.defineProperty(exports, "signalToCode", { enumerable: true, get: function () { return devkit_internals_1.signalToCode; } });
10
10
  Object.defineProperty(exports, "createProjectRootMappingsFromProjectConfigurations", { enumerable: true, get: function () { return devkit_internals_1.createProjectRootMappingsFromProjectConfigurations; } });
@@ -80,9 +80,12 @@ Object.defineProperty(exports, "addPlugin", { enumerable: true, get: function ()
80
80
  var installed_version_1 = require("./src/utils/installed-version");
81
81
  Object.defineProperty(exports, "getDeclaredPackageVersion", { enumerable: true, get: function () { return installed_version_1.getDeclaredPackageVersion; } });
82
82
  Object.defineProperty(exports, "getInstalledPackageVersion", { enumerable: true, get: function () { return installed_version_1.getInstalledPackageVersion; } });
83
+ Object.defineProperty(exports, "getInstalledPackageVersionFromTree", { enumerable: true, get: function () { return installed_version_1.getInstalledPackageVersionFromTree; } });
83
84
  var version_floor_1 = require("./src/utils/version-floor");
84
85
  Object.defineProperty(exports, "assertSupportedInstalledPackageVersion", { enumerable: true, get: function () { return version_floor_1.assertSupportedInstalledPackageVersion; } });
85
86
  Object.defineProperty(exports, "assertSupportedPackageVersion", { enumerable: true, get: function () { return version_floor_1.assertSupportedPackageVersion; } });
87
+ Object.defineProperty(exports, "getResolvedPackageVersion", { enumerable: true, get: function () { return version_floor_1.getResolvedPackageVersion; } });
88
+ Object.defineProperty(exports, "getSatisfyingInstalledPackageVersion", { enumerable: true, get: function () { return version_floor_1.getSatisfyingInstalledPackageVersion; } });
86
89
  var async_iterable_1 = require("./src/utils/async-iterable");
87
90
  Object.defineProperty(exports, "createAsyncIterable", { enumerable: true, get: function () { return async_iterable_1.createAsyncIterable; } });
88
91
  Object.defineProperty(exports, "combineAsyncIterables", { enumerable: true, get: function () { return async_iterable_1.combineAsyncIterables; } });
@@ -20,7 +20,8 @@ export declare function throwForUnsupportedVersion(packageName: string, installe
20
20
  * Resolution order:
21
21
  * - When the installed version satisfies the declared range, the installed
22
22
  * version decides. This resolves open ranges (e.g. `>=4.8.4 <6.1.0`) to
23
- * what is actually installed.
23
+ * what is actually installed. An install behind a declaration that is not a
24
+ * range (e.g. `file:../pkg`) decides as well.
24
25
  * - An exact declared version is compared to the floor directly.
25
26
  * - A declared range that cannot reach the floor throws as unsupported. A
26
27
  * range that straddles the floor cannot be judged without an installed
@@ -35,6 +36,37 @@ export declare function throwForUnsupportedVersion(packageName: string, installe
35
36
  * before writing any incompatible config.
36
37
  */
37
38
  export declare function assertSupportedPackageVersion(tree: Tree, packageName: string, minSupportedVersion: string): void;
39
+ /**
40
+ * Resolves the version of a package a generator should target.
41
+ *
42
+ * Resolution order:
43
+ * - When the installed version satisfies the declared range, the installed
44
+ * version decides. This resolves open ranges (e.g. `>=15.0.0 <17.0.0`) to
45
+ * what is actually installed. A declaration that is not a range (`latest`,
46
+ * `file:../pkg`) resolved to the installed version, so that version decides
47
+ * as well.
48
+ * - Otherwise the declared range's floor (`semver.minVersion`, a prerelease
49
+ * when the range starts at one). This is the fresh-workspace path (nothing
50
+ * installed yet) and the case where a generator is mid-flight re-pinning
51
+ * the package: the new range no longer satisfies the still-installed
52
+ * version, so intent wins. A dist tag with nothing installed resolves to
53
+ * `latestKnownVersion`.
54
+ *
55
+ * Returns `null` when the package is not declared and no
56
+ * `latestKnownVersion` is provided; an install that is not declared in the
57
+ * workspace `package.json` (e.g. a hoisted transitive dependency) is ignored.
58
+ */
59
+ export declare function getResolvedPackageVersion(tree: Tree, packageName: string, latestKnownVersion?: string): string | null;
60
+ /**
61
+ * Returns the installed version of a package when it satisfies the declared
62
+ * range, `null` when nothing is installed or the install does not match the
63
+ * declaration. An `npm:<name>@<range>` alias is matched against its range. A
64
+ * declaration without a range, such as a dist tag (`latest`) or a `file:`,
65
+ * `link:` or `workspace:` specifier, admits whatever is installed: it has no
66
+ * version to compare. Use it to gate on what actually runs while keeping the
67
+ * declared-range fallback for the fresh-install path.
68
+ */
69
+ export declare function getSatisfyingInstalledPackageVersion(tree: Tree, packageName: string, declared: string): string | null;
38
70
  /**
39
71
  * Asserts that a package installed in the workspace is at or above the
40
72
  * plugin's supported floor. No-op when the package is not resolvable from
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.throwForUnsupportedVersion = throwForUnsupportedVersion;
4
4
  exports.assertSupportedPackageVersion = assertSupportedPackageVersion;
5
+ exports.getResolvedPackageVersion = getResolvedPackageVersion;
6
+ exports.getSatisfyingInstalledPackageVersion = getSatisfyingInstalledPackageVersion;
5
7
  exports.assertSupportedInstalledPackageVersion = assertSupportedInstalledPackageVersion;
6
8
  const devkit_exports_1 = require("nx/src/devkit-exports");
7
9
  const semver_1 = require("semver");
@@ -33,7 +35,8 @@ function throwForUnsupportedVersion(packageName, installedVersion, floor) {
33
35
  * Resolution order:
34
36
  * - When the installed version satisfies the declared range, the installed
35
37
  * version decides. This resolves open ranges (e.g. `>=4.8.4 <6.1.0`) to
36
- * what is actually installed.
38
+ * what is actually installed. An install behind a declaration that is not a
39
+ * range (e.g. `file:../pkg`) decides as well.
37
40
  * - An exact declared version is compared to the floor directly.
38
41
  * - A declared range that cannot reach the floor throws as unsupported. A
39
42
  * range that straddles the floor cannot be judged without an installed
@@ -52,18 +55,13 @@ function assertSupportedPackageVersion(tree, packageName, minSupportedVersion) {
52
55
  if (!declared || (0, installed_version_1.isNonSemverDistTag)(declared)) {
53
56
  return;
54
57
  }
55
- const installed = (0, installed_version_1.getInstalledPackageVersionFromTree)(tree, packageName) ??
56
- getInstalledPackageVersionFromProcess(tree, packageName);
58
+ const installed = getSatisfyingInstalledPackageVersion(tree, packageName, declared);
57
59
  if (installed) {
58
- // An installed prerelease can match the declared range in either form:
59
- // raw (a same-tuple prerelease comparator) or as its release version.
60
60
  const release = (0, semver_1.coerce)(installed)?.version ?? installed;
61
- if ((0, semver_1.satisfies)(installed, declared) || (0, semver_1.satisfies)(release, declared)) {
62
- if ((0, semver_1.lt)(release, minSupportedVersion)) {
63
- throwForUnsupportedVersion(packageName, installed, minSupportedVersion);
64
- }
65
- return;
61
+ if ((0, semver_1.lt)(release, minSupportedVersion)) {
62
+ throwForUnsupportedVersion(packageName, installed, minSupportedVersion);
66
63
  }
64
+ return;
67
65
  }
68
66
  const cleaned = (0, semver_1.clean)(declared);
69
67
  if (cleaned) {
@@ -96,6 +94,78 @@ function assertSupportedPackageVersion(tree, packageName, minSupportedVersion) {
96
94
  throwForUnsupportedVersion(packageName, declared, minSupportedVersion);
97
95
  }
98
96
  }
97
+ /**
98
+ * Resolves the version of a package a generator should target.
99
+ *
100
+ * Resolution order:
101
+ * - When the installed version satisfies the declared range, the installed
102
+ * version decides. This resolves open ranges (e.g. `>=15.0.0 <17.0.0`) to
103
+ * what is actually installed. A declaration that is not a range (`latest`,
104
+ * `file:../pkg`) resolved to the installed version, so that version decides
105
+ * as well.
106
+ * - Otherwise the declared range's floor (`semver.minVersion`, a prerelease
107
+ * when the range starts at one). This is the fresh-workspace path (nothing
108
+ * installed yet) and the case where a generator is mid-flight re-pinning
109
+ * the package: the new range no longer satisfies the still-installed
110
+ * version, so intent wins. A dist tag with nothing installed resolves to
111
+ * `latestKnownVersion`.
112
+ *
113
+ * Returns `null` when the package is not declared and no
114
+ * `latestKnownVersion` is provided; an install that is not declared in the
115
+ * workspace `package.json` (e.g. a hoisted transitive dependency) is ignored.
116
+ */
117
+ function getResolvedPackageVersion(tree, packageName, latestKnownVersion) {
118
+ const declared = (0, package_json_1.getDependencyVersionFromPackageJson)(tree, packageName);
119
+ if (declared) {
120
+ const installed = getSatisfyingInstalledPackageVersion(tree, packageName, declared);
121
+ if (installed) {
122
+ return installed;
123
+ }
124
+ // `minVersion` reads the whole range, so `<16 >=15.8.0` floors at 15.8.0.
125
+ // It is null for a range nothing satisfies.
126
+ const floor = (0, semver_1.validRange)(declared) ? (0, semver_1.minVersion)(declared)?.version : null;
127
+ if (floor) {
128
+ return floor;
129
+ }
130
+ }
131
+ return (0, installed_version_1.getDeclaredPackageVersion)(tree, packageName, latestKnownVersion);
132
+ }
133
+ /**
134
+ * Returns the installed version of a package when it satisfies the declared
135
+ * range, `null` when nothing is installed or the install does not match the
136
+ * declaration. An `npm:<name>@<range>` alias is matched against its range. A
137
+ * declaration without a range, such as a dist tag (`latest`) or a `file:`,
138
+ * `link:` or `workspace:` specifier, admits whatever is installed: it has no
139
+ * version to compare. Use it to gate on what actually runs while keeping the
140
+ * declared-range fallback for the fresh-install path.
141
+ */
142
+ function getSatisfyingInstalledPackageVersion(tree, packageName, declared) {
143
+ const installed = (0, installed_version_1.getInstalledPackageVersionFromTree)(tree, packageName) ??
144
+ getInstalledPackageVersionFromProcess(tree, packageName);
145
+ if (!installed) {
146
+ return null;
147
+ }
148
+ const range = getNpmAliasRange(declared) ?? declared;
149
+ if (!(0, semver_1.validRange)(range)) {
150
+ return installed;
151
+ }
152
+ // An installed prerelease can match the declared range in either form:
153
+ // raw (a same-tuple prerelease comparator) or as its release version.
154
+ const release = (0, semver_1.coerce)(installed)?.version ?? installed;
155
+ return (0, semver_1.satisfies)(installed, range) || (0, semver_1.satisfies)(release, range)
156
+ ? installed
157
+ : null;
158
+ }
159
+ // The range follows the last `@`. In `npm:@scope/pkg` that `@` starts the
160
+ // scope, so there is no range.
161
+ function getNpmAliasRange(declared) {
162
+ const prefix = 'npm:';
163
+ if (!declared.startsWith(prefix)) {
164
+ return null;
165
+ }
166
+ const at = declared.lastIndexOf('@');
167
+ return at > prefix.length ? declared.slice(at + 1) : null;
168
+ }
99
169
  /**
100
170
  * Module-resolution fallback for installs without a `node_modules` layout
101
171
  * (e.g. Yarn PnP). Only valid when the tree is the running process's
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/devkit",
3
- "version": "23.3.0-beta.0",
3
+ "version": "23.3.0-beta.1",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "files": [
@@ -67,7 +67,7 @@
67
67
  },
68
68
  "devDependencies": {
69
69
  "jest": "30.3.0",
70
- "nx": "23.3.0-beta.0"
70
+ "nx": "23.3.0-beta.1"
71
71
  },
72
72
  "peerDependencies": {
73
73
  "nx": ">= 22 <= 24 || ^23.0.0-0"