nx 19.1.0-beta.0 → 19.1.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +2 -1
- package/bin/init-local.js +1 -1
- package/package.json +18 -15
- package/schemas/nx-schema.json +1 -1
- package/src/adapter/ngcli-adapter.js +6 -3
- package/src/command-line/format/format.js +47 -25
- package/src/command-line/init/implementation/angular/legacy-angular-versions.js +2 -1
- package/src/command-line/init/implementation/angular/standalone-workspace.js +0 -2
- package/src/command-line/init/implementation/react/index.js +1 -0
- package/src/command-line/migrate/migrate.js +16 -6
- package/src/command-line/release/utils/github.js +1 -1
- package/src/command-line/release/utils/shared.js +5 -3
- package/src/command-line/run/executor-utils.js +5 -0
- package/src/config/misc-interfaces.d.ts +2 -1
- package/src/config/workspace-json-project-json.d.ts +1 -0
- package/src/core/graph/main.js +1 -1
- package/src/daemon/server/server.js +1 -1
- package/src/generators/tree.d.ts +0 -1
- package/src/generators/utils/json.js +2 -1
- package/src/plugins/js/index.js +7 -2
- package/src/plugins/js/lock-file/lock-file.js +31 -1
- package/src/plugins/js/lock-file/npm-parser.js +10 -1
- package/src/plugins/js/lock-file/utils/pnpm-normalizer.js +3 -3
- package/src/plugins/target-defaults/target-defaults-plugin.d.ts +31 -0
- package/src/plugins/target-defaults/target-defaults-plugin.js +9 -0
- package/src/utils/ab-testing.js +5 -0
- package/src/utils/fileutils.d.ts +0 -1
- package/src/utils/find-matching-projects.js +1 -13
- package/src/utils/json.js +1 -1
- package/src/utils/package-json.d.ts +1 -1
- package/src/utils/package-json.js +8 -2
- package/src/utils/package-manager.d.ts +3 -3
- package/src/utils/package-manager.js +61 -18
- package/src/utils/plugins/plugin-capabilities.js +24 -1
@@ -198,7 +198,7 @@ const handleWorkspaceChanges = async (err, changeEvents) => {
|
|
198
198
|
});
|
199
199
|
return;
|
200
200
|
}
|
201
|
-
if (err
|
201
|
+
if (err) {
|
202
202
|
let error = typeof err === 'string' ? new Error(err) : err;
|
203
203
|
logger_1.serverLogger.watcherLog('Unexpected workspace watcher error', error.message);
|
204
204
|
console.error(error);
|
package/src/generators/tree.d.ts
CHANGED
@@ -30,7 +30,8 @@ exports.readJson = readJson;
|
|
30
30
|
* @param options Optional JSON Serialize Options
|
31
31
|
*/
|
32
32
|
function writeJson(tree, path, value, options) {
|
33
|
-
|
33
|
+
const serialized = (0, json_1.serializeJson)(value, options);
|
34
|
+
tree.write(path, `${serialized}\n`);
|
34
35
|
}
|
35
36
|
exports.writeJson = writeJson;
|
36
37
|
/**
|
package/src/plugins/js/index.js
CHANGED
@@ -14,6 +14,7 @@ const file_hasher_1 = require("../../hasher/file-hasher");
|
|
14
14
|
const package_manager_1 = require("../../utils/package-manager");
|
15
15
|
const workspace_root_1 = require("../../utils/workspace-root");
|
16
16
|
const versions_1 = require("../../utils/versions");
|
17
|
+
const child_process_1 = require("child_process");
|
17
18
|
exports.name = 'nx/js/dependencies-and-lockfile';
|
18
19
|
let parsedLockFile = {};
|
19
20
|
exports.createNodes = [
|
@@ -30,7 +31,9 @@ exports.createNodes = [
|
|
30
31
|
return {};
|
31
32
|
}
|
32
33
|
const lockFilePath = (0, path_1.join)(workspace_root_1.workspaceRoot, lockFile);
|
33
|
-
const lockFileContents =
|
34
|
+
const lockFileContents = packageManager !== 'bun'
|
35
|
+
? (0, fs_1.readFileSync)(lockFilePath).toString()
|
36
|
+
: (0, child_process_1.execSync)(`bun ${lockFilePath}`).toString();
|
34
37
|
const lockFileHash = getLockFileHash(lockFileContents);
|
35
38
|
if (!lockFileNeedsReprocessing(lockFileHash)) {
|
36
39
|
const nodes = readCachedParsedLockFile().externalNodes;
|
@@ -55,7 +58,9 @@ const createDependencies = (_, ctx) => {
|
|
55
58
|
(0, lock_file_1.lockFileExists)(packageManager) &&
|
56
59
|
parsedLockFile.externalNodes) {
|
57
60
|
const lockFilePath = (0, path_1.join)(workspace_root_1.workspaceRoot, (0, lock_file_1.getLockFileName)(packageManager));
|
58
|
-
const lockFileContents =
|
61
|
+
const lockFileContents = packageManager !== 'bun'
|
62
|
+
? (0, fs_1.readFileSync)(lockFilePath).toString()
|
63
|
+
: (0, child_process_1.execSync)(`bun ${lockFilePath}`).toString();
|
59
64
|
const lockFileHash = getLockFileHash(lockFileContents);
|
60
65
|
if (!lockFileNeedsReprocessing(lockFileHash)) {
|
61
66
|
lockfileDependencies = readCachedParsedLockFile().dependencies ?? [];
|
@@ -19,10 +19,17 @@ const fileutils_1 = require("../../../utils/fileutils");
|
|
19
19
|
const YARN_LOCK_FILE = 'yarn.lock';
|
20
20
|
const NPM_LOCK_FILE = 'package-lock.json';
|
21
21
|
const PNPM_LOCK_FILE = 'pnpm-lock.yaml';
|
22
|
-
|
22
|
+
const BUN_LOCK_FILE = 'bun.lockb';
|
23
|
+
exports.LOCKFILES = [
|
24
|
+
YARN_LOCK_FILE,
|
25
|
+
NPM_LOCK_FILE,
|
26
|
+
PNPM_LOCK_FILE,
|
27
|
+
BUN_LOCK_FILE,
|
28
|
+
];
|
23
29
|
const YARN_LOCK_PATH = (0, path_1.join)(workspace_root_1.workspaceRoot, YARN_LOCK_FILE);
|
24
30
|
const NPM_LOCK_PATH = (0, path_1.join)(workspace_root_1.workspaceRoot, NPM_LOCK_FILE);
|
25
31
|
const PNPM_LOCK_PATH = (0, path_1.join)(workspace_root_1.workspaceRoot, PNPM_LOCK_FILE);
|
32
|
+
const BUN_LOCK_PATH = (0, path_1.join)(workspace_root_1.workspaceRoot, BUN_LOCK_FILE);
|
26
33
|
/**
|
27
34
|
* Parses lock file and maps dependencies and metadata to {@link LockFileGraph}
|
28
35
|
*/
|
@@ -38,6 +45,11 @@ function getLockFileNodes(packageManager, contents, lockFileHash, context) {
|
|
38
45
|
if (packageManager === 'npm') {
|
39
46
|
return (0, npm_parser_1.getNpmLockfileNodes)(contents, lockFileHash);
|
40
47
|
}
|
48
|
+
if (packageManager === 'bun') {
|
49
|
+
// bun uses yarn v1 for the file format
|
50
|
+
const packageJson = (0, fileutils_1.readJsonFile)('package.json');
|
51
|
+
return (0, yarn_parser_1.getYarnLockfileNodes)(contents, lockFileHash, packageJson);
|
52
|
+
}
|
41
53
|
}
|
42
54
|
catch (e) {
|
43
55
|
if (!isPostInstallProcess()) {
|
@@ -65,6 +77,10 @@ function getLockFileDependencies(packageManager, contents, lockFileHash, context
|
|
65
77
|
if (packageManager === 'npm') {
|
66
78
|
return (0, npm_parser_1.getNpmLockfileDependencies)(contents, lockFileHash, context);
|
67
79
|
}
|
80
|
+
if (packageManager === 'bun') {
|
81
|
+
// bun uses yarn v1 for the file format
|
82
|
+
return (0, yarn_parser_1.getYarnLockfileDependencies)(contents, lockFileHash, context);
|
83
|
+
}
|
68
84
|
}
|
69
85
|
catch (e) {
|
70
86
|
if (!isPostInstallProcess()) {
|
@@ -88,6 +104,9 @@ function lockFileExists(packageManager) {
|
|
88
104
|
if (packageManager === 'npm') {
|
89
105
|
return (0, fs_1.existsSync)(NPM_LOCK_PATH);
|
90
106
|
}
|
107
|
+
if (packageManager === 'bun') {
|
108
|
+
return (0, fs_1.existsSync)(BUN_LOCK_PATH);
|
109
|
+
}
|
91
110
|
throw new Error(`Unknown package manager ${packageManager} or lock file missing`);
|
92
111
|
}
|
93
112
|
exports.lockFileExists = lockFileExists;
|
@@ -106,6 +125,9 @@ function getLockFileName(packageManager) {
|
|
106
125
|
if (packageManager === 'npm') {
|
107
126
|
return NPM_LOCK_FILE;
|
108
127
|
}
|
128
|
+
if (packageManager === 'bun') {
|
129
|
+
return BUN_LOCK_FILE;
|
130
|
+
}
|
109
131
|
throw new Error(`Unknown package manager: ${packageManager}`);
|
110
132
|
}
|
111
133
|
exports.getLockFileName = getLockFileName;
|
@@ -119,6 +141,9 @@ function getLockFilePath(packageManager) {
|
|
119
141
|
if (packageManager === 'npm') {
|
120
142
|
return NPM_LOCK_PATH;
|
121
143
|
}
|
144
|
+
if (packageManager === 'bun') {
|
145
|
+
return BUN_LOCK_PATH;
|
146
|
+
}
|
122
147
|
throw new Error(`Unknown package manager: ${packageManager}`);
|
123
148
|
}
|
124
149
|
/**
|
@@ -145,6 +170,11 @@ function createLockFile(packageJson, graph, packageManager = (0, package_manager
|
|
145
170
|
const prunedGraph = (0, project_graph_pruning_1.pruneProjectGraph)(graph, packageJson);
|
146
171
|
return (0, npm_parser_1.stringifyNpmLockfile)(prunedGraph, content, normalizedPackageJson);
|
147
172
|
}
|
173
|
+
if (packageManager === 'bun') {
|
174
|
+
output_1.output.log({
|
175
|
+
title: "Unable to create bun lock files. Run bun install it's just as quick",
|
176
|
+
});
|
177
|
+
}
|
148
178
|
}
|
149
179
|
catch (e) {
|
150
180
|
if (!isPostInstallProcess()) {
|
@@ -175,7 +175,16 @@ function findTarget(sourcePath, keyMap, targetName, versionRange) {
|
|
175
175
|
const searchPath = `${sourcePath}node_modules/${targetName}`;
|
176
176
|
if (keyMap.has(searchPath)) {
|
177
177
|
const child = keyMap.get(searchPath);
|
178
|
-
if
|
178
|
+
// if the version is alias to another package we need to parse the versions to compare
|
179
|
+
if (child.data.version.startsWith('npm:') &&
|
180
|
+
versionRange.startsWith('npm:')) {
|
181
|
+
const nodeVersion = child.data.version.slice(child.data.version.indexOf('@', 5) + 1);
|
182
|
+
const depVersion = versionRange.slice(versionRange.indexOf('@', 5) + 1);
|
183
|
+
if (nodeVersion === depVersion || (0, semver_1.satisfies)(nodeVersion, depVersion)) {
|
184
|
+
return child;
|
185
|
+
}
|
186
|
+
}
|
187
|
+
else if (child.data.version === versionRange ||
|
179
188
|
(0, semver_1.satisfies)(child.data.version, versionRange)) {
|
180
189
|
return child;
|
181
190
|
}
|
@@ -16,7 +16,7 @@ function loadPnpmHoistedDepsDefinition() {
|
|
16
16
|
const fullPath = `${workspace_root_1.workspaceRoot}/node_modules/.modules.yaml`;
|
17
17
|
if ((0, fs_1.existsSync)(fullPath)) {
|
18
18
|
const content = (0, fs_1.readFileSync)(fullPath, 'utf-8');
|
19
|
-
const { load } = require('
|
19
|
+
const { load } = require('js-yaml');
|
20
20
|
return load(content)?.hoistedDependencies ?? {};
|
21
21
|
}
|
22
22
|
else {
|
@@ -32,7 +32,7 @@ exports.loadPnpmHoistedDepsDefinition = loadPnpmHoistedDepsDefinition;
|
|
32
32
|
* https://github.com/pnpm/pnpm/blob/af3e5559d377870d4c3d303429b3ed1a4e64fedc/lockfile/lockfile-file/src/read.ts#L91
|
33
33
|
*/
|
34
34
|
function parseAndNormalizePnpmLockfile(content) {
|
35
|
-
const { load } = require('
|
35
|
+
const { load } = require('js-yaml');
|
36
36
|
const lockFileData = load(content);
|
37
37
|
return revertFromInlineSpecifiersFormatIfNecessary(convertFromLockfileFileMutable(lockFileData));
|
38
38
|
}
|
@@ -77,7 +77,7 @@ function stringifyToPnpmYaml(lockfile) {
|
|
77
77
|
const adaptedLockfile = isLockfileV6
|
78
78
|
? convertToInlineSpecifiersFormat(lockfile)
|
79
79
|
: lockfile;
|
80
|
-
const { dump } = require('
|
80
|
+
const { dump } = require('js-yaml');
|
81
81
|
return dump(sortLockfileKeys(normalizeLockfile(adaptedLockfile, isLockfileV6)), LOCKFILE_YAML_FORMAT);
|
82
82
|
}
|
83
83
|
exports.stringifyToPnpmYaml = stringifyToPnpmYaml;
|
@@ -13,6 +13,11 @@ export default TargetDefaultsPlugin;
|
|
13
13
|
*/
|
14
14
|
export declare function getTargetInfo(target: string, projectJsonTargets: Record<string, TargetConfiguration>, packageJsonTargets: Record<string, TargetConfiguration>): {
|
15
15
|
command: string;
|
16
|
+
metadata: {
|
17
|
+
[x: string]: any;
|
18
|
+
description?: string;
|
19
|
+
technologies?: string[];
|
20
|
+
};
|
16
21
|
executor?: undefined;
|
17
22
|
options?: undefined;
|
18
23
|
} | {
|
@@ -22,6 +27,11 @@ export declare function getTargetInfo(target: string, projectJsonTargets: Record
|
|
22
27
|
commands?: undefined;
|
23
28
|
script?: undefined;
|
24
29
|
};
|
30
|
+
metadata: {
|
31
|
+
[x: string]: any;
|
32
|
+
description?: string;
|
33
|
+
technologies?: string[];
|
34
|
+
};
|
25
35
|
command?: undefined;
|
26
36
|
} | {
|
27
37
|
executor: string;
|
@@ -30,9 +40,19 @@ export declare function getTargetInfo(target: string, projectJsonTargets: Record
|
|
30
40
|
command?: undefined;
|
31
41
|
script?: undefined;
|
32
42
|
};
|
43
|
+
metadata: {
|
44
|
+
[x: string]: any;
|
45
|
+
description?: string;
|
46
|
+
technologies?: string[];
|
47
|
+
};
|
33
48
|
command?: undefined;
|
34
49
|
} | {
|
35
50
|
executor: string;
|
51
|
+
metadata: {
|
52
|
+
[x: string]: any;
|
53
|
+
description?: string;
|
54
|
+
technologies?: string[];
|
55
|
+
};
|
36
56
|
command?: undefined;
|
37
57
|
options?: undefined;
|
38
58
|
} | {
|
@@ -42,9 +62,20 @@ export declare function getTargetInfo(target: string, projectJsonTargets: Record
|
|
42
62
|
command?: undefined;
|
43
63
|
commands?: undefined;
|
44
64
|
};
|
65
|
+
metadata: {
|
66
|
+
[x: string]: any;
|
67
|
+
description?: string;
|
68
|
+
technologies?: string[];
|
69
|
+
};
|
45
70
|
command?: undefined;
|
71
|
+
} | {
|
72
|
+
executor: string;
|
73
|
+
command?: undefined;
|
74
|
+
metadata?: undefined;
|
75
|
+
options?: undefined;
|
46
76
|
} | {
|
47
77
|
command?: undefined;
|
78
|
+
metadata?: undefined;
|
48
79
|
executor?: undefined;
|
49
80
|
options?: undefined;
|
50
81
|
};
|
@@ -111,9 +111,14 @@ function getTargetInfo(target, projectJsonTargets, packageJsonTargets) {
|
|
111
111
|
...packageJsonTarget?.options,
|
112
112
|
...projectJsonTarget?.options,
|
113
113
|
};
|
114
|
+
const metadata = {
|
115
|
+
...packageJsonTarget?.metadata,
|
116
|
+
...projectJsonTarget?.metadata,
|
117
|
+
};
|
114
118
|
if (projectJsonTarget?.command) {
|
115
119
|
return {
|
116
120
|
command: projectJsonTarget?.command,
|
121
|
+
metadata,
|
117
122
|
};
|
118
123
|
}
|
119
124
|
if (executor === 'nx:run-commands') {
|
@@ -123,6 +128,7 @@ function getTargetInfo(target, projectJsonTargets, packageJsonTargets) {
|
|
123
128
|
options: {
|
124
129
|
command: targetOptions?.command,
|
125
130
|
},
|
131
|
+
metadata,
|
126
132
|
};
|
127
133
|
}
|
128
134
|
else if (targetOptions?.commands) {
|
@@ -131,10 +137,12 @@ function getTargetInfo(target, projectJsonTargets, packageJsonTargets) {
|
|
131
137
|
options: {
|
132
138
|
commands: targetOptions.commands,
|
133
139
|
},
|
140
|
+
metadata,
|
134
141
|
};
|
135
142
|
}
|
136
143
|
return {
|
137
144
|
executor: 'nx:run-commands',
|
145
|
+
metadata,
|
138
146
|
};
|
139
147
|
}
|
140
148
|
if (executor === 'nx:run-script') {
|
@@ -143,6 +151,7 @@ function getTargetInfo(target, projectJsonTargets, packageJsonTargets) {
|
|
143
151
|
options: {
|
144
152
|
script: targetOptions?.script ?? target,
|
145
153
|
},
|
154
|
+
metadata,
|
146
155
|
};
|
147
156
|
}
|
148
157
|
if (executor) {
|
package/src/utils/ab-testing.js
CHANGED
@@ -90,6 +90,11 @@ async function recordStat(opts) {
|
|
90
90
|
exports.recordStat = recordStat;
|
91
91
|
function shouldRecordStats() {
|
92
92
|
const pmc = (0, package_manager_1.getPackageManagerCommand)();
|
93
|
+
if (!pmc.getRegistryUrl) {
|
94
|
+
// Fallback on true as Package management doesn't support reading config for registry.
|
95
|
+
// currently Bun doesn't support fetching config settings https://github.com/oven-sh/bun/issues/7140
|
96
|
+
return true;
|
97
|
+
}
|
93
98
|
try {
|
94
99
|
const stdout = (0, node_child_process_1.execSync)(pmc.getRegistryUrl, { encoding: 'utf-8' });
|
95
100
|
const url = new URL(stdout.trim());
|
package/src/utils/fileutils.d.ts
CHANGED
@@ -22,15 +22,6 @@ function findMatchingProjects(patterns = [], projects) {
|
|
22
22
|
}
|
23
23
|
const projectNames = Object.keys(projects);
|
24
24
|
const matchedProjects = new Set();
|
25
|
-
// If the first pattern is an exclude pattern,
|
26
|
-
// we add a wildcard pattern at the first to select
|
27
|
-
// all projects, except the ones that match the exclude pattern.
|
28
|
-
// e.g. ['!tag:someTag', 'project2'] will match all projects except
|
29
|
-
// the ones with the tag 'someTag', and also match the project 'project2',
|
30
|
-
// regardless of its tags.
|
31
|
-
if (isExcludePattern(patterns[0])) {
|
32
|
-
patterns.unshift('*');
|
33
|
-
}
|
34
25
|
for (const stringPattern of patterns) {
|
35
26
|
if (!stringPattern.length) {
|
36
27
|
continue;
|
@@ -148,11 +139,8 @@ function addMatchingProjectsByTag(projectNames, projects, pattern, matchedProjec
|
|
148
139
|
}
|
149
140
|
}
|
150
141
|
}
|
151
|
-
function isExcludePattern(pattern) {
|
152
|
-
return pattern.startsWith('!');
|
153
|
-
}
|
154
142
|
function parseStringPattern(pattern, projects) {
|
155
|
-
const isExclude =
|
143
|
+
const isExclude = pattern.startsWith('!');
|
156
144
|
// Support for things like: `!{type}:value`
|
157
145
|
if (isExclude) {
|
158
146
|
pattern = pattern.substring(1);
|
package/src/utils/json.js
CHANGED
@@ -57,6 +57,6 @@ function formatParseError(input, parseError) {
|
|
57
57
|
* @returns the formatted JSON representation of the object
|
58
58
|
*/
|
59
59
|
function serializeJson(input, options) {
|
60
|
-
return JSON.stringify(input, null, options?.spaces ?? 2)
|
60
|
+
return JSON.stringify(input, null, options?.spaces ?? 2);
|
61
61
|
}
|
62
62
|
exports.serializeJson = serializeJson;
|
@@ -65,7 +65,7 @@ export declare function normalizePackageGroup(packageGroup: PackageGroup): Array
|
|
65
65
|
export declare function readNxMigrateConfig(json: Partial<PackageJson>): NxMigrationsConfiguration & {
|
66
66
|
packageGroup?: ArrayPackageGroup;
|
67
67
|
};
|
68
|
-
export declare function buildTargetFromScript(script: string): TargetConfiguration;
|
68
|
+
export declare function buildTargetFromScript(script: string, scripts?: Record<string, string>): TargetConfiguration;
|
69
69
|
export declare function readTargetsFromPackageJson(packageJson: PackageJson): Record<string, TargetConfiguration<any>>;
|
70
70
|
/**
|
71
71
|
* Uses `require.resolve` to read the package.json for a module.
|
@@ -6,6 +6,7 @@ const path_1 = require("path");
|
|
6
6
|
const project_configuration_utils_1 = require("../project-graph/utils/project-configuration-utils");
|
7
7
|
const fileutils_1 = require("./fileutils");
|
8
8
|
const installation_directory_1 = require("./installation-directory");
|
9
|
+
const package_manager_1 = require("./package-manager");
|
9
10
|
function normalizePackageGroup(packageGroup) {
|
10
11
|
return Array.isArray(packageGroup)
|
11
12
|
? packageGroup.map((x) => typeof x === 'string' ? { package: x, version: '*' } : x)
|
@@ -38,12 +39,17 @@ function readNxMigrateConfig(json) {
|
|
38
39
|
};
|
39
40
|
}
|
40
41
|
exports.readNxMigrateConfig = readNxMigrateConfig;
|
41
|
-
function buildTargetFromScript(script) {
|
42
|
+
function buildTargetFromScript(script, scripts = {}) {
|
43
|
+
const packageManagerCommand = (0, package_manager_1.getPackageManagerCommand)();
|
42
44
|
return {
|
43
45
|
executor: 'nx:run-script',
|
44
46
|
options: {
|
45
47
|
script,
|
46
48
|
},
|
49
|
+
metadata: {
|
50
|
+
scriptContent: scripts[script],
|
51
|
+
runCommand: packageManagerCommand.run(script),
|
52
|
+
},
|
47
53
|
};
|
48
54
|
}
|
49
55
|
exports.buildTargetFromScript = buildTargetFromScript;
|
@@ -53,7 +59,7 @@ function readTargetsFromPackageJson(packageJson) {
|
|
53
59
|
const includedScripts = nx?.includedScripts || Object.keys(scripts ?? {});
|
54
60
|
//
|
55
61
|
for (const script of includedScripts) {
|
56
|
-
res[script] = buildTargetFromScript(script);
|
62
|
+
res[script] = buildTargetFromScript(script, scripts);
|
57
63
|
}
|
58
64
|
for (const targetName in nx?.targets) {
|
59
65
|
res[targetName] = (0, project_configuration_utils_1.mergeTargetConfigurations)(nx?.targets[targetName], res[targetName]);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
export type PackageManager = 'yarn' | 'pnpm' | 'npm';
|
1
|
+
export type PackageManager = 'yarn' | 'pnpm' | 'npm' | 'bun';
|
2
2
|
export interface PackageManagerCommands {
|
3
3
|
preInstall?: string;
|
4
4
|
install: string;
|
@@ -10,8 +10,8 @@ export interface PackageManagerCommands {
|
|
10
10
|
exec: string;
|
11
11
|
dlx: string;
|
12
12
|
list: string;
|
13
|
-
run: (script: string, args
|
14
|
-
getRegistryUrl
|
13
|
+
run: (script: string, args?: string) => string;
|
14
|
+
getRegistryUrl?: string;
|
15
15
|
}
|
16
16
|
/**
|
17
17
|
* Detects which package manager is used in the workspace based on the lock file.
|
@@ -20,11 +20,13 @@ const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
20
20
|
function detectPackageManager(dir = '') {
|
21
21
|
const nxJson = (0, configuration_1.readNxJson)();
|
22
22
|
return (nxJson.cli?.packageManager ??
|
23
|
-
((0, fs_1.existsSync)((0, path_1.join)(dir, '
|
24
|
-
? '
|
25
|
-
: (0, fs_1.existsSync)((0, path_1.join)(dir, '
|
26
|
-
? '
|
27
|
-
: '
|
23
|
+
((0, fs_1.existsSync)((0, path_1.join)(dir, 'bun.lockb'))
|
24
|
+
? 'bun'
|
25
|
+
: (0, fs_1.existsSync)((0, path_1.join)(dir, 'yarn.lock'))
|
26
|
+
? 'yarn'
|
27
|
+
: (0, fs_1.existsSync)((0, path_1.join)(dir, 'pnpm-lock.yaml'))
|
28
|
+
? 'pnpm'
|
29
|
+
: 'npm'));
|
28
30
|
}
|
29
31
|
exports.detectPackageManager = detectPackageManager;
|
30
32
|
/**
|
@@ -74,7 +76,7 @@ function getPackageManagerCommand(packageManager = detectPackageManager(), root
|
|
74
76
|
rm: 'yarn remove',
|
75
77
|
exec: 'yarn',
|
76
78
|
dlx: useBerry ? 'yarn dlx' : 'yarn',
|
77
|
-
run: (script, args) => `yarn ${script} ${args}`,
|
79
|
+
run: (script, args) => `yarn ${script}${args ? ` ${args}` : ''}`,
|
78
80
|
list: useBerry ? 'yarn info --name-only' : 'yarn list',
|
79
81
|
getRegistryUrl: useBerry
|
80
82
|
? 'yarn config get npmRegistryServer'
|
@@ -95,9 +97,11 @@ function getPackageManagerCommand(packageManager = detectPackageManager(), root
|
|
95
97
|
rm: 'pnpm rm',
|
96
98
|
exec: modernPnpm ? 'pnpm exec' : 'pnpx',
|
97
99
|
dlx: modernPnpm ? 'pnpm dlx' : 'pnpx',
|
98
|
-
run: (script, args) =>
|
99
|
-
?
|
100
|
-
|
100
|
+
run: (script, args) => `pnpm run ${script}${args
|
101
|
+
? includeDoubleDashBeforeArgs
|
102
|
+
? ' -- ' + args
|
103
|
+
: ` ${args}`
|
104
|
+
: ''}`,
|
101
105
|
list: 'pnpm ls --depth 100',
|
102
106
|
getRegistryUrl: 'pnpm config get registry',
|
103
107
|
};
|
@@ -114,11 +118,26 @@ function getPackageManagerCommand(packageManager = detectPackageManager(), root
|
|
114
118
|
rm: 'npm rm',
|
115
119
|
exec: 'npx',
|
116
120
|
dlx: 'npx',
|
117
|
-
run: (script, args) => `npm run ${script} --
|
121
|
+
run: (script, args) => `npm run ${script}${args ? ' -- ' + args : ''}`,
|
118
122
|
list: 'npm ls',
|
119
123
|
getRegistryUrl: 'npm config get registry',
|
120
124
|
};
|
121
125
|
},
|
126
|
+
bun: () => {
|
127
|
+
// bun doesn't current support programatically reading config https://github.com/oven-sh/bun/issues/7140
|
128
|
+
return {
|
129
|
+
install: 'bun install',
|
130
|
+
ciInstall: 'bun install --no-cache',
|
131
|
+
updateLockFile: 'bun install --frozen-lockfile',
|
132
|
+
add: 'bun install',
|
133
|
+
addDev: 'bun install -D',
|
134
|
+
rm: 'bun rm',
|
135
|
+
exec: 'bun',
|
136
|
+
dlx: 'bunx',
|
137
|
+
run: (script, args) => `bun run ${script} -- ${args}`,
|
138
|
+
list: 'bun pm ls',
|
139
|
+
};
|
140
|
+
},
|
122
141
|
};
|
123
142
|
return commands[packageManager]();
|
124
143
|
}
|
@@ -193,7 +212,12 @@ function modifyYarnRcToFitNewDirectory(contents) {
|
|
193
212
|
}
|
194
213
|
exports.modifyYarnRcToFitNewDirectory = modifyYarnRcToFitNewDirectory;
|
195
214
|
function copyPackageManagerConfigurationFiles(root, destination) {
|
196
|
-
for (const packageManagerConfigFile of [
|
215
|
+
for (const packageManagerConfigFile of [
|
216
|
+
'.npmrc',
|
217
|
+
'.yarnrc',
|
218
|
+
'.yarnrc.yml',
|
219
|
+
'bunfig.toml',
|
220
|
+
]) {
|
197
221
|
// f is an absolute path, including the {workspaceRoot}.
|
198
222
|
const f = findFileInPackageJsonDirectory(packageManagerConfigFile, root);
|
199
223
|
if (f) {
|
@@ -216,6 +240,10 @@ function copyPackageManagerConfigurationFiles(root, destination) {
|
|
216
240
|
(0, fs_1.writeFileSync)(destinationPath, updated);
|
217
241
|
break;
|
218
242
|
}
|
243
|
+
case 'bunfig.toml': {
|
244
|
+
(0, fs_1.copyFileSync)(f, destinationPath);
|
245
|
+
break;
|
246
|
+
}
|
219
247
|
}
|
220
248
|
}
|
221
249
|
}
|
@@ -254,11 +282,20 @@ async function resolvePackageVersionUsingRegistry(packageName, version) {
|
|
254
282
|
if (!result) {
|
255
283
|
throw new Error(`Unable to resolve version ${packageName}@${version}.`);
|
256
284
|
}
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
285
|
+
const lines = result.split('\n');
|
286
|
+
if (lines.length === 1) {
|
287
|
+
return lines[0];
|
288
|
+
}
|
289
|
+
/**
|
290
|
+
* The output contains multiple lines ordered by release date, so the last
|
291
|
+
* version might not be the last one in the list. We need to sort it. Each
|
292
|
+
* line looks like:
|
293
|
+
*
|
294
|
+
* <package>@<version> '<version>'
|
295
|
+
*/
|
296
|
+
const resolvedVersion = lines
|
297
|
+
.map((line) => line.split(' ')[1])
|
298
|
+
.sort()
|
262
299
|
.pop()
|
263
300
|
.replace(/'/g, '');
|
264
301
|
return resolvedVersion;
|
@@ -288,12 +325,16 @@ async function resolvePackageVersionUsingInstallation(packageName, version) {
|
|
288
325
|
exports.resolvePackageVersionUsingInstallation = resolvePackageVersionUsingInstallation;
|
289
326
|
async function packageRegistryView(pkg, version, args) {
|
290
327
|
let pm = detectPackageManager();
|
291
|
-
if (pm === 'yarn') {
|
328
|
+
if (pm === 'yarn' || pm === 'bun') {
|
292
329
|
/**
|
293
330
|
* yarn has `yarn info` but it behaves differently than (p)npm,
|
294
331
|
* which makes it's usage unreliable
|
295
332
|
*
|
296
333
|
* @see https://github.com/nrwl/nx/pull/9667#discussion_r842553994
|
334
|
+
*
|
335
|
+
* Bun has a pm ls function but it only relates to its lockfile
|
336
|
+
* and acts differently from all other package managers
|
337
|
+
* from Jarred: "it probably would be bun pm view <package-name>"
|
297
338
|
*/
|
298
339
|
pm = 'npm';
|
299
340
|
}
|
@@ -303,13 +344,15 @@ async function packageRegistryView(pkg, version, args) {
|
|
303
344
|
exports.packageRegistryView = packageRegistryView;
|
304
345
|
async function packageRegistryPack(cwd, pkg, version) {
|
305
346
|
let pm = detectPackageManager();
|
306
|
-
if (pm === 'yarn') {
|
347
|
+
if (pm === 'yarn' || pm === 'bun') {
|
307
348
|
/**
|
308
349
|
* `(p)npm pack` will download a tarball of the specified version,
|
309
350
|
* whereas `yarn` pack creates a tarball of the active workspace, so it
|
310
351
|
* does not work for getting the content of a library.
|
311
352
|
*
|
312
353
|
* @see https://github.com/nrwl/nx/pull/9667#discussion_r842553994
|
354
|
+
*
|
355
|
+
* bun doesn't currently support pack
|
313
356
|
*/
|
314
357
|
pm = 'npm';
|
315
358
|
}
|
@@ -114,7 +114,7 @@ async function listPluginCapabilities(pluginName, projects) {
|
|
114
114
|
if (hasBuilders) {
|
115
115
|
bodyLines.push(chalk.bold(chalk.green('EXECUTORS/BUILDERS')));
|
116
116
|
bodyLines.push('');
|
117
|
-
bodyLines.push(...Object.keys(plugin.executors).map((name) => `${chalk.bold(name)} : ${plugin.executors[name]
|
117
|
+
bodyLines.push(...Object.keys(plugin.executors).map((name) => `${chalk.bold(name)} : ${resolveExecutorDescription(plugin.executors[name], projects)}`));
|
118
118
|
}
|
119
119
|
if (hasProjectGraphExtension) {
|
120
120
|
bodyLines.push(`✔️ Project Graph Extension`);
|
@@ -128,3 +128,26 @@ async function listPluginCapabilities(pluginName, projects) {
|
|
128
128
|
});
|
129
129
|
}
|
130
130
|
exports.listPluginCapabilities = listPluginCapabilities;
|
131
|
+
function resolveExecutorDescription(executorJsonEntry, projects) {
|
132
|
+
try {
|
133
|
+
if (typeof executorJsonEntry === 'string') {
|
134
|
+
// it points to another executor, resolve it
|
135
|
+
const [pkgName, executor] = executorJsonEntry.split(':');
|
136
|
+
const collection = loadExecutorsCollection(workspace_root_1.workspaceRoot, pkgName, projects);
|
137
|
+
return resolveExecutorDescription(collection[executor], projects);
|
138
|
+
}
|
139
|
+
return executorJsonEntry.description;
|
140
|
+
}
|
141
|
+
catch {
|
142
|
+
return 'No description available';
|
143
|
+
}
|
144
|
+
}
|
145
|
+
function loadExecutorsCollection(workspaceRoot, pluginName, projects) {
|
146
|
+
const { json: packageJson, path: packageJsonPath } = (0, plugins_1.readPluginPackageJson)(pluginName, projects, (0, installation_directory_1.getNxRequirePaths)(workspaceRoot));
|
147
|
+
return {
|
148
|
+
...tryGetCollection(packageJsonPath, packageJson.builders, 'builders'),
|
149
|
+
...tryGetCollection(packageJsonPath, packageJson.executors, 'builders'),
|
150
|
+
...tryGetCollection(packageJsonPath, packageJson.builders, 'executors'),
|
151
|
+
...tryGetCollection(packageJsonPath, packageJson.executors, 'executors'),
|
152
|
+
};
|
153
|
+
}
|