@rushstack/lockfile-explorer 2.2.17 → 2.2.19
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/CHANGELOG.json +35 -0
- package/CHANGELOG.md +13 -1
- package/dist/{app.0b644e08b36979b58936.js → app.3fe86541880858baf783.js} +1 -1
- package/dist/index.html +1 -1
- package/dist/rush-themed-ui.js +2 -2
- package/lib-commonjs/cli/explorer/ExplorerCommandLineParser.js +27 -25
- package/lib-commonjs/cli/explorer/ExplorerCommandLineParser.js.map +1 -1
- package/lib-commonjs/cli/lint/LintCommandLineParser.js +7 -10
- package/lib-commonjs/cli/lint/LintCommandLineParser.js.map +1 -1
- package/lib-commonjs/cli/lint/actions/CheckAction.js +2 -2
- package/lib-commonjs/cli/lint/actions/CheckAction.js.map +1 -1
- package/lib-commonjs/cli/lint/actions/InitAction.js +2 -2
- package/lib-commonjs/cli/lint/actions/InitAction.js.map +1 -1
- package/lib-commonjs/start-explorer.js +3 -1
- package/lib-commonjs/start-explorer.js.map +1 -1
- package/lib-commonjs/start-lint.js +3 -1
- package/lib-commonjs/start-lint.js.map +1 -1
- package/lib-commonjs/utils/PackageUpdateChecker.js +120 -0
- package/lib-commonjs/utils/PackageUpdateChecker.js.map +1 -0
- package/lib-commonjs/utils/constants.js +15 -0
- package/lib-commonjs/utils/constants.js.map +1 -0
- package/lib-commonjs/utils/init.js +4 -3
- package/lib-commonjs/utils/init.js.map +1 -1
- package/lib-dts/cli/explorer/ExplorerCommandLineParser.d.ts +1 -2
- package/lib-dts/cli/explorer/ExplorerCommandLineParser.d.ts.map +1 -1
- package/lib-dts/cli/lint/LintCommandLineParser.d.ts +1 -2
- package/lib-dts/cli/lint/LintCommandLineParser.d.ts.map +1 -1
- package/lib-dts/cli/lint/actions/CheckAction.d.ts +2 -2
- package/lib-dts/cli/lint/actions/CheckAction.d.ts.map +1 -1
- package/lib-dts/cli/lint/actions/InitAction.d.ts +2 -2
- package/lib-dts/cli/lint/actions/InitAction.d.ts.map +1 -1
- package/lib-dts/utils/PackageUpdateChecker.d.ts +77 -0
- package/lib-dts/utils/PackageUpdateChecker.d.ts.map +1 -0
- package/lib-dts/utils/constants.d.ts +3 -0
- package/lib-dts/utils/constants.d.ts.map +1 -0
- package/lib-dts/utils/init.d.ts +3 -3
- package/lib-dts/utils/init.d.ts.map +1 -1
- package/lib-esm/cli/explorer/ExplorerCommandLineParser.js +29 -27
- package/lib-esm/cli/explorer/ExplorerCommandLineParser.js.map +1 -1
- package/lib-esm/cli/lint/LintCommandLineParser.js +8 -11
- package/lib-esm/cli/lint/LintCommandLineParser.js.map +1 -1
- package/lib-esm/cli/lint/actions/CheckAction.js +2 -2
- package/lib-esm/cli/lint/actions/CheckAction.js.map +1 -1
- package/lib-esm/cli/lint/actions/InitAction.js +2 -2
- package/lib-esm/cli/lint/actions/InitAction.js.map +1 -1
- package/lib-esm/start-explorer.js +3 -1
- package/lib-esm/start-explorer.js.map +1 -1
- package/lib-esm/start-lint.js +3 -1
- package/lib-esm/start-lint.js.map +1 -1
- package/lib-esm/utils/PackageUpdateChecker.js +113 -0
- package/lib-esm/utils/PackageUpdateChecker.js.map +1 -0
- package/lib-esm/utils/constants.js +9 -0
- package/lib-esm/utils/constants.js.map +1 -0
- package/lib-esm/utils/init.js +4 -3
- package/lib-esm/utils/init.js.map +1 -1
- package/package.json +8 -10
|
@@ -13,14 +13,14 @@ const rush_sdk_1 = require("@rushstack/rush-sdk");
|
|
|
13
13
|
const node_core_library_1 = require("@rushstack/node-core-library");
|
|
14
14
|
const common_1 = require("../../../constants/common");
|
|
15
15
|
class InitAction extends ts_command_line_1.CommandLineAction {
|
|
16
|
-
constructor(
|
|
16
|
+
constructor(terminal) {
|
|
17
17
|
super({
|
|
18
18
|
actionName: 'init',
|
|
19
19
|
summary: `Create a new ${common_1.LOCKFILE_LINT_JSON_FILENAME} config file`,
|
|
20
20
|
documentation: `This command initializes a new ${common_1.LOCKFILE_LINT_JSON_FILENAME} config file.` +
|
|
21
21
|
` The created template file includes source code comments that document the settings.`
|
|
22
22
|
});
|
|
23
|
-
this._terminal =
|
|
23
|
+
this._terminal = terminal;
|
|
24
24
|
}
|
|
25
25
|
async onExecuteAsync() {
|
|
26
26
|
const rushConfiguration = rush_sdk_1.RushConfiguration.tryLoadFromDefaultLocation();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InitAction.js","sourceRoot":"","sources":["../../../../src/cli/lint/actions/InitAction.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;AAE3D,0DAA6B;AAE7B,gEAA+D;AAC/D,kDAA+D;AAC/D,kDAAwD;AACxD,oEAA0D;
|
|
1
|
+
{"version":3,"file":"InitAction.js","sourceRoot":"","sources":["../../../../src/cli/lint/actions/InitAction.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;AAE3D,0DAA6B;AAE7B,gEAA+D;AAC/D,kDAA+D;AAC/D,kDAAwD;AACxD,oEAA0D;AAE1D,sDAAsG;AAEtG,MAAa,UAAW,SAAQ,mCAAiB;IAG/C,YAAmB,QAAmB;QACpC,KAAK,CAAC;YACJ,UAAU,EAAE,MAAM;YAClB,OAAO,EAAE,gBAAgB,oCAA2B,cAAc;YAClE,aAAa,EACX,kCAAkC,oCAA2B,eAAe;gBAC5E,uFAAuF;SAC1F,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAEkB,KAAK,CAAC,cAAc;QACrC,MAAM,iBAAiB,GAAkC,4BAAiB,CAAC,0BAA0B,EAAE,CAAC;QACxG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,kGAAkG,CACnG,CAAC;QACJ,CAAC;QACD,MAAM,aAAa,GAAW,mBAAI,CAAC,OAAO,CACxC,SAAS,EACT,uDAAuD,CACxD,CAAC;QACF,MAAM,cAAc,GAAW,mBAAI,CAAC,OAAO,CACzC,iBAAiB,CAAC,YAAY,EAC9B,QAAQ,EACR,qCAA4B,EAC5B,oCAA2B,CAC5B,CAAC;QAEF,IAAI,MAAM,8BAAU,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,iCAAiC,CAAC,CAAC;YAC7D,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,cAAc,GAAG,IAAI,CAAC,CAAC;YACzD,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,cAAc,CAAC,CAAC;QAC5E,MAAM,8BAAU,CAAC,aAAa,CAAC;YAC7B,UAAU,EAAE,aAAa;YACzB,eAAe,EAAE,cAAc;SAChC,CAAC,CAAC;IACL,CAAC;CACF;AA5CD,gCA4CC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport path from 'node:path';\n\nimport { CommandLineAction } from '@rushstack/ts-command-line';\nimport { Colorize, type ITerminal } from '@rushstack/terminal';\nimport { RushConfiguration } from '@rushstack/rush-sdk';\nimport { FileSystem } from '@rushstack/node-core-library';\n\nimport { LOCKFILE_EXPLORER_FOLDERNAME, LOCKFILE_LINT_JSON_FILENAME } from '../../../constants/common';\n\nexport class InitAction extends CommandLineAction {\n private readonly _terminal: ITerminal;\n\n public constructor(terminal: ITerminal) {\n super({\n actionName: 'init',\n summary: `Create a new ${LOCKFILE_LINT_JSON_FILENAME} config file`,\n documentation:\n `This command initializes a new ${LOCKFILE_LINT_JSON_FILENAME} config file.` +\n ` The created template file includes source code comments that document the settings.`\n });\n this._terminal = terminal;\n }\n\n protected override async onExecuteAsync(): Promise<void> {\n const rushConfiguration: RushConfiguration | undefined = RushConfiguration.tryLoadFromDefaultLocation();\n if (!rushConfiguration) {\n throw new Error(\n 'The \"lockfile-explorer check\" must be executed in a folder that is under a Rush workspace folder'\n );\n }\n const inputFilePath: string = path.resolve(\n __dirname,\n '../../../assets/lint-init/lockfile-lint-template.json'\n );\n const outputFilePath: string = path.resolve(\n rushConfiguration.commonFolder,\n 'config',\n LOCKFILE_EXPLORER_FOLDERNAME,\n LOCKFILE_LINT_JSON_FILENAME\n );\n\n if (await FileSystem.existsAsync(outputFilePath)) {\n this._terminal.writeError('The output file already exists:');\n this._terminal.writeLine('\\n ' + outputFilePath + '\\n');\n throw new Error('Unable to write output file');\n }\n\n this._terminal.writeLine(Colorize.green('Writing file: ') + outputFilePath);\n await FileSystem.copyFileAsync({\n sourcePath: inputFilePath,\n destinationPath: outputFilePath\n });\n }\n}\n"]}
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
3
|
// See LICENSE in the project root for license information.
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
const index_1 = require("@rushstack/terminal/lib/index");
|
|
5
6
|
const ExplorerCommandLineParser_1 = require("./cli/explorer/ExplorerCommandLineParser");
|
|
6
|
-
const
|
|
7
|
+
const terminal = new index_1.Terminal(new index_1.ConsoleTerminalProvider());
|
|
8
|
+
const parser = new ExplorerCommandLineParser_1.ExplorerCommandLineParser(terminal);
|
|
7
9
|
parser.executeAsync().catch(console.error); // CommandLineParser.executeAsync() should never reject the promise
|
|
8
10
|
//# sourceMappingURL=start-explorer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-explorer.js","sourceRoot":"","sources":["../src/start-explorer.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;AAE3D,wFAAqF;AAErF,MAAM,MAAM,GAA8B,IAAI,qDAAyB,
|
|
1
|
+
{"version":3,"file":"start-explorer.js","sourceRoot":"","sources":["../src/start-explorer.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;AAE3D,yDAAkF;AAElF,wFAAqF;AAErF,MAAM,QAAQ,GAAa,IAAI,gBAAQ,CAAC,IAAI,+BAAuB,EAAE,CAAC,CAAC;AACvE,MAAM,MAAM,GAA8B,IAAI,qDAAyB,CAAC,QAAQ,CAAC,CAAC;AAElF,MAAM,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,mEAAmE","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { ConsoleTerminalProvider, Terminal } from '@rushstack/terminal/lib/index';\n\nimport { ExplorerCommandLineParser } from './cli/explorer/ExplorerCommandLineParser';\n\nconst terminal: Terminal = new Terminal(new ConsoleTerminalProvider());\nconst parser: ExplorerCommandLineParser = new ExplorerCommandLineParser(terminal);\n\nparser.executeAsync().catch(console.error); // CommandLineParser.executeAsync() should never reject the promise\n"]}
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
3
|
// See LICENSE in the project root for license information.
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
const index_1 = require("@rushstack/terminal/lib/index");
|
|
5
6
|
const LintCommandLineParser_1 = require("./cli/lint/LintCommandLineParser");
|
|
6
|
-
const
|
|
7
|
+
const terminal = new index_1.Terminal(new index_1.ConsoleTerminalProvider());
|
|
8
|
+
const parser = new LintCommandLineParser_1.LintCommandLineParser(terminal);
|
|
7
9
|
parser.executeAsync().catch(console.error); // CommandLineParser.executeAsync() should never reject the promise
|
|
8
10
|
//# sourceMappingURL=start-lint.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-lint.js","sourceRoot":"","sources":["../src/start-lint.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;AAE3D,4EAAyE;AAEzE,MAAM,MAAM,GAA0B,IAAI,6CAAqB,
|
|
1
|
+
{"version":3,"file":"start-lint.js","sourceRoot":"","sources":["../src/start-lint.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;AAE3D,yDAAkF;AAElF,4EAAyE;AAEzE,MAAM,QAAQ,GAAa,IAAI,gBAAQ,CAAC,IAAI,+BAAuB,EAAE,CAAC,CAAC;AACvE,MAAM,MAAM,GAA0B,IAAI,6CAAqB,CAAC,QAAQ,CAAC,CAAC;AAE1E,MAAM,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,mEAAmE","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { ConsoleTerminalProvider, Terminal } from '@rushstack/terminal/lib/index';\n\nimport { LintCommandLineParser } from './cli/lint/LintCommandLineParser';\n\nconst terminal: Terminal = new Terminal(new ConsoleTerminalProvider());\nconst parser: LintCommandLineParser = new LintCommandLineParser(terminal);\n\nparser.executeAsync().catch(console.error); // CommandLineParser.executeAsync() should never reject the promise\n"]}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
|
+
// See LICENSE in the project root for license information.
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.PackageUpdateChecker = void 0;
|
|
9
|
+
const node_os_1 = require("node:os");
|
|
10
|
+
const semver_1 = __importDefault(require("semver"));
|
|
11
|
+
const node_core_library_1 = require("@rushstack/node-core-library");
|
|
12
|
+
const REGISTRY_BASE_URL = 'https://registry.npmjs.org';
|
|
13
|
+
const FETCH_TIMEOUT_MS = 5000;
|
|
14
|
+
const DEFAULT_CACHE_EXPIRY_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
15
|
+
const CACHE_VERSION = 1;
|
|
16
|
+
const CACHE_FOLDER = `${(0, node_os_1.homedir)()}/.rushstack/update-checks`;
|
|
17
|
+
async function _tryFetchLatestVersionAsync(packageName) {
|
|
18
|
+
const url = `${REGISTRY_BASE_URL}/${encodeURIComponent(packageName)}/latest`;
|
|
19
|
+
const controller = new AbortController();
|
|
20
|
+
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
21
|
+
try {
|
|
22
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const { version } = (await response.json());
|
|
27
|
+
return typeof version === 'string' ? version : undefined;
|
|
28
|
+
}
|
|
29
|
+
catch (_a) {
|
|
30
|
+
// Network errors, timeouts, and parse failures are all silent.
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
clearTimeout(timeout);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function _readCacheAsync(filePath) {
|
|
38
|
+
try {
|
|
39
|
+
const data = await node_core_library_1.JsonFile.loadAsync(filePath);
|
|
40
|
+
const { cacheVersion, ...rest } = data;
|
|
41
|
+
if (cacheVersion === CACHE_VERSION) {
|
|
42
|
+
return rest;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (_a) {
|
|
46
|
+
// Ignore
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function _writeCacheAsync(filePath, cache) {
|
|
50
|
+
try {
|
|
51
|
+
const cacheData = {
|
|
52
|
+
cacheVersion: CACHE_VERSION,
|
|
53
|
+
checkedAt: Date.now(),
|
|
54
|
+
...cache
|
|
55
|
+
};
|
|
56
|
+
await node_core_library_1.JsonFile.saveAsync(cacheData, filePath, {
|
|
57
|
+
ensureFolderExists: true
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch (_a) {
|
|
61
|
+
// Cache write failures are silent — a stale or missing cache just means
|
|
62
|
+
// we'll re-fetch on the next invocation.
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Checks npm for a newer version of a package and caches the result locally so that
|
|
67
|
+
* the registry is not queried on every invocation.
|
|
68
|
+
*
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
class PackageUpdateChecker {
|
|
72
|
+
constructor(options) {
|
|
73
|
+
const { packageName, currentVersion, skip = false, forceCheck = false, cacheExpiryMs = DEFAULT_CACHE_EXPIRY_MS } = options;
|
|
74
|
+
this._packageName = packageName;
|
|
75
|
+
this._currentVersion = currentVersion;
|
|
76
|
+
this._skip = skip;
|
|
77
|
+
this._forceCheck = forceCheck;
|
|
78
|
+
this._cacheExpiryMs = cacheExpiryMs;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Performs the update check and returns the result, or `undefined` if the check
|
|
82
|
+
* was skipped or the registry could not be reached.
|
|
83
|
+
*/
|
|
84
|
+
async tryGetUpdateAsync() {
|
|
85
|
+
if (this._skip) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
const cacheFilePath = this._getCacheFilePath();
|
|
89
|
+
let latestVersion;
|
|
90
|
+
if (!this._forceCheck) {
|
|
91
|
+
const cached = await _readCacheAsync(cacheFilePath);
|
|
92
|
+
if (cached !== undefined) {
|
|
93
|
+
const { checkedAt, latestVersion: latestVersionFromCache } = cached;
|
|
94
|
+
const ageMs = Date.now() - checkedAt;
|
|
95
|
+
if (ageMs < this._cacheExpiryMs) {
|
|
96
|
+
latestVersion = latestVersionFromCache;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (latestVersion === undefined) {
|
|
101
|
+
// Cache is missing or stale — fetch from the registry.
|
|
102
|
+
latestVersion = await _tryFetchLatestVersionAsync(this._packageName);
|
|
103
|
+
if (latestVersion === undefined) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
await _writeCacheAsync(cacheFilePath, { latestVersion });
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
latestVersion,
|
|
110
|
+
isOutdated: semver_1.default.gt(latestVersion, this._currentVersion)
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
_getCacheFilePath() {
|
|
114
|
+
// Replace characters that are unsafe in file names (e.g. the "/" in scoped package names).
|
|
115
|
+
const sanitizedName = this._packageName.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
116
|
+
return `${CACHE_FOLDER}/${sanitizedName}.json`;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.PackageUpdateChecker = PackageUpdateChecker;
|
|
120
|
+
//# sourceMappingURL=PackageUpdateChecker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PackageUpdateChecker.js","sourceRoot":"","sources":["../../src/utils/PackageUpdateChecker.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { homedir } from 'node:os';\n\nimport semver from 'semver';\n\nimport { type IPackageJson, JsonFile } from '@rushstack/node-core-library';\n\n/**\n * TODO: If we end up expecting to use this elsewhere, we should move this to\n * either its own package or into `@rushstack/node-core-library`.\n */\n\n/**\n * Options for {@link _PackageUpdateChecker}.\n *\n * @internal\n */\nexport interface IPackageUpdateCheckerOptions {\n /**\n * The npm package name to check for updates.\n */\n packageName: string;\n\n /**\n * The currently installed version.\n */\n currentVersion: string;\n\n /**\n * If `true`, skip the update check entirely.\n * Use this to suppress checks in CI environments or non-interactive sessions.\n *\n * @defaultValue false\n */\n skip?: boolean;\n\n /**\n * If `true`, bypass the cache and always fetch from the registry.\n * Useful in debug/verbose modes where you want an immediate, authoritative answer.\n *\n * @defaultValue false\n */\n forceCheck?: boolean;\n\n /**\n * How long (in milliseconds) to consider a cached registry response fresh\n * before re-fetching.\n *\n * @defaultValue 86400000 (24 hours)\n */\n cacheExpiryMs?: number;\n}\n\n/**\n * The result of an update check.\n *\n * @internal\n */\nexport interface IPackageUpdateResult {\n /**\n * The latest version available on the registry.\n */\n latestVersion: string;\n\n /**\n * `true` if {@link _IPackageUpdateResult.latestVersion} is strictly newer than\n * the {@link _IPackageUpdateCheckerOptions.currentVersion} that was passed to the checker.\n */\n isOutdated: boolean;\n}\n\ninterface IUpdateCheckCache {\n checkedAt: number;\n latestVersion: string;\n}\n\ninterface IUpdateCheckCacheOnDisk extends IUpdateCheckCache {\n cacheVersion: typeof CACHE_VERSION;\n}\n\nconst REGISTRY_BASE_URL: 'https://registry.npmjs.org' = 'https://registry.npmjs.org';\nconst FETCH_TIMEOUT_MS: 5000 = 5000;\nconst DEFAULT_CACHE_EXPIRY_MS: number = 24 * 60 * 60 * 1000; // 24 hours\nconst CACHE_VERSION: 1 = 1;\nconst CACHE_FOLDER: string = `${homedir()}/.rushstack/update-checks`;\n\nasync function _tryFetchLatestVersionAsync(packageName: string): Promise<string | undefined> {\n const url: string = `${REGISTRY_BASE_URL}/${encodeURIComponent(packageName)}/latest`;\n const controller: AbortController = new AbortController();\n const timeout: NodeJS.Timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n try {\n const response: Response = await fetch(url, { signal: controller.signal });\n if (!response.ok) {\n return undefined;\n }\n\n const { version } = (await response.json()) as IPackageJson;\n return typeof version === 'string' ? version : undefined;\n } catch {\n // Network errors, timeouts, and parse failures are all silent.\n return undefined;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nasync function _readCacheAsync(filePath: string): Promise<IUpdateCheckCache | undefined> {\n try {\n const data: IUpdateCheckCacheOnDisk = await JsonFile.loadAsync(filePath);\n const { cacheVersion, ...rest } = data;\n if (cacheVersion === CACHE_VERSION) {\n return rest;\n }\n } catch {\n // Ignore\n }\n}\n\nasync function _writeCacheAsync(\n filePath: string,\n cache: Omit<IUpdateCheckCache, 'checkedAt'>\n): Promise<void> {\n try {\n const cacheData: IUpdateCheckCacheOnDisk = {\n cacheVersion: CACHE_VERSION,\n checkedAt: Date.now(),\n ...cache\n };\n await JsonFile.saveAsync(cacheData, filePath, {\n ensureFolderExists: true\n });\n } catch {\n // Cache write failures are silent — a stale or missing cache just means\n // we'll re-fetch on the next invocation.\n }\n}\n\n/**\n * Checks npm for a newer version of a package and caches the result locally so that\n * the registry is not queried on every invocation.\n *\n * @internal\n */\nexport class PackageUpdateChecker {\n private readonly _packageName: string;\n private readonly _currentVersion: string;\n private readonly _skip: boolean;\n private readonly _forceCheck: boolean;\n private readonly _cacheExpiryMs: number;\n\n public constructor(options: IPackageUpdateCheckerOptions) {\n const {\n packageName,\n currentVersion,\n skip = false,\n forceCheck = false,\n cacheExpiryMs = DEFAULT_CACHE_EXPIRY_MS\n } = options;\n this._packageName = packageName;\n this._currentVersion = currentVersion;\n this._skip = skip;\n this._forceCheck = forceCheck;\n this._cacheExpiryMs = cacheExpiryMs;\n }\n\n /**\n * Performs the update check and returns the result, or `undefined` if the check\n * was skipped or the registry could not be reached.\n */\n public async tryGetUpdateAsync(): Promise<IPackageUpdateResult | undefined> {\n if (this._skip) {\n return undefined;\n }\n\n const cacheFilePath: string = this._getCacheFilePath();\n\n let latestVersion: string | undefined;\n if (!this._forceCheck) {\n const cached: IUpdateCheckCache | undefined = await _readCacheAsync(cacheFilePath);\n if (cached !== undefined) {\n const { checkedAt, latestVersion: latestVersionFromCache } = cached;\n const ageMs: number = Date.now() - checkedAt;\n if (ageMs < this._cacheExpiryMs) {\n latestVersion = latestVersionFromCache;\n }\n }\n }\n\n if (latestVersion === undefined) {\n // Cache is missing or stale — fetch from the registry.\n latestVersion = await _tryFetchLatestVersionAsync(this._packageName);\n if (latestVersion === undefined) {\n return undefined;\n }\n\n await _writeCacheAsync(cacheFilePath, { latestVersion });\n }\n\n return {\n latestVersion,\n isOutdated: semver.gt(latestVersion, this._currentVersion)\n };\n }\n\n private _getCacheFilePath(): string {\n // Replace characters that are unsafe in file names (e.g. the \"/\" in scoped package names).\n const sanitizedName: string = this._packageName.replace(/[^a-zA-Z0-9._-]/g, '_');\n return `${CACHE_FOLDER}/${sanitizedName}.json`;\n }\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
|
+
// See LICENSE in the project root for license information.
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.LFX_PACKAGE_ROOT = exports.LFX_PACKAGE_NAME = exports.LFX_VERSION = void 0;
|
|
9
|
+
const node_core_library_1 = require("@rushstack/node-core-library");
|
|
10
|
+
const package_json_1 = __importDefault(require("../../package.json"));
|
|
11
|
+
exports.LFX_VERSION = package_json_1.default.version, exports.LFX_PACKAGE_NAME = package_json_1.default.name;
|
|
12
|
+
let _lfxPackageRoot = node_core_library_1.Path.convertToSlashes(__dirname);
|
|
13
|
+
_lfxPackageRoot = _lfxPackageRoot.slice(0, _lfxPackageRoot.lastIndexOf('/', _lfxPackageRoot.lastIndexOf('/') - 1));
|
|
14
|
+
exports.LFX_PACKAGE_ROOT = node_core_library_1.Path.convertToPlatformDefault(_lfxPackageRoot);
|
|
15
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;AAE3D,oEAAoD;AAEpD,sEAA6D;AAErC,mBAAW,GAA6B,sBAA2B,UAAhD,wBAAgB,GAAK,sBAA2B,MAAC;AAE5F,IAAI,eAAe,GAAW,wBAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;AAC/D,eAAe,GAAG,eAAe,CAAC,KAAK,CACrC,CAAC,EACD,eAAe,CAAC,WAAW,CAAC,GAAG,EAAE,eAAe,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CACvE,CAAC;AACW,QAAA,gBAAgB,GAAW,wBAAI,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { Path } from '@rushstack/node-core-library';\n\nimport lockfileExplorerPackageJson from '../../package.json';\n\nexport const { version: LFX_VERSION, name: LFX_PACKAGE_NAME } = lockfileExplorerPackageJson;\n\nlet _lfxPackageRoot: string = Path.convertToSlashes(__dirname);\n_lfxPackageRoot = _lfxPackageRoot.slice(\n 0,\n _lfxPackageRoot.lastIndexOf('/', _lfxPackageRoot.lastIndexOf('/') - 1)\n);\nexport const LFX_PACKAGE_ROOT: string = Path.convertToPlatformDefault(_lfxPackageRoot);\n"]}
|
|
@@ -45,8 +45,9 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
45
45
|
const node_core_library_1 = require("@rushstack/node-core-library");
|
|
46
46
|
const RushConfiguration_1 = require("@microsoft/rush-lib/lib/api/RushConfiguration");
|
|
47
47
|
const lockfilePath = __importStar(require("../graph/lockfilePath"));
|
|
48
|
+
const constants_1 = require("./constants");
|
|
48
49
|
const init = (options) => {
|
|
49
|
-
const {
|
|
50
|
+
const { appVersion, debugMode, subspaceName } = options;
|
|
50
51
|
const currentWorkingDirectory = node_path_1.default.resolve(process.cwd());
|
|
51
52
|
let appState;
|
|
52
53
|
let currentFolder = node_core_library_1.Path.convertToSlashes(currentWorkingDirectory);
|
|
@@ -69,7 +70,7 @@ const init = (options) => {
|
|
|
69
70
|
currentWorkingDirectory,
|
|
70
71
|
appVersion,
|
|
71
72
|
debugMode,
|
|
72
|
-
lockfileExplorerProjectRoot,
|
|
73
|
+
lockfileExplorerProjectRoot: constants_1.LFX_PACKAGE_ROOT,
|
|
73
74
|
pnpmLockfileLocation: pnpmLockfileAbsolutePath,
|
|
74
75
|
pnpmfileLocation: commonTempFolder + '/.pnpmfile.cjs',
|
|
75
76
|
projectRoot: currentFolder,
|
|
@@ -92,7 +93,7 @@ const init = (options) => {
|
|
|
92
93
|
currentWorkingDirectory,
|
|
93
94
|
appVersion,
|
|
94
95
|
debugMode,
|
|
95
|
-
lockfileExplorerProjectRoot,
|
|
96
|
+
lockfileExplorerProjectRoot: constants_1.LFX_PACKAGE_ROOT,
|
|
96
97
|
pnpmLockfileLocation: currentFolder + '/pnpm-lock.yaml',
|
|
97
98
|
pnpmfileLocation: currentFolder + '/.pnpmfile.cjs',
|
|
98
99
|
projectRoot: currentFolder,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/utils/init.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE3D,uHAAuH;AACvH,6DAA6D;AAE7D,0DAA6B;AAE7B,oEAAgE;AAChE,qFAAkF;AAGlF,oEAAsD;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/utils/init.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n// This function will read the current directory and try to figure out if it's a rush project or regular pnpm workspace\n// Currently it will throw error if neither can be determined\n\nimport path from 'node:path';\n\nimport { FileSystem, Path } from '@rushstack/node-core-library';\nimport { RushConfiguration } from '@microsoft/rush-lib/lib/api/RushConfiguration';\nimport type { Subspace } from '@microsoft/rush-lib/lib/api/Subspace';\n\nimport * as lockfilePath from '../graph/lockfilePath';\nimport type { IAppState } from '../state';\nimport { LFX_PACKAGE_ROOT } from './constants';\n\nexport interface IInitOptions {\n appVersion: string;\n debugMode: boolean;\n subspaceName: string;\n}\n\nexport const init = (options: IInitOptions): Omit<IAppState, 'graph'> => {\n const { appVersion, debugMode, subspaceName } = options;\n const currentWorkingDirectory: string = path.resolve(process.cwd());\n\n let appState: IAppState | undefined;\n let currentFolder: string = Path.convertToSlashes(currentWorkingDirectory);\n while (currentFolder.includes('/')) {\n // Look for a rush.json [rush project] or pnpm-lock.yaml file [regular pnpm workspace]\n const rushJsonPath: string = currentFolder + '/rush.json';\n const pnpmLockPath: string = currentFolder + '/pnpm-lock.yaml';\n if (FileSystem.exists(rushJsonPath)) {\n console.log('Found a Rush workspace: ', rushJsonPath);\n\n const rushConfiguration: RushConfiguration = RushConfiguration.loadFromConfigurationFile(rushJsonPath);\n const subspace: Subspace = rushConfiguration.getSubspace(subspaceName);\n const commonTempFolder: string = subspace.getSubspaceTempFolderPath();\n const pnpmLockfileAbsolutePath: string = path.join(commonTempFolder, 'pnpm-lock.yaml');\n\n const relativeCommonTempFolder: string = Path.convertToSlashes(\n path.relative(currentFolder, subspace.getSubspaceTempFolderPath())\n );\n const pnpmLockfileRelativePath: string = lockfilePath.join(relativeCommonTempFolder, 'pnpm-lock.yaml');\n const pnpmFileRelativePath: string = lockfilePath.join(relativeCommonTempFolder, '.pnpmfile.cjs');\n\n const relativeCommonConfigFolder: string = Path.convertToSlashes(\n path.relative(currentFolder, subspace.getSubspaceConfigFolderPath())\n );\n const rushPnpmFileRelativePath: string = lockfilePath.join(relativeCommonConfigFolder, '.pnpmfile.cjs');\n\n appState = {\n currentWorkingDirectory,\n appVersion,\n debugMode,\n lockfileExplorerProjectRoot: LFX_PACKAGE_ROOT,\n pnpmLockfileLocation: pnpmLockfileAbsolutePath,\n pnpmfileLocation: commonTempFolder + '/.pnpmfile.cjs',\n projectRoot: currentFolder,\n lfxWorkspace: {\n workspaceRootFullPath: currentFolder,\n pnpmLockfilePath: Path.convertToSlashes(pnpmLockfileRelativePath),\n pnpmLockfileFolder: Path.convertToSlashes(path.dirname(pnpmLockfileRelativePath)),\n pnpmfilePath: Path.convertToSlashes(pnpmFileRelativePath),\n rushConfig: {\n rushVersion: rushConfiguration.rushConfigurationJson.rushVersion,\n subspaceName: subspaceName ?? '',\n rushPnpmfilePath: rushPnpmFileRelativePath\n }\n }\n };\n break;\n } else if (FileSystem.exists(pnpmLockPath)) {\n appState = {\n currentWorkingDirectory,\n appVersion,\n debugMode,\n lockfileExplorerProjectRoot: LFX_PACKAGE_ROOT,\n pnpmLockfileLocation: currentFolder + '/pnpm-lock.yaml',\n pnpmfileLocation: currentFolder + '/.pnpmfile.cjs',\n projectRoot: currentFolder,\n lfxWorkspace: {\n workspaceRootFullPath: currentFolder,\n pnpmLockfilePath: Path.convertToSlashes(path.relative(currentFolder, pnpmLockPath)),\n pnpmLockfileFolder: '',\n pnpmfilePath: '.pnpmfile.cjs',\n rushConfig: undefined\n }\n };\n\n break;\n }\n\n currentFolder = currentFolder.substring(0, currentFolder.lastIndexOf('/'));\n }\n\n if (!appState) {\n throw new Error('Could not find a Rush or PNPM workspace!');\n }\n\n return appState;\n};\n"]}
|
|
@@ -2,10 +2,9 @@ import { type ITerminal } from '@rushstack/terminal';
|
|
|
2
2
|
import { CommandLineParser } from '@rushstack/ts-command-line';
|
|
3
3
|
export declare class ExplorerCommandLineParser extends CommandLineParser {
|
|
4
4
|
readonly globalTerminal: ITerminal;
|
|
5
|
-
private readonly _terminalProvider;
|
|
6
5
|
private readonly _debugParameter;
|
|
7
6
|
private readonly _subspaceParameter;
|
|
8
|
-
constructor();
|
|
7
|
+
constructor(terminal: ITerminal);
|
|
9
8
|
get isDebug(): boolean;
|
|
10
9
|
protected onExecuteAsync(): Promise<void>;
|
|
11
10
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExplorerCommandLineParser.d.ts","sourceRoot":"","sources":["../../../src/cli/explorer/ExplorerCommandLineParser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ExplorerCommandLineParser.d.ts","sourceRoot":"","sources":["../../../src/cli/explorer/ExplorerCommandLineParser.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAEL,iBAAiB,EAElB,MAAM,4BAA4B,CAAC;AAiCpC,qBAAa,yBAA0B,SAAQ,iBAAiB;IAC9D,SAAgB,cAAc,EAAE,SAAS,CAAC;IAE1C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA2B;IAC3D,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAsC;gBAEtD,QAAQ,EAAE,SAAS;IAuBtC,IAAW,OAAO,IAAI,OAAO,CAE5B;cAEwB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAsNzD"}
|
|
@@ -2,8 +2,7 @@ import { type ITerminal } from '@rushstack/terminal';
|
|
|
2
2
|
import { CommandLineParser } from '@rushstack/ts-command-line';
|
|
3
3
|
export declare class LintCommandLineParser extends CommandLineParser {
|
|
4
4
|
readonly globalTerminal: ITerminal;
|
|
5
|
-
|
|
6
|
-
constructor();
|
|
5
|
+
constructor(terminal: ITerminal);
|
|
7
6
|
protected onExecuteAsync(): Promise<void>;
|
|
8
7
|
private _populateActions;
|
|
9
8
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LintCommandLineParser.d.ts","sourceRoot":"","sources":["../../../src/cli/lint/LintCommandLineParser.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"LintCommandLineParser.d.ts","sourceRoot":"","sources":["../../../src/cli/lint/LintCommandLineParser.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAQ/D,qBAAa,qBAAsB,SAAQ,iBAAiB;IAC1D,SAAgB,cAAc,EAAE,SAAS,CAAC;gBAEvB,QAAQ,EAAE,SAAS;cAYb,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAQxD,OAAO,CAAC,gBAAgB;CAKzB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommandLineAction } from '@rushstack/ts-command-line';
|
|
2
|
-
import type
|
|
2
|
+
import { type ITerminal } from '@rushstack/terminal';
|
|
3
3
|
export interface ILintRule {
|
|
4
4
|
rule: 'restrict-versions';
|
|
5
5
|
project: string;
|
|
@@ -18,7 +18,7 @@ export declare class CheckAction extends CommandLineAction {
|
|
|
18
18
|
private _rushConfiguration;
|
|
19
19
|
private _checkedProjects;
|
|
20
20
|
private _docMap;
|
|
21
|
-
constructor(
|
|
21
|
+
constructor(terminal: ITerminal);
|
|
22
22
|
private _checkVersionCompatibilityAsync;
|
|
23
23
|
private _searchAndValidateDependenciesAsync;
|
|
24
24
|
private _performVersionRestrictionCheckAsync;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckAction.d.ts","sourceRoot":"","sources":["../../../../src/cli/lint/actions/CheckAction.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"CheckAction.d.ts","sourceRoot":"","sources":["../../../../src/cli/lint/actions/CheckAction.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAW/D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,WAAY,SAAQ,iBAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IAEtC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,gBAAgB,CAAgC;IACxD,OAAO,CAAC,OAAO,CAA4C;gBAExC,QAAQ,EAAE,SAAS;YAexB,+BAA+B;YAqC/B,mCAAmC;YA4DnC,oCAAoC;cAoBzB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAkEzD"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { CommandLineAction } from '@rushstack/ts-command-line';
|
|
2
|
-
import type
|
|
2
|
+
import { type ITerminal } from '@rushstack/terminal';
|
|
3
3
|
export declare class InitAction extends CommandLineAction {
|
|
4
4
|
private readonly _terminal;
|
|
5
|
-
constructor(
|
|
5
|
+
constructor(terminal: ITerminal);
|
|
6
6
|
protected onExecuteAsync(): Promise<void>;
|
|
7
7
|
}
|
|
8
8
|
//# sourceMappingURL=InitAction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InitAction.d.ts","sourceRoot":"","sources":["../../../../src/cli/lint/actions/InitAction.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"InitAction.d.ts","sourceRoot":"","sources":["../../../../src/cli/lint/actions/InitAction.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAM/D,qBAAa,UAAW,SAAQ,iBAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAEnB,QAAQ,EAAE,SAAS;cAWb,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CA8BzD"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TODO: If we end up expecting to use this elsewhere, we should move this to
|
|
3
|
+
* either its own package or into `@rushstack/node-core-library`.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Options for {@link _PackageUpdateChecker}.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export interface IPackageUpdateCheckerOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The npm package name to check for updates.
|
|
13
|
+
*/
|
|
14
|
+
packageName: string;
|
|
15
|
+
/**
|
|
16
|
+
* The currently installed version.
|
|
17
|
+
*/
|
|
18
|
+
currentVersion: string;
|
|
19
|
+
/**
|
|
20
|
+
* If `true`, skip the update check entirely.
|
|
21
|
+
* Use this to suppress checks in CI environments or non-interactive sessions.
|
|
22
|
+
*
|
|
23
|
+
* @defaultValue false
|
|
24
|
+
*/
|
|
25
|
+
skip?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* If `true`, bypass the cache and always fetch from the registry.
|
|
28
|
+
* Useful in debug/verbose modes where you want an immediate, authoritative answer.
|
|
29
|
+
*
|
|
30
|
+
* @defaultValue false
|
|
31
|
+
*/
|
|
32
|
+
forceCheck?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* How long (in milliseconds) to consider a cached registry response fresh
|
|
35
|
+
* before re-fetching.
|
|
36
|
+
*
|
|
37
|
+
* @defaultValue 86400000 (24 hours)
|
|
38
|
+
*/
|
|
39
|
+
cacheExpiryMs?: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The result of an update check.
|
|
43
|
+
*
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
46
|
+
export interface IPackageUpdateResult {
|
|
47
|
+
/**
|
|
48
|
+
* The latest version available on the registry.
|
|
49
|
+
*/
|
|
50
|
+
latestVersion: string;
|
|
51
|
+
/**
|
|
52
|
+
* `true` if {@link _IPackageUpdateResult.latestVersion} is strictly newer than
|
|
53
|
+
* the {@link _IPackageUpdateCheckerOptions.currentVersion} that was passed to the checker.
|
|
54
|
+
*/
|
|
55
|
+
isOutdated: boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Checks npm for a newer version of a package and caches the result locally so that
|
|
59
|
+
* the registry is not queried on every invocation.
|
|
60
|
+
*
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
export declare class PackageUpdateChecker {
|
|
64
|
+
private readonly _packageName;
|
|
65
|
+
private readonly _currentVersion;
|
|
66
|
+
private readonly _skip;
|
|
67
|
+
private readonly _forceCheck;
|
|
68
|
+
private readonly _cacheExpiryMs;
|
|
69
|
+
constructor(options: IPackageUpdateCheckerOptions);
|
|
70
|
+
/**
|
|
71
|
+
* Performs the update check and returns the result, or `undefined` if the check
|
|
72
|
+
* was skipped or the registry could not be reached.
|
|
73
|
+
*/
|
|
74
|
+
tryGetUpdateAsync(): Promise<IPackageUpdateResult | undefined>;
|
|
75
|
+
private _getCacheFilePath;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=PackageUpdateChecker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PackageUpdateChecker.d.ts","sourceRoot":"","sources":["../../src/utils/PackageUpdateChecker.ts"],"names":[],"mappings":"AASA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAoED;;;;;GAKG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IACtC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAErB,OAAO,EAAE,4BAA4B;IAexD;;;OAGG;IACU,iBAAiB,IAAI,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAmC3E,OAAO,CAAC,iBAAiB;CAK1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAOA,eAAO,MAAiB,WAAW,UAAQ,gBAAgB,QAAgC,CAAC;AAO5F,eAAO,MAAM,gBAAgB,EAAE,MAAuD,CAAC"}
|
package/lib-dts/utils/init.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { IAppState } from '../state';
|
|
2
|
-
export
|
|
3
|
-
lockfileExplorerProjectRoot: string;
|
|
2
|
+
export interface IInitOptions {
|
|
4
3
|
appVersion: string;
|
|
5
4
|
debugMode: boolean;
|
|
6
5
|
subspaceName: string;
|
|
7
|
-
}
|
|
6
|
+
}
|
|
7
|
+
export declare const init: (options: IInitOptions) => Omit<IAppState, "graph">;
|
|
8
8
|
//# sourceMappingURL=init.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/utils/init.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/utils/init.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,IAAI,GAAI,SAAS,YAAY,KAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CA+EnE,CAAC"}
|
|
@@ -5,18 +5,25 @@ import * as path from 'node:path';
|
|
|
5
5
|
import express from 'express';
|
|
6
6
|
import yaml from 'js-yaml';
|
|
7
7
|
import cors from 'cors';
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import { ConsoleTerminalProvider, Terminal, Colorize } from '@rushstack/terminal';
|
|
8
|
+
import { Executable, FileSystem, JsonFile } from '@rushstack/node-core-library';
|
|
9
|
+
import { Colorize } from '@rushstack/terminal';
|
|
11
10
|
import { CommandLineParser } from '@rushstack/ts-command-line';
|
|
12
11
|
import { lfxGraphSerializer } from '../../../build/lfx-shared';
|
|
13
12
|
import * as lockfilePath from '../../graph/lockfilePath';
|
|
14
13
|
import { init } from '../../utils/init';
|
|
15
14
|
import { PnpmfileRunner } from '../../graph/PnpmfileRunner';
|
|
16
15
|
import * as lfxGraphLoader from '../../graph/lfxGraphLoader';
|
|
16
|
+
import { LFX_PACKAGE_NAME, LFX_VERSION } from '../../utils/constants';
|
|
17
|
+
import { PackageUpdateChecker } from '../../utils/PackageUpdateChecker';
|
|
17
18
|
const EXPLORER_TOOL_FILENAME = 'lockfile-explorer';
|
|
19
|
+
function printUpdateNotification(result, terminal) {
|
|
20
|
+
if (result === null || result === void 0 ? void 0 : result.isOutdated) {
|
|
21
|
+
terminal.writeLine(Colorize.yellow(`\nUpdate available: ${LFX_VERSION} → ${result.latestVersion}\n` +
|
|
22
|
+
`Run: npm install -g ${LFX_PACKAGE_NAME}\n`));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
18
25
|
export class ExplorerCommandLineParser extends CommandLineParser {
|
|
19
|
-
constructor() {
|
|
26
|
+
constructor(terminal) {
|
|
20
27
|
super({
|
|
21
28
|
toolFilename: EXPLORER_TOOL_FILENAME,
|
|
22
29
|
toolDescription: 'Lockfile Explorer is a desktop app for investigating and solving version conflicts in a PNPM workspace.'
|
|
@@ -32,35 +39,29 @@ export class ExplorerCommandLineParser extends CommandLineParser {
|
|
|
32
39
|
description: 'Specifies an individual Rush subspace to check.',
|
|
33
40
|
defaultValue: 'default'
|
|
34
41
|
});
|
|
35
|
-
this.
|
|
36
|
-
this.globalTerminal = new Terminal(this._terminalProvider);
|
|
42
|
+
this.globalTerminal = terminal;
|
|
37
43
|
}
|
|
38
44
|
get isDebug() {
|
|
39
45
|
return this._debugParameter.value;
|
|
40
46
|
}
|
|
41
47
|
async onExecuteAsync() {
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
const appVersion = lockfileExplorerPackageJson.version;
|
|
45
|
-
this.globalTerminal.writeLine(Colorize.bold(`\nRush Lockfile Explorer ${appVersion}`) +
|
|
48
|
+
const terminal = this.globalTerminal;
|
|
49
|
+
terminal.writeLine(Colorize.bold(`\nRush Lockfile Explorer ${LFX_VERSION}`) +
|
|
46
50
|
Colorize.cyan(' - https://lfx.rushstack.io/\n'));
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
isGlobal: true,
|
|
55
|
-
// Show the notice immediately, rather than waiting for process.onExit()
|
|
56
|
-
defer: false
|
|
51
|
+
// Start the update check now so it runs concurrently with server setup.
|
|
52
|
+
// The result is awaited and displayed inside app.listen once the server is ready.
|
|
53
|
+
const updateChecker = new PackageUpdateChecker({
|
|
54
|
+
packageName: LFX_PACKAGE_NAME,
|
|
55
|
+
currentVersion: LFX_VERSION,
|
|
56
|
+
// In debug mode, bypass the cache so the notice appears immediately.
|
|
57
|
+
forceCheck: this.isDebug
|
|
57
58
|
});
|
|
59
|
+
const updateCheckPromise = updateChecker.tryGetUpdateAsync();
|
|
58
60
|
const PORT = 8091;
|
|
59
61
|
// Must not have a trailing slash
|
|
60
62
|
const SERVICE_URL = `http://localhost:${PORT}`;
|
|
61
63
|
const appState = init({
|
|
62
|
-
|
|
63
|
-
appVersion,
|
|
64
|
+
appVersion: LFX_VERSION,
|
|
64
65
|
debugMode: this.isDebug,
|
|
65
66
|
subspaceName: this._subspaceParameter.value
|
|
66
67
|
});
|
|
@@ -77,8 +78,8 @@ export class ExplorerCommandLineParser extends CommandLineParser {
|
|
|
77
78
|
let disconnected = false;
|
|
78
79
|
setInterval(() => {
|
|
79
80
|
if (!isClientConnected && !awaitingFirstConnect && !disconnected) {
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
terminal.writeLine(Colorize.red('The client has disconnected!'));
|
|
82
|
+
terminal.writeLine(`Please open a browser window at http://localhost:${PORT}/app`);
|
|
82
83
|
disconnected = true;
|
|
83
84
|
}
|
|
84
85
|
else if (!awaitingFirstConnect) {
|
|
@@ -105,7 +106,7 @@ export class ExplorerCommandLineParser extends CommandLineParser {
|
|
|
105
106
|
isClientConnected = true;
|
|
106
107
|
if (disconnected) {
|
|
107
108
|
disconnected = false;
|
|
108
|
-
|
|
109
|
+
terminal.writeLine(Colorize.green('The client has reconnected!'));
|
|
109
110
|
}
|
|
110
111
|
res.status(200).send();
|
|
111
112
|
});
|
|
@@ -187,7 +188,8 @@ export class ExplorerCommandLineParser extends CommandLineParser {
|
|
|
187
188
|
res.send(parsedPackage);
|
|
188
189
|
});
|
|
189
190
|
app.listen(PORT, async () => {
|
|
190
|
-
|
|
191
|
+
terminal.writeLine(`App launched on ${SERVICE_URL}`);
|
|
192
|
+
printUpdateNotification(await updateCheckPromise, terminal);
|
|
191
193
|
if (!appState.debugMode) {
|
|
192
194
|
try {
|
|
193
195
|
// Launch the default web browser using the platform-native open command.
|
|
@@ -219,7 +221,7 @@ export class ExplorerCommandLineParser extends CommandLineParser {
|
|
|
219
221
|
browserProcess.unref();
|
|
220
222
|
}
|
|
221
223
|
catch (e) {
|
|
222
|
-
|
|
224
|
+
terminal.writeError('Error launching browser: ' + e.toString());
|
|
223
225
|
}
|
|
224
226
|
}
|
|
225
227
|
});
|