nx 23.0.0 → 23.0.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/README.md +1 -2
- package/dist/release/changelog-renderer/index.d.ts +1 -0
- package/dist/release/changelog-renderer/index.js +27 -12
- package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +3 -2
- package/dist/src/command-line/migrate/migrate.js +2 -1
- package/dist/src/command-line/migrate/resolve-package-version.js +3 -25
- package/dist/src/command-line/migrate/update-filters.js +2 -1
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +14 -4
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/plugins/js/project-graph/affected/tsconfig-json-changes.js +1 -1
- package/dist/src/utils/ab-testing.d.ts +9 -0
- package/dist/src/utils/ab-testing.js +18 -4
- package/dist/src/utils/catalog/index.d.ts +7 -0
- package/dist/src/utils/catalog/index.js +31 -0
- package/dist/src/utils/terminal-link.d.ts +16 -0
- package/dist/src/utils/terminal-link.js +87 -0
- package/package.json +14 -14
package/README.md
CHANGED
|
@@ -7,13 +7,12 @@
|
|
|
7
7
|
|
|
8
8
|
<div style="text-align: center;">
|
|
9
9
|
|
|
10
|
-
[](https://circleci.com/gh/nrwl/nx)
|
|
11
10
|
[]()
|
|
12
11
|
[](https://www.npmjs.com/package/nx)
|
|
13
12
|
[]()
|
|
14
13
|
[](http://commitizen.github.io/cz-cli/)
|
|
15
|
-
[](https://gitter.im/nrwl-nx/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
16
14
|
[](https://go.nx.dev/community)
|
|
15
|
+
[](https://nx.dev/docs/features/ci-features/sandboxing)
|
|
17
16
|
|
|
18
17
|
</div>
|
|
19
18
|
|
|
@@ -105,5 +105,6 @@ export default class DefaultChangelogRenderer {
|
|
|
105
105
|
protected groupChangesByType(): Record<string, ChangelogChange[]>;
|
|
106
106
|
protected groupChangesByScope(changes: ChangelogChange[]): Record<string, ChangelogChange[]>;
|
|
107
107
|
protected extractBreakingChangeExplanation(message: string): string | null;
|
|
108
|
+
private isBreakingChangeBoundary;
|
|
108
109
|
protected formatName(name?: string): string;
|
|
109
110
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const semver_1 = require("semver");
|
|
4
|
+
// Stripped from breaking change explanations (e.g. bot/session markers).
|
|
5
|
+
const HtmlCommentRegex = /<!--[\s\S]*?-->/g;
|
|
4
6
|
class DefaultChangelogRenderer {
|
|
5
7
|
/**
|
|
6
8
|
* A ChangelogRenderer class takes in the determined changes and other relevant metadata
|
|
@@ -342,20 +344,33 @@ class DefaultChangelogRenderer {
|
|
|
342
344
|
return null;
|
|
343
345
|
}
|
|
344
346
|
const startOfBreakingChange = startIndex + breakingChangeIdentifier.length;
|
|
345
|
-
//
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
347
|
+
// A squash-merged PR body can trail the note with template sections,
|
|
348
|
+
// trailers, and git metadata. Strip comments (they can appear anywhere),
|
|
349
|
+
// then keep lines until the first boundary.
|
|
350
|
+
const lines = message
|
|
351
|
+
.slice(startOfBreakingChange)
|
|
352
|
+
.replace(HtmlCommentRegex, '')
|
|
353
|
+
.split('\n');
|
|
354
|
+
// The rest of the "BREAKING CHANGE:" line is always kept; scan from the next.
|
|
355
|
+
const explanationLines = [lines[0]];
|
|
356
|
+
for (let i = 1; i < lines.length; i++) {
|
|
357
|
+
if (this.isBreakingChangeBoundary(lines[i])) {
|
|
358
|
+
break;
|
|
356
359
|
}
|
|
360
|
+
explanationLines.push(lines[i]);
|
|
357
361
|
}
|
|
358
|
-
return
|
|
362
|
+
return explanationLines.join('\n').trim();
|
|
363
|
+
}
|
|
364
|
+
isBreakingChangeBoundary(line) {
|
|
365
|
+
const trimmed = line.trim();
|
|
366
|
+
return (
|
|
367
|
+
// Markdown heading (e.g. "## Related issues")
|
|
368
|
+
/^#{1,6}\s/.test(trimmed) ||
|
|
369
|
+
// Horizontal rule / separator
|
|
370
|
+
/^-{3,}$/.test(trimmed) ||
|
|
371
|
+
/^Co-authored-by:/i.test(trimmed) ||
|
|
372
|
+
// Git metadata delimiter following the body
|
|
373
|
+
trimmed === '"');
|
|
359
374
|
}
|
|
360
375
|
formatName(name = '') {
|
|
361
376
|
return name
|
|
@@ -80,9 +80,10 @@ function buildScopeRules(mode) {
|
|
|
80
80
|
return [
|
|
81
81
|
`<scope_rules>`,
|
|
82
82
|
`- Apply only the changes the migration prompt asks for.`,
|
|
83
|
-
`- Do not refactor
|
|
83
|
+
`- Do not refactor or update dependencies beyond what the migration prompt directs, and do not reformat files you did not change.`,
|
|
84
|
+
`- After applying your changes and before writing the handoff, format the files you created or modified so they match the workspace's style. If the workspace uses Prettier, run \`nx format:write\`, which formats your uncommitted changes; if it has no formatter configured, skip this.`,
|
|
84
85
|
`- Do not modify files outside the workspace root.`,
|
|
85
|
-
`- Do not run other \`nx\` commands that mutate workspace state (\`nx migrate\`, \`nx reset\`, \`nx run-many\`, generators, etc.). Read-only inspection (\`nx show\`, \`nx graph --file\`, reading files) is fine.`,
|
|
86
|
+
`- Do not run other \`nx\` commands that mutate workspace state (\`nx migrate\`, \`nx reset\`, \`nx run-many\`, generators, etc.), except \`nx format:write\` to format the files you changed. Read-only inspection (\`nx show\`, \`nx graph --file\`, reading files) is fine.`,
|
|
86
87
|
`- If the migration instructions are unclear, internally inconsistent, or conflict with the current workspace state, ask the user for direction (see the handoff contract). Do not guess.`,
|
|
87
88
|
`</scope_rules>`,
|
|
88
89
|
].join('\n');
|
|
@@ -1413,7 +1413,8 @@ async function generateMigrationsJsonAndUpdatePackageJson(root, opts, fetch) {
|
|
|
1413
1413
|
// the user already has. Drop those before writing; nx migrate is
|
|
1414
1414
|
// forward-only, never a downgrade.
|
|
1415
1415
|
phase = 'package_updates';
|
|
1416
|
-
|
|
1416
|
+
// Resolve catalog: specifiers first so the filter compares real versions.
|
|
1417
|
+
const writableUpdates = (0, update_filters_1.filterDowngradedUpdates)(packageUpdates, (0, catalog_1.resolveCatalogSpecifiers)(originalPackageJson), installedPackageVersions);
|
|
1417
1418
|
const wrotePackageJson = await updatePackageJson(root, writableUpdates);
|
|
1418
1419
|
const wroteNxJsonInstallation = await updateInstallationDetails(root, writableUpdates);
|
|
1419
1420
|
const promptMigrationFiles = (0, prompt_files_1.writePromptMigrationFiles)(root, migrations, promptContents ?? {}, packageUpdates[walkedTargetPackage].version);
|
|
@@ -137,9 +137,9 @@ async function resolveWithPolicy(packageName, version, policy, applySideEffects)
|
|
|
137
137
|
if (applySideEffects && outcome.version !== outcome.unconstrained) {
|
|
138
138
|
reportChangedOutcome(packageName, spec, outcome.version, outcome.unconstrained, policy);
|
|
139
139
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
140
|
+
// An immature loose pick is returned as-is. nx does not write the
|
|
141
|
+
// minimumReleaseAgeExclude entry here: migrate does not replace the install,
|
|
142
|
+
// so the real `pnpm install` (>=11.1.3) auto-writes it itself.
|
|
143
143
|
return outcome.version;
|
|
144
144
|
}
|
|
145
145
|
catch (e) {
|
|
@@ -171,28 +171,6 @@ function reportChangedOutcome(packageName, spec, picked, unconstrained, policy)
|
|
|
171
171
|
title: `Resolved ${packageName}@${picked} instead of ${unconstrained}: ${policy.sourceDescription}.`,
|
|
172
172
|
});
|
|
173
173
|
}
|
|
174
|
-
// pnpm v11 loose installs an immature version; >=11.1.3 also records it as an
|
|
175
|
-
// exclude in pnpm-workspace.yaml. Mirror that so a later real install agrees.
|
|
176
|
-
function handleImmaturePick(packageName, version, policy) {
|
|
177
|
-
if (policy.behavior.packageManager !== 'pnpm' ||
|
|
178
|
-
!policy.behavior.writesExcludes) {
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
const added = (0, pnpm_exclude_writer_1.appendMinimumReleaseAgeExcludes)(workspace_root_1.workspaceRoot, [
|
|
182
|
-
`${packageName}@${version}`,
|
|
183
|
-
]);
|
|
184
|
-
// Already present (e.g. a prior pick or a pre-existing entry): nothing written,
|
|
185
|
-
// so do not claim we added it.
|
|
186
|
-
if (added.length === 0) {
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
output_1.output.log({
|
|
190
|
-
title: `Added ${packageName}@${version} to minimumReleaseAgeExclude in pnpm-workspace.yaml.`,
|
|
191
|
-
bodyLines: [
|
|
192
|
-
`It is within the ${policy.sourceDescription} window; this mirrors what pnpm would write at install time.`,
|
|
193
|
-
],
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
174
|
async function handleViolation(packageName, error, policy) {
|
|
197
175
|
const isPnpmStrict = policy.behavior.packageManager === 'pnpm' &&
|
|
198
176
|
policy.behavior.strict &&
|
|
@@ -35,7 +35,8 @@ function filterDowngradedUpdates(packageUpdates, packageJson, getInstalledVersio
|
|
|
35
35
|
if (!specifier) {
|
|
36
36
|
continue;
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
// Skip specifiers that aren't semver ranges (workspace:/npm:/git/file).
|
|
39
|
+
const floor = (0, semver_1.validRange)(specifier) ? (0, semver_1.minVersion)(specifier) : null;
|
|
39
40
|
if (floor && (0, semver_1.lt)(floor.version, resolvedNorm)) {
|
|
40
41
|
result[name] = update;
|
|
41
42
|
}
|
|
@@ -181,7 +181,7 @@ function sleep(ms) {
|
|
|
181
181
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
182
182
|
}
|
|
183
183
|
async function connectExistingRepoToNxCloudPrompt(command = 'init', key = 'setupNxCloud') {
|
|
184
|
-
const res = await nxCloudPrompt(key);
|
|
184
|
+
const res = await nxCloudPrompt(key, utmMediumForCommand(command));
|
|
185
185
|
await (0, ab_testing_1.recordStat)({
|
|
186
186
|
command,
|
|
187
187
|
nxVersion: versions_1.nxVersion,
|
|
@@ -200,7 +200,7 @@ async function connectExistingRepoToNxCloudPrompt(command = 'init', key = 'setup
|
|
|
200
200
|
return res;
|
|
201
201
|
}
|
|
202
202
|
async function connectToNxCloudWithPrompt(command) {
|
|
203
|
-
const setNxCloud = await nxCloudPrompt('setupNxCloud');
|
|
203
|
+
const setNxCloud = await nxCloudPrompt('setupNxCloud', utmMediumForCommand(command));
|
|
204
204
|
let useCloud = false;
|
|
205
205
|
if (setNxCloud === 'yes') {
|
|
206
206
|
useCloud = await connectToNxCloudCommand({ generateToken: false }, command);
|
|
@@ -229,7 +229,17 @@ async function connectToNxCloudWithPrompt(command) {
|
|
|
229
229
|
},
|
|
230
230
|
});
|
|
231
231
|
}
|
|
232
|
-
|
|
232
|
+
function utmMediumForCommand(command) {
|
|
233
|
+
switch (command) {
|
|
234
|
+
case 'migrate':
|
|
235
|
+
return 'nx-migrate';
|
|
236
|
+
case 'view-logs':
|
|
237
|
+
return 'nx-connect';
|
|
238
|
+
default:
|
|
239
|
+
return 'nx-init';
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
async function nxCloudPrompt(key, utmMedium) {
|
|
233
243
|
const { message, choices, initial, footer, hint } = ab_testing_1.messages.getPrompt(key);
|
|
234
244
|
const promptConfig = {
|
|
235
245
|
name: 'NxCloud',
|
|
@@ -239,7 +249,7 @@ async function nxCloudPrompt(key) {
|
|
|
239
249
|
initial,
|
|
240
250
|
}; // meeroslav: types in enquirer are not up to date
|
|
241
251
|
if (footer) {
|
|
242
|
-
promptConfig.footer = () => pc.dim(footer);
|
|
252
|
+
promptConfig.footer = () => pc.dim(`${footer} ${(0, ab_testing_1.nxCloudHyperlink)(utmMedium)}`);
|
|
243
253
|
}
|
|
244
254
|
if (hint) {
|
|
245
255
|
promptConfig.hint = () => pc.dim(hint);
|
|
Binary file
|
|
Binary file
|
|
@@ -45,7 +45,7 @@ function getProjectsAffectedByPaths(change, nodes) {
|
|
|
45
45
|
const normalizedPath = path && path.startsWith('./') ? path.substring(2) : path;
|
|
46
46
|
const r = project.data.root;
|
|
47
47
|
const root = r && r.endsWith('/') ? r.substring(0, r.length - 1) : r;
|
|
48
|
-
if ((normalizedPath && root && normalizedPath.startsWith(root)) ||
|
|
48
|
+
if ((normalizedPath && root && normalizedPath.startsWith(`${root}/`)) ||
|
|
49
49
|
normalizedPath == root) {
|
|
50
50
|
result.push(project.name);
|
|
51
51
|
}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
export declare const NX_CLOUD_URL = "https://nx.dev/nx-cloud";
|
|
2
|
+
/**
|
|
3
|
+
* Clickable Nx Cloud marketing link for cloud prompt footers. The visible text
|
|
4
|
+
* stays the clean `NX_CLOUD_URL` while clicks carry UTM attribution; terminals
|
|
5
|
+
* without OSC 8 support just render the bare URL (CLOUD-4642). The medium is
|
|
6
|
+
* per-command because `nx init` and `nx migrate` share a footer but report
|
|
7
|
+
* different mediums.
|
|
8
|
+
*/
|
|
9
|
+
export declare function nxCloudHyperlink(utmMedium: string): string;
|
|
1
10
|
/**
|
|
2
11
|
* Meta payload types for recordStat telemetry (matches CNW format).
|
|
3
12
|
*/
|
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.messages = exports.PromptMessages = void 0;
|
|
3
|
+
exports.messages = exports.PromptMessages = exports.NX_CLOUD_URL = void 0;
|
|
4
|
+
exports.nxCloudHyperlink = nxCloudHyperlink;
|
|
4
5
|
exports.recordStat = recordStat;
|
|
5
6
|
const tslib_1 = require("tslib");
|
|
6
7
|
const node_child_process_1 = require("node:child_process");
|
|
7
8
|
const is_ci_1 = require("./is-ci");
|
|
8
9
|
const package_manager_1 = require("./package-manager");
|
|
9
10
|
const get_cloud_options_1 = require("../nx-cloud/utilities/get-cloud-options");
|
|
11
|
+
const terminal_link_1 = require("./terminal-link");
|
|
10
12
|
const pc = tslib_1.__importStar(require("picocolors"));
|
|
13
|
+
exports.NX_CLOUD_URL = 'https://nx.dev/nx-cloud';
|
|
14
|
+
/**
|
|
15
|
+
* Clickable Nx Cloud marketing link for cloud prompt footers. The visible text
|
|
16
|
+
* stays the clean `NX_CLOUD_URL` while clicks carry UTM attribution; terminals
|
|
17
|
+
* without OSC 8 support just render the bare URL (CLOUD-4642). The medium is
|
|
18
|
+
* per-command because `nx init` and `nx migrate` share a footer but report
|
|
19
|
+
* different mediums.
|
|
20
|
+
*/
|
|
21
|
+
function nxCloudHyperlink(utmMedium) {
|
|
22
|
+
const tracked = `${exports.NX_CLOUD_URL}?utm_source=nx-cli&utm_medium=${utmMedium}`;
|
|
23
|
+
return (0, terminal_link_1.terminalLink)(exports.NX_CLOUD_URL, tracked);
|
|
24
|
+
}
|
|
11
25
|
const messageOptions = {
|
|
12
26
|
setupNxCloud: [
|
|
13
27
|
{
|
|
@@ -19,7 +33,7 @@ const messageOptions = {
|
|
|
19
33
|
{ value: 'skip', name: 'Skip for now' },
|
|
20
34
|
{ value: 'never', name: pc.dim("No, don't ask again") },
|
|
21
35
|
],
|
|
22
|
-
footer: '\nFree for small teams. Remote caching and task distribution. 2-minute setup:
|
|
36
|
+
footer: '\nFree for small teams. Remote caching and task distribution. 2-minute setup:',
|
|
23
37
|
},
|
|
24
38
|
{
|
|
25
39
|
code: 'cloud-self-healing-remote-cache',
|
|
@@ -30,7 +44,7 @@ const messageOptions = {
|
|
|
30
44
|
{ value: 'skip', name: 'Skip for now' },
|
|
31
45
|
{ value: 'never', name: pc.dim("No, don't ask again") },
|
|
32
46
|
],
|
|
33
|
-
footer: '\nLearn about it at
|
|
47
|
+
footer: '\nLearn about it at',
|
|
34
48
|
hint: `\n(it's free and can be disabled any time)`,
|
|
35
49
|
},
|
|
36
50
|
],
|
|
@@ -47,7 +61,7 @@ const messageOptions = {
|
|
|
47
61
|
},
|
|
48
62
|
{ value: 'skip', name: 'No' },
|
|
49
63
|
],
|
|
50
|
-
footer: '\nRead more about Nx Cloud at
|
|
64
|
+
footer: '\nRead more about Nx Cloud at',
|
|
51
65
|
hint: `\n(it's free and can be disabled any time)`,
|
|
52
66
|
},
|
|
53
67
|
],
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Tree } from '../../generators/tree';
|
|
2
|
+
import type { PackageJson } from '../package-json';
|
|
2
3
|
import type { CatalogManager } from './manager';
|
|
3
4
|
import { getCatalogManager } from './manager-factory';
|
|
4
5
|
export { type CatalogManager, getCatalogManager };
|
|
@@ -8,6 +9,12 @@ export { type CatalogManager, getCatalogManager };
|
|
|
8
9
|
* applies). Throws when the reference cannot be resolved.
|
|
9
10
|
*/
|
|
10
11
|
export declare function resolveCatalogReferenceIfNeeded(packageName: string, version: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Resolves a package.json's `catalog:` dependency / devDependency specifiers to
|
|
14
|
+
* their declared version range. Non-catalog or unresolvable specifiers are
|
|
15
|
+
* returned unchanged.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveCatalogSpecifiers(packageJson: PackageJson | null): PackageJson | null;
|
|
11
18
|
/**
|
|
12
19
|
* Detects which packages in a package.json use catalog references
|
|
13
20
|
* Returns Map of package name -> catalog name (undefined for default catalog)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getCatalogManager = void 0;
|
|
4
4
|
exports.resolveCatalogReferenceIfNeeded = resolveCatalogReferenceIfNeeded;
|
|
5
|
+
exports.resolveCatalogSpecifiers = resolveCatalogSpecifiers;
|
|
5
6
|
exports.getCatalogDependenciesFromPackageJson = getCatalogDependenciesFromPackageJson;
|
|
6
7
|
const json_1 = require("../../generators/utils/json");
|
|
7
8
|
const workspace_root_1 = require("../workspace-root");
|
|
@@ -23,6 +24,36 @@ function resolveCatalogReferenceIfNeeded(packageName, version) {
|
|
|
23
24
|
}
|
|
24
25
|
return resolvedVersion;
|
|
25
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolves a package.json's `catalog:` dependency / devDependency specifiers to
|
|
29
|
+
* their declared version range. Non-catalog or unresolvable specifiers are
|
|
30
|
+
* returned unchanged.
|
|
31
|
+
*/
|
|
32
|
+
function resolveCatalogSpecifiers(packageJson) {
|
|
33
|
+
if (!packageJson) {
|
|
34
|
+
return packageJson;
|
|
35
|
+
}
|
|
36
|
+
const resolveSection = (section) => {
|
|
37
|
+
const resolved = {};
|
|
38
|
+
for (const [name, specifier] of Object.entries(section)) {
|
|
39
|
+
try {
|
|
40
|
+
resolved[name] = resolveCatalogReferenceIfNeeded(name, specifier);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
resolved[name] = specifier;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return resolved;
|
|
47
|
+
};
|
|
48
|
+
const result = { ...packageJson };
|
|
49
|
+
if (packageJson.dependencies) {
|
|
50
|
+
result.dependencies = resolveSection(packageJson.dependencies);
|
|
51
|
+
}
|
|
52
|
+
if (packageJson.devDependencies) {
|
|
53
|
+
result.devDependencies = resolveSection(packageJson.devDependencies);
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
26
57
|
/**
|
|
27
58
|
* Detects which packages in a package.json use catalog references
|
|
28
59
|
* Returns Map of package name -> catalog name (undefined for default catalog)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrap `text` in an OSC 8 hyperlink that points at `url`. Supported terminals
|
|
3
|
+
* render `text` as a clickable link to `url`; everywhere else `text` prints
|
|
4
|
+
* unchanged. This lets us keep tracking querystrings out of the visible output
|
|
5
|
+
* while still attaching them to the link target (CLOUD-4642).
|
|
6
|
+
*/
|
|
7
|
+
export declare function terminalLink(text: string, url: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Exported for testing. VTE reports versions as a packed integer, e.g. "5402"
|
|
10
|
+
* means 0.54.2; everything else is dot-separated.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseVersion(versionString?: string): {
|
|
13
|
+
major: number;
|
|
14
|
+
minor: number;
|
|
15
|
+
patch: number;
|
|
16
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Keep in sync with packages/create-nx-workspace/src/utils/terminal-link.ts.
|
|
3
|
+
// create-nx-workspace cannot depend on nx, so this generic OSC 8 helper is
|
|
4
|
+
// intentionally duplicated (same reasoning as output.ts / package-manager.ts).
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.terminalLink = terminalLink;
|
|
7
|
+
exports.parseVersion = parseVersion;
|
|
8
|
+
const OSC = '\u001B]';
|
|
9
|
+
const BEL = '\u0007';
|
|
10
|
+
const SEP = ';';
|
|
11
|
+
/**
|
|
12
|
+
* Wrap `text` in an OSC 8 hyperlink that points at `url`. Supported terminals
|
|
13
|
+
* render `text` as a clickable link to `url`; everywhere else `text` prints
|
|
14
|
+
* unchanged. This lets us keep tracking querystrings out of the visible output
|
|
15
|
+
* while still attaching them to the link target (CLOUD-4642).
|
|
16
|
+
*/
|
|
17
|
+
function terminalLink(text, url) {
|
|
18
|
+
if (!supportsHyperlinks()) {
|
|
19
|
+
return text;
|
|
20
|
+
}
|
|
21
|
+
return [OSC, '8', SEP, SEP, url, BEL, text, OSC, '8', SEP, SEP, BEL].join('');
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Best-effort detection of OSC 8 hyperlink support, adapted from the
|
|
25
|
+
* `supports-hyperlinks` package. Defaults to false when in doubt so we never
|
|
26
|
+
* print raw escape sequences to a terminal that can't render them.
|
|
27
|
+
*/
|
|
28
|
+
function supportsHyperlinks() {
|
|
29
|
+
const env = process.env;
|
|
30
|
+
if (env.FORCE_HYPERLINK !== undefined) {
|
|
31
|
+
return !(env.FORCE_HYPERLINK.length > 0 && parseInt(env.FORCE_HYPERLINK, 10) === 0);
|
|
32
|
+
}
|
|
33
|
+
if (!process.stdout || !process.stdout.isTTY) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
if (process.platform === 'win32') {
|
|
37
|
+
// Only Windows Terminal advertises OSC 8 support reliably.
|
|
38
|
+
return Boolean(env.WT_SESSION);
|
|
39
|
+
}
|
|
40
|
+
if (env.CI || env.TEAMCITY_VERSION) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
if (env.TERM === 'dumb') {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
if (env.TERM_PROGRAM) {
|
|
47
|
+
const version = parseVersion(env.TERM_PROGRAM_VERSION);
|
|
48
|
+
switch (env.TERM_PROGRAM) {
|
|
49
|
+
case 'iTerm.app':
|
|
50
|
+
return version.major === 3 ? version.minor >= 1 : version.major > 3;
|
|
51
|
+
case 'WezTerm':
|
|
52
|
+
return version.major >= 20200620;
|
|
53
|
+
case 'vscode':
|
|
54
|
+
return (version.major > 1 || (version.major === 1 && version.minor >= 72));
|
|
55
|
+
case 'ghostty':
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (env.VTE_VERSION) {
|
|
60
|
+
if (env.VTE_VERSION === '0.50.0') {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
const version = parseVersion(env.VTE_VERSION);
|
|
64
|
+
return version.major > 0 || version.minor >= 50;
|
|
65
|
+
}
|
|
66
|
+
if (env.TERM === 'xterm-kitty') {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
if (env.TERMINAL_EMULATOR === 'JetBrains-JediTerm') {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Exported for testing. VTE reports versions as a packed integer, e.g. "5402"
|
|
76
|
+
* means 0.54.2; everything else is dot-separated.
|
|
77
|
+
*/
|
|
78
|
+
function parseVersion(versionString = '') {
|
|
79
|
+
if (/^\d{3,4}$/.test(versionString)) {
|
|
80
|
+
const m = /(\d{1,2})(\d{2})/.exec(versionString) ?? [];
|
|
81
|
+
return { major: 0, minor: parseInt(m[1], 10), patch: parseInt(m[2], 10) };
|
|
82
|
+
}
|
|
83
|
+
const [major = 0, minor = 0, patch = 0] = (versionString ?? '')
|
|
84
|
+
.split('.')
|
|
85
|
+
.map((n) => parseInt(n, 10) || 0);
|
|
86
|
+
return { major, minor, patch };
|
|
87
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nx",
|
|
3
|
-
"version": "23.0.
|
|
3
|
+
"version": "23.0.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"figures": "3.2.0",
|
|
95
95
|
"flat": "5.0.2",
|
|
96
96
|
"follow-redirects": "1.16.0",
|
|
97
|
-
"form-data": "4.0.
|
|
97
|
+
"form-data": "4.0.6",
|
|
98
98
|
"fs-constants": "1.0.0",
|
|
99
99
|
"function-bind": "1.1.2",
|
|
100
100
|
"get-caller-file": "2.0.5",
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"has-flag": "4.0.0",
|
|
105
105
|
"has-symbols": "1.1.0",
|
|
106
106
|
"has-tostringtag": "1.0.2",
|
|
107
|
-
"hasown": "2.0.
|
|
107
|
+
"hasown": "2.0.4",
|
|
108
108
|
"ieee754": "1.2.1",
|
|
109
109
|
"ignore": "7.0.5",
|
|
110
110
|
"inherits": "2.0.4",
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"strip-bom": "3.0.0",
|
|
147
147
|
"supports-color": "7.2.0",
|
|
148
148
|
"tar-stream": "2.2.0",
|
|
149
|
-
"tmp": "0.2.
|
|
149
|
+
"tmp": "0.2.7",
|
|
150
150
|
"tsconfig-paths": "4.2.0",
|
|
151
151
|
"tslib": "2.8.1",
|
|
152
152
|
"util-deprecate": "1.0.2",
|
|
@@ -172,16 +172,16 @@
|
|
|
172
172
|
}
|
|
173
173
|
},
|
|
174
174
|
"optionalDependencies": {
|
|
175
|
-
"@nx/nx-darwin-arm64": "23.0.
|
|
176
|
-
"@nx/nx-darwin-x64": "23.0.
|
|
177
|
-
"@nx/nx-freebsd-x64": "23.0.
|
|
178
|
-
"@nx/nx-linux-arm-gnueabihf": "23.0.
|
|
179
|
-
"@nx/nx-linux-arm64-gnu": "23.0.
|
|
180
|
-
"@nx/nx-linux-arm64-musl": "23.0.
|
|
181
|
-
"@nx/nx-linux-x64-gnu": "23.0.
|
|
182
|
-
"@nx/nx-linux-x64-musl": "23.0.
|
|
183
|
-
"@nx/nx-win32-arm64-msvc": "23.0.
|
|
184
|
-
"@nx/nx-win32-x64-msvc": "23.0.
|
|
175
|
+
"@nx/nx-darwin-arm64": "23.0.1",
|
|
176
|
+
"@nx/nx-darwin-x64": "23.0.1",
|
|
177
|
+
"@nx/nx-freebsd-x64": "23.0.1",
|
|
178
|
+
"@nx/nx-linux-arm-gnueabihf": "23.0.1",
|
|
179
|
+
"@nx/nx-linux-arm64-gnu": "23.0.1",
|
|
180
|
+
"@nx/nx-linux-arm64-musl": "23.0.1",
|
|
181
|
+
"@nx/nx-linux-x64-gnu": "23.0.1",
|
|
182
|
+
"@nx/nx-linux-x64-musl": "23.0.1",
|
|
183
|
+
"@nx/nx-win32-arm64-msvc": "23.0.1",
|
|
184
|
+
"@nx/nx-win32-x64-msvc": "23.0.1"
|
|
185
185
|
},
|
|
186
186
|
"nx-migrations": {
|
|
187
187
|
"migrations": "./migrations.json",
|