@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.
Files changed (56) hide show
  1. package/CHANGELOG.json +35 -0
  2. package/CHANGELOG.md +13 -1
  3. package/dist/{app.0b644e08b36979b58936.js → app.3fe86541880858baf783.js} +1 -1
  4. package/dist/index.html +1 -1
  5. package/dist/rush-themed-ui.js +2 -2
  6. package/lib-commonjs/cli/explorer/ExplorerCommandLineParser.js +27 -25
  7. package/lib-commonjs/cli/explorer/ExplorerCommandLineParser.js.map +1 -1
  8. package/lib-commonjs/cli/lint/LintCommandLineParser.js +7 -10
  9. package/lib-commonjs/cli/lint/LintCommandLineParser.js.map +1 -1
  10. package/lib-commonjs/cli/lint/actions/CheckAction.js +2 -2
  11. package/lib-commonjs/cli/lint/actions/CheckAction.js.map +1 -1
  12. package/lib-commonjs/cli/lint/actions/InitAction.js +2 -2
  13. package/lib-commonjs/cli/lint/actions/InitAction.js.map +1 -1
  14. package/lib-commonjs/start-explorer.js +3 -1
  15. package/lib-commonjs/start-explorer.js.map +1 -1
  16. package/lib-commonjs/start-lint.js +3 -1
  17. package/lib-commonjs/start-lint.js.map +1 -1
  18. package/lib-commonjs/utils/PackageUpdateChecker.js +120 -0
  19. package/lib-commonjs/utils/PackageUpdateChecker.js.map +1 -0
  20. package/lib-commonjs/utils/constants.js +15 -0
  21. package/lib-commonjs/utils/constants.js.map +1 -0
  22. package/lib-commonjs/utils/init.js +4 -3
  23. package/lib-commonjs/utils/init.js.map +1 -1
  24. package/lib-dts/cli/explorer/ExplorerCommandLineParser.d.ts +1 -2
  25. package/lib-dts/cli/explorer/ExplorerCommandLineParser.d.ts.map +1 -1
  26. package/lib-dts/cli/lint/LintCommandLineParser.d.ts +1 -2
  27. package/lib-dts/cli/lint/LintCommandLineParser.d.ts.map +1 -1
  28. package/lib-dts/cli/lint/actions/CheckAction.d.ts +2 -2
  29. package/lib-dts/cli/lint/actions/CheckAction.d.ts.map +1 -1
  30. package/lib-dts/cli/lint/actions/InitAction.d.ts +2 -2
  31. package/lib-dts/cli/lint/actions/InitAction.d.ts.map +1 -1
  32. package/lib-dts/utils/PackageUpdateChecker.d.ts +77 -0
  33. package/lib-dts/utils/PackageUpdateChecker.d.ts.map +1 -0
  34. package/lib-dts/utils/constants.d.ts +3 -0
  35. package/lib-dts/utils/constants.d.ts.map +1 -0
  36. package/lib-dts/utils/init.d.ts +3 -3
  37. package/lib-dts/utils/init.d.ts.map +1 -1
  38. package/lib-esm/cli/explorer/ExplorerCommandLineParser.js +29 -27
  39. package/lib-esm/cli/explorer/ExplorerCommandLineParser.js.map +1 -1
  40. package/lib-esm/cli/lint/LintCommandLineParser.js +8 -11
  41. package/lib-esm/cli/lint/LintCommandLineParser.js.map +1 -1
  42. package/lib-esm/cli/lint/actions/CheckAction.js +2 -2
  43. package/lib-esm/cli/lint/actions/CheckAction.js.map +1 -1
  44. package/lib-esm/cli/lint/actions/InitAction.js +2 -2
  45. package/lib-esm/cli/lint/actions/InitAction.js.map +1 -1
  46. package/lib-esm/start-explorer.js +3 -1
  47. package/lib-esm/start-explorer.js.map +1 -1
  48. package/lib-esm/start-lint.js +3 -1
  49. package/lib-esm/start-lint.js.map +1 -1
  50. package/lib-esm/utils/PackageUpdateChecker.js +113 -0
  51. package/lib-esm/utils/PackageUpdateChecker.js.map +1 -0
  52. package/lib-esm/utils/constants.js +9 -0
  53. package/lib-esm/utils/constants.js.map +1 -0
  54. package/lib-esm/utils/init.js +4 -3
  55. package/lib-esm/utils/init.js.map +1 -1
  56. package/package.json +8 -10
@@ -1 +1 @@
1
- {"version":3,"file":"ExplorerCommandLineParser.js","sourceRoot":"","sources":["../../../src/cli/explorer/ExplorerCommandLineParser.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,cAAc,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EACL,UAAU,EACV,UAAU,EAEV,QAAQ,EACR,iBAAiB,EAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAkB,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAClG,OAAO,EAEL,iBAAiB,EAElB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAEL,kBAAkB,EAInB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,YAAY,MAAM,0BAA0B,CAAC;AAEzD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,cAAc,MAAM,4BAA4B,CAAC;AAE7D,MAAM,sBAAsB,GAAwB,mBAAmB,CAAC;AAExE,MAAM,OAAO,yBAA0B,SAAQ,iBAAiB;IAO9D;QACE,KAAK,CAAC;YACJ,YAAY,EAAE,sBAAsB;YACpC,eAAe,EACb,yGAAyG;SAC5G,CAAC,CAAC;QAEH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,mBAAmB,CAAC;YAC9C,iBAAiB,EAAE,SAAS;YAC5B,kBAAkB,EAAE,IAAI;YACxB,WAAW,EAAE,sEAAsE;SACpF,CAAC,CAAC;QAEH,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,qBAAqB,CAAC;YACnD,iBAAiB,EAAE,YAAY;YAC/B,YAAY,EAAE,eAAe;YAC7B,WAAW,EAAE,iDAAiD;YAC9D,YAAY,EAAE,SAAS;SACxB,CAAC,CAAC;QAEH,IAAI,CAAC,iBAAiB,GAAG,IAAI,uBAAuB,EAAE,CAAC;QACvD,IAAI,CAAC,cAAc,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC7D,CAAC;IAED,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;IACpC,CAAC;IAEkB,KAAK,CAAC,cAAc;QACrC,MAAM,2BAA2B,GAAW,iBAAiB,CAAC,QAAQ,CAAC,sBAAsB,CAAC,SAAS,CAAE,CAAC;QAC1G,MAAM,2BAA2B,GAAiB,QAAQ,CAAC,IAAI,CAC7D,GAAG,2BAA2B,eAAe,CAC9C,CAAC;QACF,MAAM,UAAU,GAAW,2BAA2B,CAAC,OAAO,CAAC;QAE/D,IAAI,CAAC,cAAc,CAAC,SAAS,CAC3B,QAAQ,CAAC,IAAI,CAAC,4BAA4B,UAAU,EAAE,CAAC;YACrD,QAAQ,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAClD,CAAC;QAEF,cAAc,CAAC;YACb,GAAG,EAAE,2BAA2B;YAChC,0FAA0F;YAC1F,6CAA6C;YAC7C,mBAAmB,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;SAClD,CAAC,CAAC,MAAM,CAAC;YACR,mEAAmE;YACnE,QAAQ,EAAE,IAAI;YACd,wEAAwE;YACxE,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;QAEH,MAAM,IAAI,GAAW,IAAI,CAAC;QAC1B,iCAAiC;QACjC,MAAM,WAAW,GAAW,oBAAoB,IAAI,EAAE,CAAC;QAEvD,MAAM,QAAQ,GAAc,IAAI,CAAC;YAC/B,2BAA2B;YAC3B,UAAU;YACV,SAAS,EAAE,IAAI,CAAC,OAAO;YACvB,YAAY,EAAE,IAAI,CAAC,kBAAkB,CAAC,KAAK;SAC5C,CAAC,CAAC;QAEH,MAAM,YAAY,GAAsB,QAAQ,CAAC,YAAY,CAAC;QAE9D,+EAA+E;QAC/E,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC;QAEpD,MAAM,cAAc,GAAW,GAAG,QAAQ,CAAC,2BAA2B,OAAO,CAAC;QAC9E,MAAM,GAAG,GAAwB,OAAO,EAAE,CAAC;QAC3C,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAEhB,oEAAoE;QACpE,IAAI,oBAAoB,GAAY,IAAI,CAAC;QACzC,IAAI,iBAAiB,GAAY,KAAK,CAAC;QACvC,IAAI,YAAY,GAAY,KAAK,CAAC;QAClC,WAAW,CAAC,GAAG,EAAE;YACf,IAAI,CAAC,iBAAiB,IAAI,CAAC,oBAAoB,IAAI,CAAC,YAAY,EAAE,CAAC;gBACjE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAC;gBAC1D,OAAO,CAAC,GAAG,CAAC,oDAAoD,IAAI,MAAM,CAAC,CAAC;gBAC5E,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;iBAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBACjC,iBAAiB,GAAG,KAAK,CAAC;YAC5B,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,kGAAkG;QAClG,GAAG,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC,GAAoB,EAAE,GAAqB,EAAE,EAAE;YAC5E,MAAM,UAAU,GAAgB;gBAC9B,UAAU,EAAE,WAAW;gBACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,SAAS,EAAE,IAAI,CAAC,OAAO;aACxB,CAAC;YACF,MAAM,UAAU,GAAW;gBACzB,0CAA0C;gBAC1C,gBAAgB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE;aAC7C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEb,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;QAE7C,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;QAElF,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,GAAoB,EAAE,GAAqB,EAAE,EAAE;YACrE,oBAAoB,GAAG,KAAK,CAAC;YAC7B,iBAAiB,GAAG,IAAI,CAAC;YACzB,IAAI,YAAY,EAAE,CAAC;gBACjB,YAAY,GAAG,KAAK,CAAC;gBACrB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;YAC7D,CAAC;YACD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,EAAE,GAAoB,EAAE,GAAqB,EAAE,EAAE;YAC1E,MAAM,gBAAgB,GAAW,MAAM,UAAU,CAAC,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;YAC/F,MAAM,QAAQ,GAAY,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAY,CAAC;YAEjE,MAAM,KAAK,GAAa,cAAc,CAAC,qBAAqB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YAErF,MAAM,SAAS,GAAkB,kBAAkB,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAC3E,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,IAAI,CACN,mBAAmB,EACnB,KAAK,EAAE,GAAyD,EAAE,GAAqB,EAAE,EAAE;YACzF,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YACjC,MAAM,YAAY,GAAW,GAAG,QAAQ,CAAC,WAAW,IAAI,WAAW,eAAe,CAAC;YACnF,IAAI,eAAuB,CAAC;YAC5B,IAAI,CAAC;gBACH,eAAe,GAAG,MAAM,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YACjE,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;oBAClC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;wBAC1B,OAAO,EAAE,gHAAgH;wBACzH,KAAK,EAAE,gCAAgC,WAAW,EAAE;qBACrD,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,CAAC;gBACV,CAAC;YACH,CAAC;YAED,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5B,CAAC,CACF,CAAC;QAEF,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,GAAoB,EAAE,GAAqB,EAAE,EAAE;;YAC7E,MAAM,YAAY,GAAW,YAAY,CAAC,IAAI,CAC5C,YAAY,CAAC,qBAAqB,EAClC,MAAA,MAAA,YAAY,CAAC,UAAU,0CAAE,gBAAgB,mCAAI,YAAY,CAAC,YAAY,CACvE,CAAC;YAEF,IAAI,QAAgB,CAAC;YACrB,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YAC1D,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;oBAClC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;wBAC1B,OAAO,EAAE,oDAAoD,YAAY,GAAG;wBAC5E,KAAK,EAAE,0BAA0B;qBAClC,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,CAAC;gBACV,CAAC;YACH,CAAC;YAED,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,IAAI,CACN,mBAAmB,EACnB,KAAK,EAAE,GAAyD,EAAE,GAAqB,EAAE,EAAE;YACzF,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YACjC,MAAM,YAAY,GAAW,GAAG,QAAQ,CAAC,WAAW,IAAI,WAAW,eAAe,CAAC;YACnF,IAAI,WAAyB,CAAC;YAC9B,IAAI,CAAC;gBACH,WAAW,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YACvD,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;oBAClC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;wBAC1B,OAAO,EAAE,iDAAiD,WAAW,EAAE;qBACxE,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,CAAC;gBACV,CAAC;YACH,CAAC;YAED,IAAI,aAAa,GAAiB,WAAW,CAAC;YAE9C,MAAM,YAAY,GAAW,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,qBAAqB,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;YACtG,IAAI,MAAM,UAAU,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC/C,MAAM,cAAc,GAAmB,IAAI,cAAc,CAAC,YAAY,CAAC,CAAC;gBACxE,IAAI,CAAC;oBACH,aAAa,GAAG,MAAM,cAAc,CAAC,qBAAqB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;gBACxF,CAAC;wBAAS,CAAC;oBACT,MAAM,cAAc,CAAC,YAAY,EAAE,CAAC;gBACtC,CAAC;YACH,CAAC;YAED,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1B,CAAC,CACF,CAAC;QAEF,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;YAC1B,OAAO,CAAC,GAAG,CAAC,mBAAmB,WAAW,EAAE,CAAC,CAAC;YAE9C,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;gBACxB,IAAI,CAAC;oBACH,yEAAyE;oBACzE,IAAI,UAAkB,CAAC;oBACvB,IAAI,WAAqB,CAAC;oBAC1B,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;wBACzB,KAAK,OAAO,CAAC,CAAC,CAAC;4BACb,8DAA8D;4BAC9D,iEAAiE;4BACjE,sDAAsD;4BACtD,UAAU,GAAG,KAAK,CAAC;4BACnB,WAAW,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;4BAC/C,MAAM;wBACR,CAAC;wBAED,KAAK,QAAQ,CAAC,CAAC,CAAC;4BACd,UAAU,GAAG,MAAM,CAAC;4BACpB,WAAW,GAAG,CAAC,WAAW,CAAC,CAAC;4BAC5B,MAAM;wBACR,CAAC;wBAED,OAAO,CAAC,CAAC,CAAC;4BACR,oCAAoC;4BACpC,UAAU,GAAG,UAAU,CAAC;4BACxB,WAAW,GAAG,CAAC,WAAW,CAAC,CAAC;4BAC5B,MAAM;wBACR,CAAC;oBACH,CAAC;oBAED,MAAM,cAAc,GAAiB,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;oBACpG,0EAA0E;oBAC1E,cAAc,CAAC,KAAK,EAAE,CAAC;gBACzB,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,2BAA2B,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC7E,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF","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 process from 'node:process';\nimport * as path from 'node:path';\nimport type { ChildProcess } from 'node:child_process';\n\nimport express from 'express';\nimport yaml from 'js-yaml';\nimport cors from 'cors';\nimport updateNotifier from 'update-notifier';\n\nimport {\n Executable,\n FileSystem,\n type IPackageJson,\n JsonFile,\n PackageJsonLookup\n} from '@rushstack/node-core-library';\nimport { ConsoleTerminalProvider, type ITerminal, Terminal, Colorize } from '@rushstack/terminal';\nimport {\n type CommandLineFlagParameter,\n CommandLineParser,\n type IRequiredCommandLineStringParameter\n} from '@rushstack/ts-command-line';\n\nimport {\n type LfxGraph,\n lfxGraphSerializer,\n type IAppContext,\n type IJsonLfxGraph,\n type IJsonLfxWorkspace\n} from '../../../build/lfx-shared';\nimport * as lockfilePath from '../../graph/lockfilePath';\nimport type { IAppState } from '../../state';\nimport { init } from '../../utils/init';\nimport { PnpmfileRunner } from '../../graph/PnpmfileRunner';\nimport * as lfxGraphLoader from '../../graph/lfxGraphLoader';\n\nconst EXPLORER_TOOL_FILENAME: 'lockfile-explorer' = 'lockfile-explorer';\n\nexport class ExplorerCommandLineParser extends CommandLineParser {\n public readonly globalTerminal: ITerminal;\n private readonly _terminalProvider: ConsoleTerminalProvider;\n private readonly _debugParameter: CommandLineFlagParameter;\n\n private readonly _subspaceParameter: IRequiredCommandLineStringParameter;\n\n public constructor() {\n super({\n toolFilename: EXPLORER_TOOL_FILENAME,\n toolDescription:\n 'Lockfile Explorer is a desktop app for investigating and solving version conflicts in a PNPM workspace.'\n });\n\n this._debugParameter = this.defineFlagParameter({\n parameterLongName: '--debug',\n parameterShortName: '-d',\n description: 'Show the full call stack if an error occurs while executing the tool'\n });\n\n this._subspaceParameter = this.defineStringParameter({\n parameterLongName: '--subspace',\n argumentName: 'SUBSPACE_NAME',\n description: 'Specifies an individual Rush subspace to check.',\n defaultValue: 'default'\n });\n\n this._terminalProvider = new ConsoleTerminalProvider();\n this.globalTerminal = new Terminal(this._terminalProvider);\n }\n\n public get isDebug(): boolean {\n return this._debugParameter.value;\n }\n\n protected override async onExecuteAsync(): Promise<void> {\n const lockfileExplorerProjectRoot: string = PackageJsonLookup.instance.tryGetPackageFolderFor(__dirname)!;\n const lockfileExplorerPackageJson: IPackageJson = JsonFile.load(\n `${lockfileExplorerProjectRoot}/package.json`\n );\n const appVersion: string = lockfileExplorerPackageJson.version;\n\n this.globalTerminal.writeLine(\n Colorize.bold(`\\nRush Lockfile Explorer ${appVersion}`) +\n Colorize.cyan(' - https://lfx.rushstack.io/\\n')\n );\n\n updateNotifier({\n pkg: lockfileExplorerPackageJson,\n // Normally update-notifier waits a day or so before it starts displaying upgrade notices.\n // In debug mode, show the notice right away.\n updateCheckInterval: this.isDebug ? 0 : undefined\n }).notify({\n // Make sure it says \"-g\" in the \"npm install\" example command line\n isGlobal: true,\n // Show the notice immediately, rather than waiting for process.onExit()\n defer: false\n });\n\n const PORT: number = 8091;\n // Must not have a trailing slash\n const SERVICE_URL: string = `http://localhost:${PORT}`;\n\n const appState: IAppState = init({\n lockfileExplorerProjectRoot,\n appVersion,\n debugMode: this.isDebug,\n subspaceName: this._subspaceParameter.value\n });\n\n const lfxWorkspace: IJsonLfxWorkspace = appState.lfxWorkspace;\n\n // Important: This must happen after init() reads the current working directory\n process.chdir(appState.lockfileExplorerProjectRoot);\n\n const distFolderPath: string = `${appState.lockfileExplorerProjectRoot}/dist`;\n const app: express.Application = express();\n app.use(express.json());\n app.use(cors());\n\n // Variable used to check if the front-end client is still connected\n let awaitingFirstConnect: boolean = true;\n let isClientConnected: boolean = false;\n let disconnected: boolean = false;\n setInterval(() => {\n if (!isClientConnected && !awaitingFirstConnect && !disconnected) {\n console.log(Colorize.red('The client has disconnected!'));\n console.log(`Please open a browser window at http://localhost:${PORT}/app`);\n disconnected = true;\n } else if (!awaitingFirstConnect) {\n isClientConnected = false;\n }\n }, 4000);\n\n // This takes precedence over the `/app` static route, which also has an `initappcontext.js` file.\n app.get('/initappcontext.js', (req: express.Request, res: express.Response) => {\n const appContext: IAppContext = {\n serviceUrl: SERVICE_URL,\n appVersion: appState.appVersion,\n debugMode: this.isDebug\n };\n const sourceCode: string = [\n `console.log('Loaded initappcontext.js');`,\n `appContext = ${JSON.stringify(appContext)}`\n ].join('\\n');\n\n res.type('application/javascript').send(sourceCode);\n });\n\n app.use('/', express.static(distFolderPath));\n\n app.use('/favicon.ico', express.static(distFolderPath, { index: 'favicon.ico' }));\n\n app.get('/api/health', (req: express.Request, res: express.Response) => {\n awaitingFirstConnect = false;\n isClientConnected = true;\n if (disconnected) {\n disconnected = false;\n console.log(Colorize.green('The client has reconnected!'));\n }\n res.status(200).send();\n });\n\n app.get('/api/graph', async (req: express.Request, res: express.Response) => {\n const pnpmLockfileText: string = await FileSystem.readFileAsync(appState.pnpmLockfileLocation);\n const lockfile: unknown = yaml.load(pnpmLockfileText) as unknown;\n\n const graph: LfxGraph = lfxGraphLoader.generateLockfileGraph(lockfile, lfxWorkspace);\n\n const jsonGraph: IJsonLfxGraph = lfxGraphSerializer.serializeToJson(graph);\n res.type('application/json').send(jsonGraph);\n });\n\n app.post(\n '/api/package-json',\n async (req: express.Request<{}, {}, { projectPath: string }, {}>, res: express.Response) => {\n const { projectPath } = req.body;\n const fileLocation: string = `${appState.projectRoot}/${projectPath}/package.json`;\n let packageJsonText: string;\n try {\n packageJsonText = await FileSystem.readFileAsync(fileLocation);\n } catch (e) {\n if (FileSystem.isNotExistError(e)) {\n return res.status(404).send({\n message: `Could not load package.json file for this package. Have you installed all the dependencies for this workspace?`,\n error: `No package.json in location: ${projectPath}`\n });\n } else {\n throw e;\n }\n }\n\n res.send(packageJsonText);\n }\n );\n\n app.get('/api/pnpmfile', async (req: express.Request, res: express.Response) => {\n const pnpmfilePath: string = lockfilePath.join(\n lfxWorkspace.workspaceRootFullPath,\n lfxWorkspace.rushConfig?.rushPnpmfilePath ?? lfxWorkspace.pnpmfilePath\n );\n\n let pnpmfile: string;\n try {\n pnpmfile = await FileSystem.readFileAsync(pnpmfilePath);\n } catch (e) {\n if (FileSystem.isNotExistError(e)) {\n return res.status(404).send({\n message: `Could not load .pnpmfile.cjs file in this repo: \"${pnpmfilePath}\"`,\n error: `No .pnpmifile.cjs found.`\n });\n } else {\n throw e;\n }\n }\n\n res.send(pnpmfile);\n });\n\n app.post(\n '/api/package-spec',\n async (req: express.Request<{}, {}, { projectPath: string }, {}>, res: express.Response) => {\n const { projectPath } = req.body;\n const fileLocation: string = `${appState.projectRoot}/${projectPath}/package.json`;\n let packageJson: IPackageJson;\n try {\n packageJson = await JsonFile.loadAsync(fileLocation);\n } catch (e) {\n if (FileSystem.isNotExistError(e)) {\n return res.status(404).send({\n message: `Could not load package.json file in location: ${projectPath}`\n });\n } else {\n throw e;\n }\n }\n\n let parsedPackage: IPackageJson = packageJson;\n\n const pnpmfilePath: string = path.join(lfxWorkspace.workspaceRootFullPath, lfxWorkspace.pnpmfilePath);\n if (await FileSystem.existsAsync(pnpmfilePath)) {\n const pnpmFileRunner: PnpmfileRunner = new PnpmfileRunner(pnpmfilePath);\n try {\n parsedPackage = await pnpmFileRunner.transformPackageAsync(packageJson, fileLocation);\n } finally {\n await pnpmFileRunner.disposeAsync();\n }\n }\n\n res.send(parsedPackage);\n }\n );\n\n app.listen(PORT, async () => {\n console.log(`App launched on ${SERVICE_URL}`);\n\n if (!appState.debugMode) {\n try {\n // Launch the default web browser using the platform-native open command.\n let browserCmd: string;\n let browserArgs: string[];\n switch (process.platform) {\n case 'win32': {\n // \"start\" is a cmd.exe built-in, not a standalone executable.\n // The empty string is the required [title] argument; without it,\n // cmd interprets the URL as the title and ignores it.\n browserCmd = 'cmd';\n browserArgs = ['/c', 'start', '', SERVICE_URL];\n break;\n }\n\n case 'darwin': {\n browserCmd = 'open';\n browserArgs = [SERVICE_URL];\n break;\n }\n\n default: {\n // Linux and other Unix-like systems\n browserCmd = 'xdg-open';\n browserArgs = [SERVICE_URL];\n break;\n }\n }\n\n const browserProcess: ChildProcess = Executable.spawn(browserCmd, browserArgs, { stdio: 'ignore' });\n // Detach from our Node.js process so the browser stays open after we exit\n browserProcess.unref();\n } catch (e) {\n this.globalTerminal.writeError('Error launching browser: ' + e.toString());\n }\n }\n });\n }\n}\n"]}
1
+ {"version":3,"file":"ExplorerCommandLineParser.js","sourceRoot":"","sources":["../../../src/cli/explorer/ExplorerCommandLineParser.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 process from 'node:process';\nimport * as path from 'node:path';\nimport type { ChildProcess } from 'node:child_process';\n\nimport express from 'express';\nimport yaml from 'js-yaml';\nimport cors from 'cors';\n\nimport { Executable, FileSystem, type IPackageJson, JsonFile } from '@rushstack/node-core-library';\nimport { type ITerminal, Colorize } from '@rushstack/terminal';\nimport {\n type CommandLineFlagParameter,\n CommandLineParser,\n type IRequiredCommandLineStringParameter\n} from '@rushstack/ts-command-line';\n\nimport {\n type LfxGraph,\n lfxGraphSerializer,\n type IAppContext,\n type IJsonLfxGraph,\n type IJsonLfxWorkspace\n} from '../../../build/lfx-shared';\nimport * as lockfilePath from '../../graph/lockfilePath';\nimport type { IAppState } from '../../state';\nimport { init } from '../../utils/init';\nimport { PnpmfileRunner } from '../../graph/PnpmfileRunner';\nimport * as lfxGraphLoader from '../../graph/lfxGraphLoader';\nimport { LFX_PACKAGE_NAME, LFX_VERSION } from '../../utils/constants';\nimport { type IPackageUpdateResult, PackageUpdateChecker } from '../../utils/PackageUpdateChecker';\n\nconst EXPLORER_TOOL_FILENAME: 'lockfile-explorer' = 'lockfile-explorer';\n\nfunction printUpdateNotification(\n result: { latestVersion: string; isOutdated: boolean } | undefined,\n terminal: ITerminal\n): void {\n if (result?.isOutdated) {\n terminal.writeLine(\n Colorize.yellow(\n `\\nUpdate available: ${LFX_VERSION} → ${result.latestVersion}\\n` +\n `Run: npm install -g ${LFX_PACKAGE_NAME}\\n`\n )\n );\n }\n}\n\nexport class ExplorerCommandLineParser extends CommandLineParser {\n public readonly globalTerminal: ITerminal;\n\n private readonly _debugParameter: CommandLineFlagParameter;\n private readonly _subspaceParameter: IRequiredCommandLineStringParameter;\n\n public constructor(terminal: ITerminal) {\n super({\n toolFilename: EXPLORER_TOOL_FILENAME,\n toolDescription:\n 'Lockfile Explorer is a desktop app for investigating and solving version conflicts in a PNPM workspace.'\n });\n\n this._debugParameter = this.defineFlagParameter({\n parameterLongName: '--debug',\n parameterShortName: '-d',\n description: 'Show the full call stack if an error occurs while executing the tool'\n });\n\n this._subspaceParameter = this.defineStringParameter({\n parameterLongName: '--subspace',\n argumentName: 'SUBSPACE_NAME',\n description: 'Specifies an individual Rush subspace to check.',\n defaultValue: 'default'\n });\n\n this.globalTerminal = terminal;\n }\n\n public get isDebug(): boolean {\n return this._debugParameter.value;\n }\n\n protected override async onExecuteAsync(): Promise<void> {\n const terminal: ITerminal = this.globalTerminal;\n\n terminal.writeLine(\n Colorize.bold(`\\nRush Lockfile Explorer ${LFX_VERSION}`) +\n Colorize.cyan(' - https://lfx.rushstack.io/\\n')\n );\n\n // Start the update check now so it runs concurrently with server setup.\n // The result is awaited and displayed inside app.listen once the server is ready.\n const updateChecker: PackageUpdateChecker = new PackageUpdateChecker({\n packageName: LFX_PACKAGE_NAME,\n currentVersion: LFX_VERSION,\n // In debug mode, bypass the cache so the notice appears immediately.\n forceCheck: this.isDebug\n });\n const updateCheckPromise: Promise<IPackageUpdateResult | undefined> = updateChecker.tryGetUpdateAsync();\n\n const PORT: number = 8091;\n // Must not have a trailing slash\n const SERVICE_URL: string = `http://localhost:${PORT}`;\n\n const appState: IAppState = init({\n appVersion: LFX_VERSION,\n debugMode: this.isDebug,\n subspaceName: this._subspaceParameter.value\n });\n\n const lfxWorkspace: IJsonLfxWorkspace = appState.lfxWorkspace;\n\n // Important: This must happen after init() reads the current working directory\n process.chdir(appState.lockfileExplorerProjectRoot);\n\n const distFolderPath: string = `${appState.lockfileExplorerProjectRoot}/dist`;\n const app: express.Application = express();\n app.use(express.json());\n app.use(cors());\n\n // Variable used to check if the front-end client is still connected\n let awaitingFirstConnect: boolean = true;\n let isClientConnected: boolean = false;\n let disconnected: boolean = false;\n setInterval(() => {\n if (!isClientConnected && !awaitingFirstConnect && !disconnected) {\n terminal.writeLine(Colorize.red('The client has disconnected!'));\n terminal.writeLine(`Please open a browser window at http://localhost:${PORT}/app`);\n disconnected = true;\n } else if (!awaitingFirstConnect) {\n isClientConnected = false;\n }\n }, 4000);\n\n // This takes precedence over the `/app` static route, which also has an `initappcontext.js` file.\n app.get('/initappcontext.js', (req: express.Request, res: express.Response) => {\n const appContext: IAppContext = {\n serviceUrl: SERVICE_URL,\n appVersion: appState.appVersion,\n debugMode: this.isDebug\n };\n const sourceCode: string = [\n `console.log('Loaded initappcontext.js');`,\n `appContext = ${JSON.stringify(appContext)}`\n ].join('\\n');\n\n res.type('application/javascript').send(sourceCode);\n });\n\n app.use('/', express.static(distFolderPath));\n\n app.use('/favicon.ico', express.static(distFolderPath, { index: 'favicon.ico' }));\n\n app.get('/api/health', (req: express.Request, res: express.Response) => {\n awaitingFirstConnect = false;\n isClientConnected = true;\n if (disconnected) {\n disconnected = false;\n terminal.writeLine(Colorize.green('The client has reconnected!'));\n }\n res.status(200).send();\n });\n\n app.get('/api/graph', async (req: express.Request, res: express.Response) => {\n const pnpmLockfileText: string = await FileSystem.readFileAsync(appState.pnpmLockfileLocation);\n const lockfile: unknown = yaml.load(pnpmLockfileText) as unknown;\n\n const graph: LfxGraph = lfxGraphLoader.generateLockfileGraph(lockfile, lfxWorkspace);\n\n const jsonGraph: IJsonLfxGraph = lfxGraphSerializer.serializeToJson(graph);\n res.type('application/json').send(jsonGraph);\n });\n\n app.post(\n '/api/package-json',\n async (req: express.Request<{}, {}, { projectPath: string }, {}>, res: express.Response) => {\n const { projectPath } = req.body;\n const fileLocation: string = `${appState.projectRoot}/${projectPath}/package.json`;\n let packageJsonText: string;\n try {\n packageJsonText = await FileSystem.readFileAsync(fileLocation);\n } catch (e) {\n if (FileSystem.isNotExistError(e)) {\n return res.status(404).send({\n message: `Could not load package.json file for this package. Have you installed all the dependencies for this workspace?`,\n error: `No package.json in location: ${projectPath}`\n });\n } else {\n throw e;\n }\n }\n\n res.send(packageJsonText);\n }\n );\n\n app.get('/api/pnpmfile', async (req: express.Request, res: express.Response) => {\n const pnpmfilePath: string = lockfilePath.join(\n lfxWorkspace.workspaceRootFullPath,\n lfxWorkspace.rushConfig?.rushPnpmfilePath ?? lfxWorkspace.pnpmfilePath\n );\n\n let pnpmfile: string;\n try {\n pnpmfile = await FileSystem.readFileAsync(pnpmfilePath);\n } catch (e) {\n if (FileSystem.isNotExistError(e)) {\n return res.status(404).send({\n message: `Could not load .pnpmfile.cjs file in this repo: \"${pnpmfilePath}\"`,\n error: `No .pnpmifile.cjs found.`\n });\n } else {\n throw e;\n }\n }\n\n res.send(pnpmfile);\n });\n\n app.post(\n '/api/package-spec',\n async (req: express.Request<{}, {}, { projectPath: string }, {}>, res: express.Response) => {\n const { projectPath } = req.body;\n const fileLocation: string = `${appState.projectRoot}/${projectPath}/package.json`;\n let packageJson: IPackageJson;\n try {\n packageJson = await JsonFile.loadAsync(fileLocation);\n } catch (e) {\n if (FileSystem.isNotExistError(e)) {\n return res.status(404).send({\n message: `Could not load package.json file in location: ${projectPath}`\n });\n } else {\n throw e;\n }\n }\n\n let parsedPackage: IPackageJson = packageJson;\n\n const pnpmfilePath: string = path.join(lfxWorkspace.workspaceRootFullPath, lfxWorkspace.pnpmfilePath);\n if (await FileSystem.existsAsync(pnpmfilePath)) {\n const pnpmFileRunner: PnpmfileRunner = new PnpmfileRunner(pnpmfilePath);\n try {\n parsedPackage = await pnpmFileRunner.transformPackageAsync(packageJson, fileLocation);\n } finally {\n await pnpmFileRunner.disposeAsync();\n }\n }\n\n res.send(parsedPackage);\n }\n );\n\n app.listen(PORT, async () => {\n terminal.writeLine(`App launched on ${SERVICE_URL}`);\n\n printUpdateNotification(await updateCheckPromise, terminal);\n\n if (!appState.debugMode) {\n try {\n // Launch the default web browser using the platform-native open command.\n let browserCmd: string;\n let browserArgs: string[];\n switch (process.platform) {\n case 'win32': {\n // \"start\" is a cmd.exe built-in, not a standalone executable.\n // The empty string is the required [title] argument; without it,\n // cmd interprets the URL as the title and ignores it.\n browserCmd = 'cmd';\n browserArgs = ['/c', 'start', '', SERVICE_URL];\n break;\n }\n\n case 'darwin': {\n browserCmd = 'open';\n browserArgs = [SERVICE_URL];\n break;\n }\n\n default: {\n // Linux and other Unix-like systems\n browserCmd = 'xdg-open';\n browserArgs = [SERVICE_URL];\n break;\n }\n }\n\n const browserProcess: ChildProcess = Executable.spawn(browserCmd, browserArgs, { stdio: 'ignore' });\n // Detach from our Node.js process so the browser stays open after we exit\n browserProcess.unref();\n } catch (e) {\n terminal.writeError('Error launching browser: ' + e.toString());\n }\n }\n });\n }\n}\n"]}
@@ -1,31 +1,28 @@
1
1
  // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
2
  // See LICENSE in the project root for license information.
3
- import { ConsoleTerminalProvider, Terminal, Colorize } from '@rushstack/terminal';
3
+ import { Colorize } from '@rushstack/terminal';
4
4
  import { CommandLineParser } from '@rushstack/ts-command-line';
5
- import { JsonFile, PackageJsonLookup } from '@rushstack/node-core-library';
6
5
  import { InitAction } from './actions/InitAction';
7
6
  import { CheckAction } from './actions/CheckAction';
7
+ import { LFX_VERSION } from '../../utils/constants';
8
8
  const LINT_TOOL_FILENAME = 'lockfile-lint';
9
9
  export class LintCommandLineParser extends CommandLineParser {
10
- constructor() {
10
+ constructor(terminal) {
11
11
  super({
12
12
  toolFilename: LINT_TOOL_FILENAME,
13
13
  toolDescription: 'Lockfile Lint applies configured policies to find and report dependency issues in your PNPM workspace.'
14
14
  });
15
- this._terminalProvider = new ConsoleTerminalProvider();
16
- this.globalTerminal = new Terminal(this._terminalProvider);
15
+ this.globalTerminal = terminal;
17
16
  this._populateActions();
18
17
  }
19
18
  async onExecuteAsync() {
20
- const lockfileExplorerProjectRoot = PackageJsonLookup.instance.tryGetPackageFolderFor(__dirname);
21
- const lockfileExplorerPackageJson = JsonFile.load(`${lockfileExplorerProjectRoot}/package.json`);
22
- const appVersion = lockfileExplorerPackageJson.version;
23
- this.globalTerminal.writeLine(Colorize.bold(`\nRush Lockfile Lint ${appVersion}`) + Colorize.cyan(' - https://lfx.rushstack.io/\n'));
19
+ this.globalTerminal.writeLine(Colorize.bold(`\nRush Lockfile Lint ${LFX_VERSION}`) + Colorize.cyan(' - https://lfx.rushstack.io/\n'));
24
20
  await super.onExecuteAsync();
25
21
  }
26
22
  _populateActions() {
27
- this.addAction(new InitAction(this));
28
- this.addAction(new CheckAction(this));
23
+ const terminal = this.globalTerminal;
24
+ this.addAction(new InitAction(terminal));
25
+ this.addAction(new CheckAction(terminal));
29
26
  }
30
27
  }
31
28
  //# sourceMappingURL=LintCommandLineParser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LintCommandLineParser.js","sourceRoot":"","sources":["../../../src/cli/lint/LintCommandLineParser.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,EAAE,uBAAuB,EAAkB,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAqB,QAAQ,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAE9F,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,kBAAkB,GAAoB,eAAe,CAAC;AAE5D,MAAM,OAAO,qBAAsB,SAAQ,iBAAiB;IAI1D;QACE,KAAK,CAAC;YACJ,YAAY,EAAE,kBAAkB;YAChC,eAAe,EACb,wGAAwG;SAC3G,CAAC,CAAC;QAEH,IAAI,CAAC,iBAAiB,GAAG,IAAI,uBAAuB,EAAE,CAAC;QACvD,IAAI,CAAC,cAAc,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAE3D,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAEkB,KAAK,CAAC,cAAc;QACrC,MAAM,2BAA2B,GAAW,iBAAiB,CAAC,QAAQ,CAAC,sBAAsB,CAAC,SAAS,CAAE,CAAC;QAC1G,MAAM,2BAA2B,GAAiB,QAAQ,CAAC,IAAI,CAC7D,GAAG,2BAA2B,eAAe,CAC9C,CAAC;QACF,MAAM,UAAU,GAAW,2BAA2B,CAAC,OAAO,CAAC;QAE/D,IAAI,CAAC,cAAc,CAAC,SAAS,CAC3B,QAAQ,CAAC,IAAI,CAAC,wBAAwB,UAAU,EAAE,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,gCAAgC,CAAC,CACtG,CAAC;QAEF,MAAM,KAAK,CAAC,cAAc,EAAE,CAAC;IAC/B,CAAC;IAEO,gBAAgB;QACtB,IAAI,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IACxC,CAAC;CACF","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, type ITerminal, Terminal, Colorize } from '@rushstack/terminal';\nimport { CommandLineParser } from '@rushstack/ts-command-line';\nimport { type IPackageJson, JsonFile, PackageJsonLookup } from '@rushstack/node-core-library';\n\nimport { InitAction } from './actions/InitAction';\nimport { CheckAction } from './actions/CheckAction';\n\nconst LINT_TOOL_FILENAME: 'lockfile-lint' = 'lockfile-lint';\n\nexport class LintCommandLineParser extends CommandLineParser {\n public readonly globalTerminal: ITerminal;\n private readonly _terminalProvider: ConsoleTerminalProvider;\n\n public constructor() {\n super({\n toolFilename: LINT_TOOL_FILENAME,\n toolDescription:\n 'Lockfile Lint applies configured policies to find and report dependency issues in your PNPM workspace.'\n });\n\n this._terminalProvider = new ConsoleTerminalProvider();\n this.globalTerminal = new Terminal(this._terminalProvider);\n\n this._populateActions();\n }\n\n protected override async onExecuteAsync(): Promise<void> {\n const lockfileExplorerProjectRoot: string = PackageJsonLookup.instance.tryGetPackageFolderFor(__dirname)!;\n const lockfileExplorerPackageJson: IPackageJson = JsonFile.load(\n `${lockfileExplorerProjectRoot}/package.json`\n );\n const appVersion: string = lockfileExplorerPackageJson.version;\n\n this.globalTerminal.writeLine(\n Colorize.bold(`\\nRush Lockfile Lint ${appVersion}`) + Colorize.cyan(' - https://lfx.rushstack.io/\\n')\n );\n\n await super.onExecuteAsync();\n }\n\n private _populateActions(): void {\n this.addAction(new InitAction(this));\n this.addAction(new CheckAction(this));\n }\n}\n"]}
1
+ {"version":3,"file":"LintCommandLineParser.js","sourceRoot":"","sources":["../../../src/cli/lint/LintCommandLineParser.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,EAAkB,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,kBAAkB,GAAoB,eAAe,CAAC;AAE5D,MAAM,OAAO,qBAAsB,SAAQ,iBAAiB;IAG1D,YAAmB,QAAmB;QACpC,KAAK,CAAC;YACJ,YAAY,EAAE,kBAAkB;YAChC,eAAe,EACb,wGAAwG;SAC3G,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC;QAE/B,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAEkB,KAAK,CAAC,cAAc;QACrC,IAAI,CAAC,cAAc,CAAC,SAAS,CAC3B,QAAQ,CAAC,IAAI,CAAC,wBAAwB,WAAW,EAAE,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,gCAAgC,CAAC,CACvG,CAAC;QAEF,MAAM,KAAK,CAAC,cAAc,EAAE,CAAC;IAC/B,CAAC;IAEO,gBAAgB;QACtB,MAAM,QAAQ,GAAc,IAAI,CAAC,cAAc,CAAC;QAChD,IAAI,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,SAAS,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC5C,CAAC;CACF","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 { type ITerminal, Colorize } from '@rushstack/terminal';\nimport { CommandLineParser } from '@rushstack/ts-command-line';\n\nimport { InitAction } from './actions/InitAction';\nimport { CheckAction } from './actions/CheckAction';\nimport { LFX_VERSION } from '../../utils/constants';\n\nconst LINT_TOOL_FILENAME: 'lockfile-lint' = 'lockfile-lint';\n\nexport class LintCommandLineParser extends CommandLineParser {\n public readonly globalTerminal: ITerminal;\n\n public constructor(terminal: ITerminal) {\n super({\n toolFilename: LINT_TOOL_FILENAME,\n toolDescription:\n 'Lockfile Lint applies configured policies to find and report dependency issues in your PNPM workspace.'\n });\n\n this.globalTerminal = terminal;\n\n this._populateActions();\n }\n\n protected override async onExecuteAsync(): Promise<void> {\n this.globalTerminal.writeLine(\n Colorize.bold(`\\nRush Lockfile Lint ${LFX_VERSION}`) + Colorize.cyan(' - https://lfx.rushstack.io/\\n')\n );\n\n await super.onExecuteAsync();\n }\n\n private _populateActions(): void {\n const terminal: ITerminal = this.globalTerminal;\n this.addAction(new InitAction(terminal));\n this.addAction(new CheckAction(terminal));\n }\n}\n"]}
@@ -11,7 +11,7 @@ import lockfileLintSchema from '../../../schemas/lockfile-lint.schema.json';
11
11
  import { LOCKFILE_EXPLORER_FOLDERNAME, LOCKFILE_LINT_JSON_FILENAME } from '../../../constants/common';
12
12
  import { getShrinkwrapFileMajorVersion, parseDependencyPath, splicePackageWithVersion } from '../../../utils/shrinkwrap';
13
13
  export class CheckAction extends CommandLineAction {
14
- constructor(parser) {
14
+ constructor(terminal) {
15
15
  super({
16
16
  actionName: 'check',
17
17
  summary: 'Check and report dependency issues in your workspace',
@@ -19,7 +19,7 @@ export class CheckAction extends CommandLineAction {
19
19
  LOCKFILE_LINT_JSON_FILENAME +
20
20
  ', reporting any problems found in your PNPM workspace.'
21
21
  });
22
- this._terminal = parser.globalTerminal;
22
+ this._terminal = terminal;
23
23
  this._checkedProjects = new Set();
24
24
  this._docMap = new Map();
25
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CheckAction.js","sourceRoot":"","sources":["../../../../src/cli/lint/actions/CheckAction.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 path from 'node:path';\n\nimport yaml from 'js-yaml';\nimport semver from 'semver';\nimport type * as lockfileTypes from '@pnpm/lockfile.types';\nimport type * as pnpmTypes from '@pnpm/types';\n\nimport { RushConfiguration, type RushConfigurationProject, type Subspace } from '@rushstack/rush-sdk';\nimport { CommandLineAction } from '@rushstack/ts-command-line';\nimport { Colorize, type ITerminal } from '@rushstack/terminal';\nimport { AlreadyReportedError, Async, FileSystem, JsonFile, JsonSchema } from '@rushstack/node-core-library';\n\nimport lockfileLintSchema from '../../../schemas/lockfile-lint.schema.json';\nimport { LOCKFILE_EXPLORER_FOLDERNAME, LOCKFILE_LINT_JSON_FILENAME } from '../../../constants/common';\nimport type { LintCommandLineParser } from '../LintCommandLineParser';\nimport {\n getShrinkwrapFileMajorVersion,\n parseDependencyPath,\n splicePackageWithVersion\n} from '../../../utils/shrinkwrap';\n\nexport interface ILintRule {\n rule: 'restrict-versions';\n project: string;\n requiredVersions: Record<string, string>;\n}\n\nexport interface ILockfileLint {\n rules: ILintRule[];\n}\n\nexport interface ILintIssue {\n project: string;\n rule: string;\n message: string;\n}\n\nexport class CheckAction extends CommandLineAction {\n private readonly _terminal: ITerminal;\n\n private _rushConfiguration!: RushConfiguration;\n private _checkedProjects: Set<RushConfigurationProject>;\n private _docMap: Map<string, lockfileTypes.LockfileObject>;\n\n public constructor(parser: LintCommandLineParser) {\n super({\n actionName: 'check',\n summary: 'Check and report dependency issues in your workspace',\n documentation:\n 'This command applies the policies that are configured in ' +\n LOCKFILE_LINT_JSON_FILENAME +\n ', reporting any problems found in your PNPM workspace.'\n });\n\n this._terminal = parser.globalTerminal;\n this._checkedProjects = new Set();\n this._docMap = new Map();\n }\n\n private async _checkVersionCompatibilityAsync(\n shrinkwrapFileMajorVersion: number,\n packages: lockfileTypes.PackageSnapshots | undefined,\n dependencyPath: pnpmTypes.DepPath,\n requiredVersions: Record<string, string>,\n checkedDependencyPaths: Set<string>\n ): Promise<void> {\n if (packages && packages[dependencyPath] && !checkedDependencyPaths.has(dependencyPath)) {\n checkedDependencyPaths.add(dependencyPath);\n const { name, version } = parseDependencyPath(shrinkwrapFileMajorVersion, dependencyPath);\n if (name in requiredVersions && !semver.satisfies(version, requiredVersions[name])) {\n throw new Error(\n `The version of \"${name}\" should match \"${requiredVersions[name]}\";` +\n ` actual version is \"${version}\"`\n );\n }\n\n await Promise.all(\n Object.entries(packages[dependencyPath].dependencies ?? {}).map(\n async ([dependencyPackageName, dependencyPackageVersion]) => {\n await this._checkVersionCompatibilityAsync(\n shrinkwrapFileMajorVersion,\n packages,\n splicePackageWithVersion(\n shrinkwrapFileMajorVersion,\n dependencyPackageName,\n dependencyPackageVersion\n ) as pnpmTypes.DepPath,\n requiredVersions,\n checkedDependencyPaths\n );\n }\n )\n );\n }\n }\n\n private async _searchAndValidateDependenciesAsync(\n project: RushConfigurationProject,\n requiredVersions: Record<string, string>\n ): Promise<void> {\n this._terminal.writeLine(`Checking project \"${project.packageName}\"`);\n\n const projectFolder: string = project.projectFolder;\n const subspace: Subspace = project.subspace;\n const shrinkwrapFilename: string = subspace.getCommittedShrinkwrapFilePath();\n let doc: lockfileTypes.LockfileObject;\n if (this._docMap.has(shrinkwrapFilename)) {\n doc = this._docMap.get(shrinkwrapFilename)!;\n } else {\n const pnpmLockfileText: string = await FileSystem.readFileAsync(shrinkwrapFilename);\n doc = yaml.load(pnpmLockfileText) as lockfileTypes.LockfileObject;\n this._docMap.set(shrinkwrapFilename, doc);\n }\n const { importers, lockfileVersion, packages } = doc;\n const shrinkwrapFileMajorVersion: number = getShrinkwrapFileMajorVersion(lockfileVersion);\n const checkedDependencyPaths: Set<string> = new Set<string>();\n\n await Promise.all(\n Object.entries(importers).map(async ([relativePath, { dependencies }]) => {\n if (path.resolve(projectFolder, relativePath) === projectFolder) {\n const dependenciesEntries: [string, unknown][] = Object.entries(dependencies ?? {});\n for (const [dependencyName, dependencyValue] of dependenciesEntries) {\n const fullDependencyPath: pnpmTypes.DepPath = splicePackageWithVersion(\n shrinkwrapFileMajorVersion,\n dependencyName,\n typeof dependencyValue === 'string'\n ? dependencyValue\n : (\n dependencyValue as {\n version: string;\n specifier: string;\n }\n ).version\n ) as pnpmTypes.DepPath;\n if (fullDependencyPath.includes('link:')) {\n const dependencyProject: RushConfigurationProject | undefined =\n this._rushConfiguration.getProjectByName(dependencyName);\n if (dependencyProject && !this._checkedProjects?.has(dependencyProject)) {\n this._checkedProjects!.add(project);\n await this._searchAndValidateDependenciesAsync(dependencyProject, requiredVersions);\n }\n } else {\n await this._checkVersionCompatibilityAsync(\n shrinkwrapFileMajorVersion,\n packages,\n fullDependencyPath,\n requiredVersions,\n checkedDependencyPaths\n );\n }\n }\n }\n })\n );\n }\n\n private async _performVersionRestrictionCheckAsync(\n requiredVersions: Record<string, string>,\n projectName: string\n ): Promise<string | undefined> {\n try {\n const project: RushConfigurationProject | undefined =\n this._rushConfiguration?.getProjectByName(projectName);\n if (!project) {\n throw new Error(\n `Specified project \"${projectName}\" does not exist in ${LOCKFILE_LINT_JSON_FILENAME}`\n );\n }\n this._checkedProjects.add(project);\n await this._searchAndValidateDependenciesAsync(project, requiredVersions);\n return undefined;\n } catch (e) {\n return e.message;\n }\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 this._rushConfiguration = rushConfiguration!;\n\n const lintingFile: string = path.resolve(\n this._rushConfiguration.commonFolder,\n 'config',\n LOCKFILE_EXPLORER_FOLDERNAME,\n LOCKFILE_LINT_JSON_FILENAME\n );\n const { rules }: ILockfileLint = await JsonFile.loadAndValidateAsync(\n lintingFile,\n JsonSchema.fromLoadedObject(lockfileLintSchema)\n );\n const issues: ILintIssue[] = [];\n await Async.forEachAsync(\n rules,\n async ({ requiredVersions, project, rule }) => {\n switch (rule) {\n case 'restrict-versions': {\n const message: string | undefined = await this._performVersionRestrictionCheckAsync(\n requiredVersions,\n project\n );\n if (message) {\n issues.push({ project, rule, message });\n }\n break;\n }\n\n default: {\n throw new Error('Unsupported rule name: ' + rule);\n }\n }\n },\n { concurrency: 50 }\n );\n if (issues.length > 0) {\n this._terminal.writeLine();\n\n // Deterministic order\n for (const issue of issues.sort((a, b): number => {\n let diff: number = a.project.localeCompare(b.project);\n if (diff !== 0) {\n return diff;\n }\n diff = a.rule.localeCompare(b.rule);\n if (diff !== 0) {\n return diff;\n }\n return a.message.localeCompare(b.message);\n })) {\n this._terminal.writeLine(\n Colorize.red('PROBLEM: ') + Colorize.cyan(`[${issue.rule}] `) + issue.message + '\\n'\n );\n }\n\n throw new AlreadyReportedError();\n }\n this._terminal.writeLine(Colorize.green('SUCCESS: ') + 'All checks passed.');\n }\n}\n"]}
1
+ {"version":3,"file":"CheckAction.js","sourceRoot":"","sources":["../../../../src/cli/lint/actions/CheckAction.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 path from 'node:path';\n\nimport yaml from 'js-yaml';\nimport semver from 'semver';\nimport type * as lockfileTypes from '@pnpm/lockfile.types';\nimport type * as pnpmTypes from '@pnpm/types';\n\nimport { RushConfiguration, type RushConfigurationProject, type Subspace } from '@rushstack/rush-sdk';\nimport { CommandLineAction } from '@rushstack/ts-command-line';\nimport { Colorize, type ITerminal } from '@rushstack/terminal';\nimport { AlreadyReportedError, Async, FileSystem, JsonFile, JsonSchema } from '@rushstack/node-core-library';\n\nimport lockfileLintSchema from '../../../schemas/lockfile-lint.schema.json';\nimport { LOCKFILE_EXPLORER_FOLDERNAME, LOCKFILE_LINT_JSON_FILENAME } from '../../../constants/common';\nimport {\n getShrinkwrapFileMajorVersion,\n parseDependencyPath,\n splicePackageWithVersion\n} from '../../../utils/shrinkwrap';\n\nexport interface ILintRule {\n rule: 'restrict-versions';\n project: string;\n requiredVersions: Record<string, string>;\n}\n\nexport interface ILockfileLint {\n rules: ILintRule[];\n}\n\nexport interface ILintIssue {\n project: string;\n rule: string;\n message: string;\n}\n\nexport class CheckAction extends CommandLineAction {\n private readonly _terminal: ITerminal;\n\n private _rushConfiguration!: RushConfiguration;\n private _checkedProjects: Set<RushConfigurationProject>;\n private _docMap: Map<string, lockfileTypes.LockfileObject>;\n\n public constructor(terminal: ITerminal) {\n super({\n actionName: 'check',\n summary: 'Check and report dependency issues in your workspace',\n documentation:\n 'This command applies the policies that are configured in ' +\n LOCKFILE_LINT_JSON_FILENAME +\n ', reporting any problems found in your PNPM workspace.'\n });\n\n this._terminal = terminal;\n this._checkedProjects = new Set();\n this._docMap = new Map();\n }\n\n private async _checkVersionCompatibilityAsync(\n shrinkwrapFileMajorVersion: number,\n packages: lockfileTypes.PackageSnapshots | undefined,\n dependencyPath: pnpmTypes.DepPath,\n requiredVersions: Record<string, string>,\n checkedDependencyPaths: Set<string>\n ): Promise<void> {\n if (packages && packages[dependencyPath] && !checkedDependencyPaths.has(dependencyPath)) {\n checkedDependencyPaths.add(dependencyPath);\n const { name, version } = parseDependencyPath(shrinkwrapFileMajorVersion, dependencyPath);\n if (name in requiredVersions && !semver.satisfies(version, requiredVersions[name])) {\n throw new Error(\n `The version of \"${name}\" should match \"${requiredVersions[name]}\";` +\n ` actual version is \"${version}\"`\n );\n }\n\n await Promise.all(\n Object.entries(packages[dependencyPath].dependencies ?? {}).map(\n async ([dependencyPackageName, dependencyPackageVersion]) => {\n await this._checkVersionCompatibilityAsync(\n shrinkwrapFileMajorVersion,\n packages,\n splicePackageWithVersion(\n shrinkwrapFileMajorVersion,\n dependencyPackageName,\n dependencyPackageVersion\n ) as pnpmTypes.DepPath,\n requiredVersions,\n checkedDependencyPaths\n );\n }\n )\n );\n }\n }\n\n private async _searchAndValidateDependenciesAsync(\n project: RushConfigurationProject,\n requiredVersions: Record<string, string>\n ): Promise<void> {\n this._terminal.writeLine(`Checking project \"${project.packageName}\"`);\n\n const projectFolder: string = project.projectFolder;\n const subspace: Subspace = project.subspace;\n const shrinkwrapFilename: string = subspace.getCommittedShrinkwrapFilePath();\n let doc: lockfileTypes.LockfileObject;\n if (this._docMap.has(shrinkwrapFilename)) {\n doc = this._docMap.get(shrinkwrapFilename)!;\n } else {\n const pnpmLockfileText: string = await FileSystem.readFileAsync(shrinkwrapFilename);\n doc = yaml.load(pnpmLockfileText) as lockfileTypes.LockfileObject;\n this._docMap.set(shrinkwrapFilename, doc);\n }\n const { importers, lockfileVersion, packages } = doc;\n const shrinkwrapFileMajorVersion: number = getShrinkwrapFileMajorVersion(lockfileVersion);\n const checkedDependencyPaths: Set<string> = new Set<string>();\n\n await Promise.all(\n Object.entries(importers).map(async ([relativePath, { dependencies }]) => {\n if (path.resolve(projectFolder, relativePath) === projectFolder) {\n const dependenciesEntries: [string, unknown][] = Object.entries(dependencies ?? {});\n for (const [dependencyName, dependencyValue] of dependenciesEntries) {\n const fullDependencyPath: pnpmTypes.DepPath = splicePackageWithVersion(\n shrinkwrapFileMajorVersion,\n dependencyName,\n typeof dependencyValue === 'string'\n ? dependencyValue\n : (\n dependencyValue as {\n version: string;\n specifier: string;\n }\n ).version\n ) as pnpmTypes.DepPath;\n if (fullDependencyPath.includes('link:')) {\n const dependencyProject: RushConfigurationProject | undefined =\n this._rushConfiguration.getProjectByName(dependencyName);\n if (dependencyProject && !this._checkedProjects?.has(dependencyProject)) {\n this._checkedProjects!.add(project);\n await this._searchAndValidateDependenciesAsync(dependencyProject, requiredVersions);\n }\n } else {\n await this._checkVersionCompatibilityAsync(\n shrinkwrapFileMajorVersion,\n packages,\n fullDependencyPath,\n requiredVersions,\n checkedDependencyPaths\n );\n }\n }\n }\n })\n );\n }\n\n private async _performVersionRestrictionCheckAsync(\n requiredVersions: Record<string, string>,\n projectName: string\n ): Promise<string | undefined> {\n try {\n const project: RushConfigurationProject | undefined =\n this._rushConfiguration?.getProjectByName(projectName);\n if (!project) {\n throw new Error(\n `Specified project \"${projectName}\" does not exist in ${LOCKFILE_LINT_JSON_FILENAME}`\n );\n }\n this._checkedProjects.add(project);\n await this._searchAndValidateDependenciesAsync(project, requiredVersions);\n return undefined;\n } catch (e) {\n return e.message;\n }\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 this._rushConfiguration = rushConfiguration!;\n\n const lintingFile: string = path.resolve(\n this._rushConfiguration.commonFolder,\n 'config',\n LOCKFILE_EXPLORER_FOLDERNAME,\n LOCKFILE_LINT_JSON_FILENAME\n );\n const { rules }: ILockfileLint = await JsonFile.loadAndValidateAsync(\n lintingFile,\n JsonSchema.fromLoadedObject(lockfileLintSchema)\n );\n const issues: ILintIssue[] = [];\n await Async.forEachAsync(\n rules,\n async ({ requiredVersions, project, rule }) => {\n switch (rule) {\n case 'restrict-versions': {\n const message: string | undefined = await this._performVersionRestrictionCheckAsync(\n requiredVersions,\n project\n );\n if (message) {\n issues.push({ project, rule, message });\n }\n break;\n }\n\n default: {\n throw new Error('Unsupported rule name: ' + rule);\n }\n }\n },\n { concurrency: 50 }\n );\n if (issues.length > 0) {\n this._terminal.writeLine();\n\n // Deterministic order\n for (const issue of issues.sort((a, b): number => {\n let diff: number = a.project.localeCompare(b.project);\n if (diff !== 0) {\n return diff;\n }\n diff = a.rule.localeCompare(b.rule);\n if (diff !== 0) {\n return diff;\n }\n return a.message.localeCompare(b.message);\n })) {\n this._terminal.writeLine(\n Colorize.red('PROBLEM: ') + Colorize.cyan(`[${issue.rule}] `) + issue.message + '\\n'\n );\n }\n\n throw new AlreadyReportedError();\n }\n this._terminal.writeLine(Colorize.green('SUCCESS: ') + 'All checks passed.');\n }\n}\n"]}
@@ -7,14 +7,14 @@ import { RushConfiguration } from '@rushstack/rush-sdk';
7
7
  import { FileSystem } from '@rushstack/node-core-library';
8
8
  import { LOCKFILE_EXPLORER_FOLDERNAME, LOCKFILE_LINT_JSON_FILENAME } from '../../../constants/common';
9
9
  export class InitAction extends CommandLineAction {
10
- constructor(parser) {
10
+ constructor(terminal) {
11
11
  super({
12
12
  actionName: 'init',
13
13
  summary: `Create a new ${LOCKFILE_LINT_JSON_FILENAME} config file`,
14
14
  documentation: `This command initializes a new ${LOCKFILE_LINT_JSON_FILENAME} config file.` +
15
15
  ` The created template file includes source code comments that document the settings.`
16
16
  });
17
- this._terminal = parser.globalTerminal;
17
+ this._terminal = terminal;
18
18
  }
19
19
  async onExecuteAsync() {
20
20
  const rushConfiguration = 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,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAkB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAG1D,OAAO,EAAE,4BAA4B,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAEtG,MAAM,OAAO,UAAW,SAAQ,iBAAiB;IAG/C,YAAmB,MAA6B;QAC9C,KAAK,CAAC;YACJ,UAAU,EAAE,MAAM;YAClB,OAAO,EAAE,gBAAgB,2BAA2B,cAAc;YAClE,aAAa,EACX,kCAAkC,2BAA2B,eAAe;gBAC5E,uFAAuF;SAC1F,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC;IACzC,CAAC;IAEkB,KAAK,CAAC,cAAc;QACrC,MAAM,iBAAiB,GAAkC,iBAAiB,CAAC,0BAA0B,EAAE,CAAC;QACxG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,kGAAkG,CACnG,CAAC;QACJ,CAAC;QACD,MAAM,aAAa,GAAW,IAAI,CAAC,OAAO,CACxC,SAAS,EACT,uDAAuD,CACxD,CAAC;QACF,MAAM,cAAc,GAAW,IAAI,CAAC,OAAO,CACzC,iBAAiB,CAAC,YAAY,EAC9B,QAAQ,EACR,4BAA4B,EAC5B,2BAA2B,CAC5B,CAAC;QAEF,IAAI,MAAM,UAAU,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,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,cAAc,CAAC,CAAC;QAC5E,MAAM,UAAU,CAAC,aAAa,CAAC;YAC7B,UAAU,EAAE,aAAa;YACzB,eAAe,EAAE,cAAc;SAChC,CAAC,CAAC;IACL,CAAC;CACF","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 type { LintCommandLineParser } from '../LintCommandLineParser';\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(parser: LintCommandLineParser) {\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 = parser.globalTerminal;\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"]}
1
+ {"version":3,"file":"InitAction.js","sourceRoot":"","sources":["../../../../src/cli/lint/actions/InitAction.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAkB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,OAAO,EAAE,4BAA4B,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAEtG,MAAM,OAAO,UAAW,SAAQ,iBAAiB;IAG/C,YAAmB,QAAmB;QACpC,KAAK,CAAC;YACJ,UAAU,EAAE,MAAM;YAClB,OAAO,EAAE,gBAAgB,2BAA2B,cAAc;YAClE,aAAa,EACX,kCAAkC,2BAA2B,eAAe;gBAC5E,uFAAuF;SAC1F,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAEkB,KAAK,CAAC,cAAc;QACrC,MAAM,iBAAiB,GAAkC,iBAAiB,CAAC,0BAA0B,EAAE,CAAC;QACxG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,kGAAkG,CACnG,CAAC;QACJ,CAAC;QACD,MAAM,aAAa,GAAW,IAAI,CAAC,OAAO,CACxC,SAAS,EACT,uDAAuD,CACxD,CAAC;QACF,MAAM,cAAc,GAAW,IAAI,CAAC,OAAO,CACzC,iBAAiB,CAAC,YAAY,EAC9B,QAAQ,EACR,4BAA4B,EAC5B,2BAA2B,CAC5B,CAAC;QAEF,IAAI,MAAM,UAAU,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,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,cAAc,CAAC,CAAC;QAC5E,MAAM,UAAU,CAAC,aAAa,CAAC;YAC7B,UAAU,EAAE,aAAa;YACzB,eAAe,EAAE,cAAc;SAChC,CAAC,CAAC;IACL,CAAC;CACF","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"]}
@@ -1,6 +1,8 @@
1
1
  // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
2
  // See LICENSE in the project root for license information.
3
+ import { ConsoleTerminalProvider, Terminal } from '@rushstack/terminal/lib/index';
3
4
  import { ExplorerCommandLineParser } from './cli/explorer/ExplorerCommandLineParser';
4
- const parser = new ExplorerCommandLineParser();
5
+ const terminal = new Terminal(new ConsoleTerminalProvider());
6
+ const parser = new ExplorerCommandLineParser(terminal);
5
7
  parser.executeAsync().catch(console.error); // CommandLineParser.executeAsync() should never reject the promise
6
8
  //# 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,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAErF,MAAM,MAAM,GAA8B,IAAI,yBAAyB,EAAE,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 { ExplorerCommandLineParser } from './cli/explorer/ExplorerCommandLineParser';\n\nconst parser: ExplorerCommandLineParser = new ExplorerCommandLineParser();\n\nparser.executeAsync().catch(console.error); // CommandLineParser.executeAsync() should never reject the promise\n"]}
1
+ {"version":3,"file":"start-explorer.js","sourceRoot":"","sources":["../src/start-explorer.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,EAAE,uBAAuB,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAElF,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAErF,MAAM,QAAQ,GAAa,IAAI,QAAQ,CAAC,IAAI,uBAAuB,EAAE,CAAC,CAAC;AACvE,MAAM,MAAM,GAA8B,IAAI,yBAAyB,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"]}
@@ -1,6 +1,8 @@
1
1
  // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
2
  // See LICENSE in the project root for license information.
3
+ import { ConsoleTerminalProvider, Terminal } from '@rushstack/terminal/lib/index';
3
4
  import { LintCommandLineParser } from './cli/lint/LintCommandLineParser';
4
- const parser = new LintCommandLineParser();
5
+ const terminal = new Terminal(new ConsoleTerminalProvider());
6
+ const parser = new LintCommandLineParser(terminal);
5
7
  parser.executeAsync().catch(console.error); // CommandLineParser.executeAsync() should never reject the promise
6
8
  //# 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,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,MAAM,MAAM,GAA0B,IAAI,qBAAqB,EAAE,CAAC;AAElE,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 { LintCommandLineParser } from './cli/lint/LintCommandLineParser';\n\nconst parser: LintCommandLineParser = new LintCommandLineParser();\n\nparser.executeAsync().catch(console.error); // CommandLineParser.executeAsync() should never reject the promise\n"]}
1
+ {"version":3,"file":"start-lint.js","sourceRoot":"","sources":["../src/start-lint.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,EAAE,uBAAuB,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAElF,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,MAAM,QAAQ,GAAa,IAAI,QAAQ,CAAC,IAAI,uBAAuB,EAAE,CAAC,CAAC;AACvE,MAAM,MAAM,GAA0B,IAAI,qBAAqB,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,113 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
+ // See LICENSE in the project root for license information.
3
+ import { homedir } from 'node:os';
4
+ import semver from 'semver';
5
+ import { JsonFile } from '@rushstack/node-core-library';
6
+ const REGISTRY_BASE_URL = 'https://registry.npmjs.org';
7
+ const FETCH_TIMEOUT_MS = 5000;
8
+ const DEFAULT_CACHE_EXPIRY_MS = 24 * 60 * 60 * 1000; // 24 hours
9
+ const CACHE_VERSION = 1;
10
+ const CACHE_FOLDER = `${homedir()}/.rushstack/update-checks`;
11
+ async function _tryFetchLatestVersionAsync(packageName) {
12
+ const url = `${REGISTRY_BASE_URL}/${encodeURIComponent(packageName)}/latest`;
13
+ const controller = new AbortController();
14
+ const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
15
+ try {
16
+ const response = await fetch(url, { signal: controller.signal });
17
+ if (!response.ok) {
18
+ return undefined;
19
+ }
20
+ const { version } = (await response.json());
21
+ return typeof version === 'string' ? version : undefined;
22
+ }
23
+ catch (_a) {
24
+ // Network errors, timeouts, and parse failures are all silent.
25
+ return undefined;
26
+ }
27
+ finally {
28
+ clearTimeout(timeout);
29
+ }
30
+ }
31
+ async function _readCacheAsync(filePath) {
32
+ try {
33
+ const data = await JsonFile.loadAsync(filePath);
34
+ const { cacheVersion, ...rest } = data;
35
+ if (cacheVersion === CACHE_VERSION) {
36
+ return rest;
37
+ }
38
+ }
39
+ catch (_a) {
40
+ // Ignore
41
+ }
42
+ }
43
+ async function _writeCacheAsync(filePath, cache) {
44
+ try {
45
+ const cacheData = {
46
+ cacheVersion: CACHE_VERSION,
47
+ checkedAt: Date.now(),
48
+ ...cache
49
+ };
50
+ await JsonFile.saveAsync(cacheData, filePath, {
51
+ ensureFolderExists: true
52
+ });
53
+ }
54
+ catch (_a) {
55
+ // Cache write failures are silent — a stale or missing cache just means
56
+ // we'll re-fetch on the next invocation.
57
+ }
58
+ }
59
+ /**
60
+ * Checks npm for a newer version of a package and caches the result locally so that
61
+ * the registry is not queried on every invocation.
62
+ *
63
+ * @internal
64
+ */
65
+ export class PackageUpdateChecker {
66
+ constructor(options) {
67
+ const { packageName, currentVersion, skip = false, forceCheck = false, cacheExpiryMs = DEFAULT_CACHE_EXPIRY_MS } = options;
68
+ this._packageName = packageName;
69
+ this._currentVersion = currentVersion;
70
+ this._skip = skip;
71
+ this._forceCheck = forceCheck;
72
+ this._cacheExpiryMs = cacheExpiryMs;
73
+ }
74
+ /**
75
+ * Performs the update check and returns the result, or `undefined` if the check
76
+ * was skipped or the registry could not be reached.
77
+ */
78
+ async tryGetUpdateAsync() {
79
+ if (this._skip) {
80
+ return undefined;
81
+ }
82
+ const cacheFilePath = this._getCacheFilePath();
83
+ let latestVersion;
84
+ if (!this._forceCheck) {
85
+ const cached = await _readCacheAsync(cacheFilePath);
86
+ if (cached !== undefined) {
87
+ const { checkedAt, latestVersion: latestVersionFromCache } = cached;
88
+ const ageMs = Date.now() - checkedAt;
89
+ if (ageMs < this._cacheExpiryMs) {
90
+ latestVersion = latestVersionFromCache;
91
+ }
92
+ }
93
+ }
94
+ if (latestVersion === undefined) {
95
+ // Cache is missing or stale — fetch from the registry.
96
+ latestVersion = await _tryFetchLatestVersionAsync(this._packageName);
97
+ if (latestVersion === undefined) {
98
+ return undefined;
99
+ }
100
+ await _writeCacheAsync(cacheFilePath, { latestVersion });
101
+ }
102
+ return {
103
+ latestVersion,
104
+ isOutdated: semver.gt(latestVersion, this._currentVersion)
105
+ };
106
+ }
107
+ _getCacheFilePath() {
108
+ // Replace characters that are unsafe in file names (e.g. the "/" in scoped package names).
109
+ const sanitizedName = this._packageName.replace(/[^a-zA-Z0-9._-]/g, '_');
110
+ return `${CACHE_FOLDER}/${sanitizedName}.json`;
111
+ }
112
+ }
113
+ //# 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,9 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
+ // See LICENSE in the project root for license information.
3
+ import { Path } from '@rushstack/node-core-library';
4
+ import lockfileExplorerPackageJson from '../../package.json';
5
+ export const { version: LFX_VERSION, name: LFX_PACKAGE_NAME } = lockfileExplorerPackageJson;
6
+ let _lfxPackageRoot = Path.convertToSlashes(__dirname);
7
+ _lfxPackageRoot = _lfxPackageRoot.slice(0, _lfxPackageRoot.lastIndexOf('/', _lfxPackageRoot.lastIndexOf('/') - 1));
8
+ export const LFX_PACKAGE_ROOT = Path.convertToPlatformDefault(_lfxPackageRoot);
9
+ //# 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,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAEpD,OAAO,2BAA2B,MAAM,oBAAoB,CAAC;AAE7D,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB,EAAE,GAAG,2BAA2B,CAAC;AAE5F,IAAI,eAAe,GAAW,IAAI,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;AACF,MAAM,CAAC,MAAM,gBAAgB,GAAW,IAAI,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"]}
@@ -6,8 +6,9 @@ import path from 'node:path';
6
6
  import { FileSystem, Path } from '@rushstack/node-core-library';
7
7
  import { RushConfiguration } from '@microsoft/rush-lib/lib/api/RushConfiguration';
8
8
  import * as lockfilePath from '../graph/lockfilePath';
9
+ import { LFX_PACKAGE_ROOT } from './constants';
9
10
  export const init = (options) => {
10
- const { lockfileExplorerProjectRoot, appVersion, debugMode, subspaceName } = options;
11
+ const { appVersion, debugMode, subspaceName } = options;
11
12
  const currentWorkingDirectory = path.resolve(process.cwd());
12
13
  let appState;
13
14
  let currentFolder = Path.convertToSlashes(currentWorkingDirectory);
@@ -30,7 +31,7 @@ export const init = (options) => {
30
31
  currentWorkingDirectory,
31
32
  appVersion,
32
33
  debugMode,
33
- lockfileExplorerProjectRoot,
34
+ lockfileExplorerProjectRoot: LFX_PACKAGE_ROOT,
34
35
  pnpmLockfileLocation: pnpmLockfileAbsolutePath,
35
36
  pnpmfileLocation: commonTempFolder + '/.pnpmfile.cjs',
36
37
  projectRoot: currentFolder,
@@ -53,7 +54,7 @@ export const init = (options) => {
53
54
  currentWorkingDirectory,
54
55
  appVersion,
55
56
  debugMode,
56
- lockfileExplorerProjectRoot,
57
+ lockfileExplorerProjectRoot: LFX_PACKAGE_ROOT,
57
58
  pnpmLockfileLocation: currentFolder + '/pnpm-lock.yaml',
58
59
  pnpmfileLocation: currentFolder + '/.pnpmfile.cjs',
59
60
  projectRoot: currentFolder,
@@ -1 +1 @@
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';\n\nexport const init = (options: {\n lockfileExplorerProjectRoot: string;\n appVersion: string;\n debugMode: boolean;\n subspaceName: string;\n}): Omit<IAppState, 'graph'> => {\n const { lockfileExplorerProjectRoot, 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,\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,\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"]}
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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rushstack/lockfile-explorer",
3
- "version": "2.2.17",
3
+ "version": "2.2.19",
4
4
  "description": "Rush Lockfile Explorer: The UI for solving version conflicts quickly in a large monorepo",
5
5
  "keywords": [
6
6
  "conflict",
@@ -42,14 +42,13 @@
42
42
  "@types/cors": "~2.8.12",
43
43
  "@types/express": "4.17.21",
44
44
  "@types/js-yaml": "4.0.9",
45
- "@types/update-notifier": "~6.0.1",
46
45
  "eslint": "~9.37.0",
47
46
  "@pnpm/lockfile.types": "1002.0.1",
48
47
  "@pnpm/types": "1000.8.0",
49
48
  "@types/semver": "7.7.1",
50
- "@rushstack/heft": "1.2.16",
51
- "@rushstack/lockfile-explorer-web": "0.0.0",
52
- "local-node-rig": "1.0.0"
49
+ "@rushstack/heft": "1.2.18",
50
+ "local-node-rig": "1.0.0",
51
+ "@rushstack/lockfile-explorer-web": "0.0.0"
53
52
  },
54
53
  "dependencies": {
55
54
  "tslib": "~2.8.1",
@@ -58,12 +57,11 @@
58
57
  "express": "4.21.1",
59
58
  "js-yaml": "~4.1.0",
60
59
  "semver": "~7.7.4",
61
- "update-notifier": "~5.1.0",
62
- "@microsoft/rush-lib": "5.175.0",
63
60
  "@rushstack/node-core-library": "5.23.1",
64
- "@rushstack/terminal": "0.23.0",
65
- "@rushstack/rush-sdk": "5.175.0",
66
- "@rushstack/ts-command-line": "5.3.8"
61
+ "@rushstack/rush-sdk": "5.175.1",
62
+ "@microsoft/rush-lib": "5.175.1",
63
+ "@rushstack/terminal": "0.24.0",
64
+ "@rushstack/ts-command-line": "5.3.9"
67
65
  },
68
66
  "exports": {
69
67
  "./lib/*.schema.json": "./lib-commonjs/*.schema.json",