From 65de92b55bfbe6e04441264214f0f02edbc687e2 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 20:48:43 -0700 Subject: [PATCH 01/26] Enable packlets mixin --- apps/lockfile-explorer-web/eslint.config.js | 2 ++ eslint/local-eslint-config/config/heft.json | 2 +- .../default/includes/eslint/flat/mixins/packlets.js | 6 ++++++ .../profiles/app/includes/eslint/flat/mixins/packlets.js | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 rigs/decoupled-local-node-rig/profiles/default/includes/eslint/flat/mixins/packlets.js diff --git a/apps/lockfile-explorer-web/eslint.config.js b/apps/lockfile-explorer-web/eslint.config.js index 4664e2044d7..9765c392aa3 100644 --- a/apps/lockfile-explorer-web/eslint.config.js +++ b/apps/lockfile-explorer-web/eslint.config.js @@ -3,10 +3,12 @@ const webAppProfile = require('local-web-rig/profiles/app/includes/eslint/flat/profile/web-app'); const reactMixin = require('local-web-rig/profiles/app/includes/eslint/flat/mixins/react'); +const packletsMixin = require('local-web-rig/profiles/app/includes/eslint/flat/mixins/packlets'); module.exports = [ ...webAppProfile, ...reactMixin, + packletsMixin, { files: ['**/*.ts', '**/*.tsx'], languageOptions: { diff --git a/eslint/local-eslint-config/config/heft.json b/eslint/local-eslint-config/config/heft.json index d4ccbea3f42..14fee0004b8 100644 --- a/eslint/local-eslint-config/config/heft.json +++ b/eslint/local-eslint-config/config/heft.json @@ -3,7 +3,7 @@ "phasesByName": { "build": { - "cleanFiles": [{ "includeGlobs": ["mixins", "patch", "profile"] }], + "cleanFiles": [{ "includeGlobs": ["flat/**"] }], "tasksByName": { "copy-contents": { diff --git a/rigs/decoupled-local-node-rig/profiles/default/includes/eslint/flat/mixins/packlets.js b/rigs/decoupled-local-node-rig/profiles/default/includes/eslint/flat/mixins/packlets.js new file mode 100644 index 00000000000..61892fd848d --- /dev/null +++ b/rigs/decoupled-local-node-rig/profiles/default/includes/eslint/flat/mixins/packlets.js @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +const packletsMixin = require('@rushstack/eslint-config/flat/mixins/packlets'); + +module.exports = { ...packletsMixin }; diff --git a/rigs/local-web-rig/profiles/app/includes/eslint/flat/mixins/packlets.js b/rigs/local-web-rig/profiles/app/includes/eslint/flat/mixins/packlets.js index 4291377cb4d..d33ecdd60ec 100644 --- a/rigs/local-web-rig/profiles/app/includes/eslint/flat/mixins/packlets.js +++ b/rigs/local-web-rig/profiles/app/includes/eslint/flat/mixins/packlets.js @@ -3,4 +3,4 @@ const packletsMixin = require('local-eslint-config/flat/mixins/packlets'); -module.exports = [...packletsMixin]; +module.exports = { ...packletsMixin }; From 897cb78799c68bb4c421b6c19064a124a814c1ee Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 21:09:19 -0700 Subject: [PATCH 02/26] Move shared code into a packlet --- apps/lockfile-explorer-web/package.json | 10 ++++++++++ .../src/containers/BookmarksSidebar/index.tsx | 2 +- .../src/containers/LockfileEntryDetailsView/index.tsx | 5 +++-- .../src/containers/LockfileViewer/index.tsx | 2 +- .../src/containers/PackageJsonViewer/index.tsx | 2 +- .../src/helpers/isEntryModified.ts | 2 +- apps/lockfile-explorer-web/src/helpers/lfxApiClient.ts | 6 +++--- apps/lockfile-explorer-web/src/helpers/localStorage.ts | 2 +- .../src/{types => packlets/lfx-shared}/IAppContext.ts | 0 .../lfx-shared/IJsonLfxGraph.ts} | 0 .../lfx-shared/IJsonLfxWorkspace.ts} | 6 +++--- .../src/{parsing => packlets/lfx-shared}/LfxGraph.ts | 2 +- .../src/packlets/lfx-shared/index.ts | 8 ++++++++ .../lfx-shared}/lfxGraphSerializer.ts | 2 +- .../src/parsing/lfxGraphLoader.ts | 10 ++++++---- apps/lockfile-explorer-web/src/parsing/readLockfile.ts | 2 +- .../src/parsing/test/lockfile.test.ts | 2 +- .../src/parsing/test/serializeToJson.test.ts | 4 ++-- .../src/store/slices/entrySlice.ts | 2 +- apps/lockfile-explorer-web/src/types/AppContext.ts | 2 +- apps/lockfile-explorer/.vscode/launch.json | 4 ++-- .../src/cli/explorer/ExplorerCommandLineParser.ts | 2 +- apps/lockfile-explorer/src/state/index.ts | 4 ++-- 23 files changed, 51 insertions(+), 30 deletions(-) rename apps/lockfile-explorer-web/src/{types => packlets/lfx-shared}/IAppContext.ts (100%) rename apps/lockfile-explorer-web/src/{parsing/JsonLfxGraph.ts => packlets/lfx-shared/IJsonLfxGraph.ts} (100%) rename apps/lockfile-explorer-web/src/{types/lfxProtocol.ts => packlets/lfx-shared/IJsonLfxWorkspace.ts} (84%) rename apps/lockfile-explorer-web/src/{parsing => packlets/lfx-shared}/LfxGraph.ts (98%) create mode 100644 apps/lockfile-explorer-web/src/packlets/lfx-shared/index.ts rename apps/lockfile-explorer-web/src/{parsing => packlets/lfx-shared}/lfxGraphSerializer.ts (99%) diff --git a/apps/lockfile-explorer-web/package.json b/apps/lockfile-explorer-web/package.json index c6445b31fb0..683e6a8c844 100644 --- a/apps/lockfile-explorer-web/package.json +++ b/apps/lockfile-explorer-web/package.json @@ -11,6 +11,16 @@ "_phase:build": "heft run --only build -- --clean", "_phase:test": "heft run --only test -- --clean" }, + "exports": { + "./packlets/lfx-shared": "./lib-commonjs/packlets/lfx-shared/index.js" + }, + "typesVersions": { + "*": { + "packlets/lfx-shared": [ + "lib/packlets/lfx-shared/index.d.ts" + ] + } + }, "dependencies": { "@lifaon/path": "~2.1.0", "@reduxjs/toolkit": "~1.8.6", diff --git a/apps/lockfile-explorer-web/src/containers/BookmarksSidebar/index.tsx b/apps/lockfile-explorer-web/src/containers/BookmarksSidebar/index.tsx index 3603d4dd56c..9a2d3199823 100644 --- a/apps/lockfile-explorer-web/src/containers/BookmarksSidebar/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/BookmarksSidebar/index.tsx @@ -5,7 +5,7 @@ import React, { useCallback } from 'react'; import appStyles from '../../App.scss'; import styles from './styles.scss'; import { useAppDispatch, useAppSelector } from '../../store/hooks'; -import type { LockfileEntry } from '../../parsing/LfxGraph'; +import type { LockfileEntry } from '../../packlets/lfx-shared'; import { clearStackAndPush, removeBookmark } from '../../store/slices/entrySlice'; import { Button, ScrollArea, Text } from '@rushstack/rush-themed-ui'; diff --git a/apps/lockfile-explorer-web/src/containers/LockfileEntryDetailsView/index.tsx b/apps/lockfile-explorer-web/src/containers/LockfileEntryDetailsView/index.tsx index 8e9b9b83b81..9cfe8fda918 100644 --- a/apps/lockfile-explorer-web/src/containers/LockfileEntryDetailsView/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/LockfileEntryDetailsView/index.tsx @@ -3,14 +3,15 @@ import React, { useCallback, useEffect, useState } from 'react'; import { ScrollArea, Text } from '@rushstack/rush-themed-ui'; + import styles from './styles.scss'; import appStyles from '../../App.scss'; -import { DependencyKind, type LockfileDependency } from '../../parsing/LfxGraph'; + +import { DependencyKind, type LockfileDependency, type LockfileEntry } from '../../packlets/lfx-shared'; import { readPackageJsonAsync } from '../../helpers/lfxApiClient'; import { useAppDispatch, useAppSelector } from '../../store/hooks'; import { pushToStack, selectCurrentEntry } from '../../store/slices/entrySlice'; import { ReactNull } from '../../types/ReactNull'; -import type { LockfileEntry } from '../../parsing/LfxGraph'; import { logDiagnosticInfo } from '../../helpers/logDiagnosticInfo'; import { displaySpecChanges } from '../../helpers/displaySpecChanges'; import type { IPackageJson } from '../../types/IPackageJson'; diff --git a/apps/lockfile-explorer-web/src/containers/LockfileViewer/index.tsx b/apps/lockfile-explorer-web/src/containers/LockfileViewer/index.tsx index 17176f29f48..1d513f1b8a6 100644 --- a/apps/lockfile-explorer-web/src/containers/LockfileViewer/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/LockfileViewer/index.tsx @@ -3,7 +3,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; import styles from './styles.scss'; -import { type LockfileEntry, LockfileEntryFilter } from '../../parsing/LfxGraph'; +import { type LockfileEntry, LockfileEntryFilter } from '../../packlets/lfx-shared'; import { ReactNull } from '../../types/ReactNull'; import { useAppDispatch, useAppSelector } from '../../store/hooks'; import { diff --git a/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/index.tsx b/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/index.tsx index 071a3f20a8d..8eebff05ee3 100644 --- a/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/index.tsx @@ -12,7 +12,7 @@ import { loadSpecChanges } from '../../store/slices/workspaceSlice'; import { displaySpecChanges } from '../../helpers/displaySpecChanges'; import { isEntryModified } from '../../helpers/isEntryModified'; import { ScrollArea, Tabs, Text } from '@rushstack/rush-themed-ui'; -import { LockfileEntryFilter } from '../../parsing/LfxGraph'; +import { LockfileEntryFilter } from '../../packlets/lfx-shared'; const PackageView: { [key: string]: string } = { PACKAGE_JSON: 'PACKAGE_JSON', diff --git a/apps/lockfile-explorer-web/src/helpers/isEntryModified.ts b/apps/lockfile-explorer-web/src/helpers/isEntryModified.ts index 53cdff9e4c4..20ea680d7d2 100644 --- a/apps/lockfile-explorer-web/src/helpers/isEntryModified.ts +++ b/apps/lockfile-explorer-web/src/helpers/isEntryModified.ts @@ -2,7 +2,7 @@ // See LICENSE in the project root for license information. import type { ISpecChange } from '../parsing/compareSpec'; -import type { LockfileEntry } from '../parsing/LfxGraph'; +import type { LockfileEntry } from '../packlets/lfx-shared'; export const isEntryModified = ( entry: LockfileEntry | undefined, diff --git a/apps/lockfile-explorer-web/src/helpers/lfxApiClient.ts b/apps/lockfile-explorer-web/src/helpers/lfxApiClient.ts index 14d694c9785..9cc6f469556 100644 --- a/apps/lockfile-explorer-web/src/helpers/lfxApiClient.ts +++ b/apps/lockfile-explorer-web/src/helpers/lfxApiClient.ts @@ -2,7 +2,7 @@ // See LICENSE in the project root for license information. import type { IPackageJson } from '../types/IPackageJson'; -import type { ILfxWorkspace } from '../types/lfxProtocol'; +import type { IJsonLfxWorkspace } from '../packlets/lfx-shared'; const SERVICE_URL: string = window.appContext.serviceUrl; @@ -19,7 +19,7 @@ export async function checkAliveAsync(): Promise { * Read the contents of a text file under the workspace directory. * @param relativePath - a file path that is relative to the working directory. */ -export async function readWorkspaceConfigAsync(): Promise { +export async function readWorkspaceConfigAsync(): Promise { let response: Response; try { @@ -39,7 +39,7 @@ export async function readWorkspaceConfigAsync(): Promise { throw new Error('Network error: ' + (e.message || 'An unknown error occurred')); } - const responseJson: ILfxWorkspace = await response.json(); + const responseJson: IJsonLfxWorkspace = await response.json(); return responseJson; } diff --git a/apps/lockfile-explorer-web/src/helpers/localStorage.ts b/apps/lockfile-explorer-web/src/helpers/localStorage.ts index 77d703d859f..12c447f2170 100644 --- a/apps/lockfile-explorer-web/src/helpers/localStorage.ts +++ b/apps/lockfile-explorer-web/src/helpers/localStorage.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import { type LockfileEntry, LockfileEntryFilter } from '../parsing/LfxGraph'; +import { type LockfileEntry, LockfileEntryFilter } from '../packlets/lfx-shared'; const BOOKMARK_KEY: string = 'LOCKFILE_EXPLORER_BOOKMARKS'; diff --git a/apps/lockfile-explorer-web/src/types/IAppContext.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/IAppContext.ts similarity index 100% rename from apps/lockfile-explorer-web/src/types/IAppContext.ts rename to apps/lockfile-explorer-web/src/packlets/lfx-shared/IAppContext.ts diff --git a/apps/lockfile-explorer-web/src/parsing/JsonLfxGraph.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxGraph.ts similarity index 100% rename from apps/lockfile-explorer-web/src/parsing/JsonLfxGraph.ts rename to apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxGraph.ts diff --git a/apps/lockfile-explorer-web/src/types/lfxProtocol.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxWorkspace.ts similarity index 84% rename from apps/lockfile-explorer-web/src/types/lfxProtocol.ts rename to apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxWorkspace.ts index 04a1d793964..c9ad00998c5 100644 --- a/apps/lockfile-explorer-web/src/types/lfxProtocol.ts +++ b/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxWorkspace.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -export interface ILfxWorkspaceRushConfig { +export interface IJsonLfxWorkspaceRushConfig { /** * The rushVersion from rush.json. */ @@ -14,7 +14,7 @@ export interface ILfxWorkspaceRushConfig { subspaceName: string; } -export interface ILfxWorkspace { +export interface IJsonLfxWorkspace { /** * Absolute path to the workspace folder that is opened by the app. * Relative paths are generally relative to this path. @@ -30,5 +30,5 @@ export interface ILfxWorkspace { * If this is a Rush workspace (versus a plain PNPM workspace), then * this section will be defined. */ - rushConfig: ILfxWorkspaceRushConfig | undefined; + rushConfig: IJsonLfxWorkspaceRushConfig | undefined; } diff --git a/apps/lockfile-explorer-web/src/parsing/LfxGraph.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts similarity index 98% rename from apps/lockfile-explorer-web/src/parsing/LfxGraph.ts rename to apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts index 8cbfd4ee7ea..08fe5e7d17c 100644 --- a/apps/lockfile-explorer-web/src/parsing/LfxGraph.ts +++ b/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { IJsonPeerDependencyMeta } from './JsonLfxGraph'; +import type { IJsonPeerDependencyMeta } from './IJsonLfxGraph'; export enum DependencyKind { DEPENDENCY = 'regular', diff --git a/apps/lockfile-explorer-web/src/packlets/lfx-shared/index.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/index.ts new file mode 100644 index 00000000000..c060ea5e6b6 --- /dev/null +++ b/apps/lockfile-explorer-web/src/packlets/lfx-shared/index.ts @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +export * from './IAppContext'; +export * from './IJsonLfxGraph'; +export * from './IJsonLfxWorkspace'; +export * from './LfxGraph'; +export * as lfxGraphSerializer from './lfxGraphSerializer'; diff --git a/apps/lockfile-explorer-web/src/parsing/lfxGraphSerializer.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/lfxGraphSerializer.ts similarity index 99% rename from apps/lockfile-explorer-web/src/parsing/lfxGraphSerializer.ts rename to apps/lockfile-explorer-web/src/packlets/lfx-shared/lfxGraphSerializer.ts index 30a0e19fa53..f93cb6c1bde 100644 --- a/apps/lockfile-explorer-web/src/parsing/lfxGraphSerializer.ts +++ b/apps/lockfile-explorer-web/src/packlets/lfx-shared/lfxGraphSerializer.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { IJsonLfxDependency, IJsonLfxEntry, IJsonLfxGraph } from './JsonLfxGraph'; +import type { IJsonLfxDependency, IJsonLfxEntry, IJsonLfxGraph } from './IJsonLfxGraph'; import { type ILockfileEntryOptions, LfxGraph, LockfileDependency, LockfileEntry } from './LfxGraph'; export function serializeToJson(graph: LfxGraph): IJsonLfxGraph { diff --git a/apps/lockfile-explorer-web/src/parsing/lfxGraphLoader.ts b/apps/lockfile-explorer-web/src/parsing/lfxGraphLoader.ts index e9b02ec4e47..59670de9273 100644 --- a/apps/lockfile-explorer-web/src/parsing/lfxGraphLoader.ts +++ b/apps/lockfile-explorer-web/src/parsing/lfxGraphLoader.ts @@ -1,15 +1,17 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. +import { Path } from '@lifaon/path'; + import { type ILockfileDependencyOptions, type ILockfileEntryOptions, LfxGraph, LockfileEntry, - LockfileEntryFilter -} from './LfxGraph'; -import { DependencyKind, LockfileDependency } from './LfxGraph'; -import { Path } from '@lifaon/path'; + LockfileEntryFilter, + DependencyKind, + LockfileDependency +} from '../packlets/lfx-shared'; enum PnpmLockfileVersion { V6, diff --git a/apps/lockfile-explorer-web/src/parsing/readLockfile.ts b/apps/lockfile-explorer-web/src/parsing/readLockfile.ts index c68b9bb26d8..bbd780235b8 100644 --- a/apps/lockfile-explorer-web/src/parsing/readLockfile.ts +++ b/apps/lockfile-explorer-web/src/parsing/readLockfile.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { LockfileEntry } from './LfxGraph'; +import type { LockfileEntry } from '../packlets/lfx-shared'; import * as lfxGraphLoader from './lfxGraphLoader'; const serviceUrl: string = window.appContext.serviceUrl; diff --git a/apps/lockfile-explorer-web/src/parsing/test/lockfile.test.ts b/apps/lockfile-explorer-web/src/parsing/test/lockfile.test.ts index d6cbc0626dc..01af2c3ccf6 100644 --- a/apps/lockfile-explorer-web/src/parsing/test/lockfile.test.ts +++ b/apps/lockfile-explorer-web/src/parsing/test/lockfile.test.ts @@ -3,7 +3,7 @@ import { TEST_LOCKFILE } from './testLockfile'; import * as lfxGraphLoader from '../lfxGraphLoader'; -import type { LockfileEntry } from '../LfxGraph'; +import type { LockfileEntry } from '../../packlets/lfx-shared'; describe('LockfileGeneration', () => { it('creates a valid bi-directional graph', () => { diff --git a/apps/lockfile-explorer-web/src/parsing/test/serializeToJson.test.ts b/apps/lockfile-explorer-web/src/parsing/test/serializeToJson.test.ts index 2fe9915fbe8..2dc9cbfb808 100644 --- a/apps/lockfile-explorer-web/src/parsing/test/serializeToJson.test.ts +++ b/apps/lockfile-explorer-web/src/parsing/test/serializeToJson.test.ts @@ -3,8 +3,8 @@ import { TEST_LOCKFILE } from './testLockfile'; import * as lfxGraphLoader from '../lfxGraphLoader'; -import * as lfxGraphSerializer from '../lfxGraphSerializer'; -import type { LfxGraph } from '../LfxGraph'; +import { lfxGraphSerializer } from '../../packlets/lfx-shared'; +import type { LfxGraph } from '../../packlets/lfx-shared'; describe('serializeToJson', () => { it('serializes a simple graph', () => { diff --git a/apps/lockfile-explorer-web/src/store/slices/entrySlice.ts b/apps/lockfile-explorer-web/src/store/slices/entrySlice.ts index 8c6bd99c0fc..f25d3bff424 100644 --- a/apps/lockfile-explorer-web/src/store/slices/entrySlice.ts +++ b/apps/lockfile-explorer-web/src/store/slices/entrySlice.ts @@ -2,7 +2,7 @@ // See LICENSE in the project root for license information. import { createSlice, type PayloadAction, type Reducer } from '@reduxjs/toolkit'; -import { type LockfileEntry, LockfileEntryFilter } from '../../parsing/LfxGraph'; +import { type LockfileEntry, LockfileEntryFilter } from '../../packlets/lfx-shared'; import type { RootState } from '../index'; import { getBookmarksFromStorage, diff --git a/apps/lockfile-explorer-web/src/types/AppContext.ts b/apps/lockfile-explorer-web/src/types/AppContext.ts index 28e788cf31f..5bd79089f4c 100644 --- a/apps/lockfile-explorer-web/src/types/AppContext.ts +++ b/apps/lockfile-explorer-web/src/types/AppContext.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { IAppContext } from './IAppContext'; +import type { IAppContext } from '../packlets/lfx-shared'; declare global { // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/apps/lockfile-explorer/.vscode/launch.json b/apps/lockfile-explorer/.vscode/launch.json index f1cdf885db1..10b8aff39f2 100644 --- a/apps/lockfile-explorer/.vscode/launch.json +++ b/apps/lockfile-explorer/.vscode/launch.json @@ -19,8 +19,8 @@ "request": "launch", "name": "Run in specified folder", "program": "${workspaceFolder}/lib/start-explorer.js", - //"cwd": "C:\\Git\\lockfile-explorer-demos", - "cwd": "(your project path)", + "cwd": "C:\\Git\\lockfile-explorer-demos", + //"cwd": "(your project path)", "args": ["--debug"], "sourceMaps": true } diff --git a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts index 4f9d3efb2f7..fe8d92765d9 100644 --- a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts +++ b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts @@ -15,8 +15,8 @@ import { CommandLineParser, type IRequiredCommandLineStringParameter } from '@rushstack/ts-command-line'; -import type { IAppContext } from '@rushstack/lockfile-explorer-web/lib/types/IAppContext'; import type { Lockfile } from '@pnpm/lockfile-types'; +import type { IAppContext } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; import type { IAppState } from '../../state'; import { init } from '../../utils/init'; diff --git a/apps/lockfile-explorer/src/state/index.ts b/apps/lockfile-explorer/src/state/index.ts index d718311e17f..5cb346ae230 100644 --- a/apps/lockfile-explorer/src/state/index.ts +++ b/apps/lockfile-explorer/src/state/index.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { ILfxWorkspace } from '@rushstack/lockfile-explorer-web/lib/types/lfxProtocol'; +import { type IJsonLfxWorkspace } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; export interface IAppState { lockfileExplorerProjectRoot: string; @@ -11,5 +11,5 @@ export interface IAppState { pnpmfileLocation: string; appVersion: string; debugMode: boolean; - lfxWorkspace: ILfxWorkspace; + lfxWorkspace: IJsonLfxWorkspace; } From 949f5874058bb86461f5a40f736c685c849186de Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 21:17:17 -0700 Subject: [PATCH 03/26] - Rename `LockfileEntry` -> `LfxGraphEntry` - Rename `LockfileDependency` -> `LfxGraphDependency` - Rename `DependencyKind` -> `LfxDependencyKind` and simplify the enum members - Rename `LockfileEntryFilter` -> `LfxGraphEntryKind` - Eliminate circular dependency in IJsonLfxGraph.ts --- .../src/containers/BookmarksSidebar/index.tsx | 6 +- .../LockfileEntryDetailsView/index.tsx | 30 ++++--- .../src/containers/LockfileViewer/index.tsx | 64 +++++++-------- .../containers/PackageJsonViewer/index.tsx | 4 +- .../src/helpers/isEntryModified.ts | 4 +- .../src/helpers/localStorage.ts | 14 ++-- .../src/packlets/lfx-shared/IJsonLfxGraph.ts | 17 +++- .../src/packlets/lfx-shared/LfxGraph.ts | 47 ++++------- .../packlets/lfx-shared/lfxGraphSerializer.ts | 22 ++--- .../src/parsing/lfxGraphLoader.ts | 66 ++++++++------- .../src/parsing/readLockfile.ts | 4 +- .../src/parsing/test/lockfile.test.ts | 4 +- .../src/store/slices/entrySlice.ts | 82 +++++++++---------- apps/lockfile-explorer/src/state/index.ts | 2 +- 14 files changed, 179 insertions(+), 187 deletions(-) diff --git a/apps/lockfile-explorer-web/src/containers/BookmarksSidebar/index.tsx b/apps/lockfile-explorer-web/src/containers/BookmarksSidebar/index.tsx index 9a2d3199823..c15fd3772ed 100644 --- a/apps/lockfile-explorer-web/src/containers/BookmarksSidebar/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/BookmarksSidebar/index.tsx @@ -5,7 +5,7 @@ import React, { useCallback } from 'react'; import appStyles from '../../App.scss'; import styles from './styles.scss'; import { useAppDispatch, useAppSelector } from '../../store/hooks'; -import type { LockfileEntry } from '../../packlets/lfx-shared'; +import type { LfxGraphEntry } from '../../packlets/lfx-shared'; import { clearStackAndPush, removeBookmark } from '../../store/slices/entrySlice'; import { Button, ScrollArea, Text } from '@rushstack/rush-themed-ui'; @@ -14,13 +14,13 @@ export const BookmarksSidebar = (): JSX.Element => { const dispatch = useAppDispatch(); const clear = useCallback( - (entry: LockfileEntry) => () => { + (entry: LfxGraphEntry) => () => { dispatch(clearStackAndPush(entry)); }, [dispatch] ); const deleteEntry = useCallback( - (entry: LockfileEntry) => () => { + (entry: LfxGraphEntry) => () => { dispatch(removeBookmark(entry)); }, [dispatch] diff --git a/apps/lockfile-explorer-web/src/containers/LockfileEntryDetailsView/index.tsx b/apps/lockfile-explorer-web/src/containers/LockfileEntryDetailsView/index.tsx index 9cfe8fda918..8b0fb3769e1 100644 --- a/apps/lockfile-explorer-web/src/containers/LockfileEntryDetailsView/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/LockfileEntryDetailsView/index.tsx @@ -7,7 +7,7 @@ import { ScrollArea, Text } from '@rushstack/rush-themed-ui'; import styles from './styles.scss'; import appStyles from '../../App.scss'; -import { DependencyKind, type LockfileDependency, type LockfileEntry } from '../../packlets/lfx-shared'; +import { LfxDependencyKind, type LfxGraphDependency, type LfxGraphEntry } from '../../packlets/lfx-shared'; import { readPackageJsonAsync } from '../../helpers/lfxApiClient'; import { useAppDispatch, useAppSelector } from '../../store/hooks'; import { pushToStack, selectCurrentEntry } from '../../store/slices/entrySlice'; @@ -28,7 +28,7 @@ enum DependencyKey { } interface IInfluencerType { - entry: LockfileEntry; + entry: LfxGraphEntry; type: DependencyType; } @@ -37,14 +37,14 @@ export const LockfileEntryDetailsView = (): JSX.Element | ReactNull => { const specChanges = useAppSelector((state) => state.workspace.specChanges); const dispatch = useAppDispatch(); - const [inspectDependency, setInspectDependency] = useState(null); + const [inspectDependency, setInspectDependency] = useState(null); const [influencers, setInfluencers] = useState([]); const [directRefsPackageJSON, setDirectRefsPackageJSON] = useState>( new Map() ); useEffect(() => { - async function loadPackageJson(referrers: LockfileEntry[]): Promise { + async function loadPackageJson(referrers: LfxGraphEntry[]): Promise { const referrersJsonMap = new Map(); await Promise.all( referrers.map(async (ref) => { @@ -81,15 +81,15 @@ export const LockfileEntryDetailsView = (): JSX.Element | ReactNull => { // Check if we need to calculate influencers. // If the current dependencyToTrace is a peer dependency then we do - if (dependencyToTrace.dependencyType !== DependencyKind.PEER_DEPENDENCY) { + if (dependencyToTrace.dependencyType !== LfxDependencyKind.Peer) { return; } // calculate influencers const stack = [selectedEntry]; - const determinants = new Set(); - const transitiveReferrers = new Set(); - const visitedNodes = new Set(); + const determinants = new Set(); + const transitiveReferrers = new Set(); + const visitedNodes = new Set(); visitedNodes.add(selectedEntry); while (stack.length) { const currEntry = stack.pop(); @@ -180,7 +180,7 @@ export const LockfileEntryDetailsView = (): JSX.Element | ReactNull => { package.json spec:{' '} - {inspectDependency.dependencyType === DependencyKind.PEER_DEPENDENCY + {inspectDependency.dependencyType === LfxDependencyKind.Peer ? `"${inspectDependency.peerDependencyMeta.version}" ${ inspectDependency.peerDependencyMeta.optional ? 'Optional' : 'Required' } Peer` @@ -204,9 +204,7 @@ export const LockfileEntryDetailsView = (): JSX.Element | ReactNull => { const renderPeerDependencies = (): JSX.Element | ReactNull => { if (!selectedEntry) return ReactNull; - const peerDeps = selectedEntry.dependencies.filter( - (d) => d.dependencyType === DependencyKind.PEER_DEPENDENCY - ); + const peerDeps = selectedEntry.dependencies.filter((d) => d.dependencyType === LfxDependencyKind.Peer); if (!peerDeps.length) { return (
@@ -214,7 +212,7 @@ export const LockfileEntryDetailsView = (): JSX.Element | ReactNull => {
); } - if (!inspectDependency || inspectDependency.dependencyType !== DependencyKind.PEER_DEPENDENCY) { + if (!inspectDependency || inspectDependency.dependencyType !== LfxDependencyKind.Peer) { return (
Select a peer dependency to view its influencers @@ -302,7 +300,7 @@ export const LockfileEntryDetailsView = (): JSX.Element | ReactNull => {
- {selectedEntry.referrers?.map((referrer: LockfileEntry) => ( + {selectedEntry.referrers?.map((referrer: LfxGraphEntry) => (
{
- {selectedEntry.dependencies?.map((dependency: LockfileDependency) => ( + {selectedEntry.dependencies?.map((dependency: LfxGraphDependency) => (
{ > Name: {dependency.name}{' '} - {dependency.dependencyType === DependencyKind.PEER_DEPENDENCY + {dependency.dependencyType === LfxDependencyKind.Peer ? `${ dependency.peerDependencyMeta.optional ? '(Optional)' : '(Non-optional)' } Peer Dependency` diff --git a/apps/lockfile-explorer-web/src/containers/LockfileViewer/index.tsx b/apps/lockfile-explorer-web/src/containers/LockfileViewer/index.tsx index 1d513f1b8a6..bd90300589e 100644 --- a/apps/lockfile-explorer-web/src/containers/LockfileViewer/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/LockfileViewer/index.tsx @@ -3,7 +3,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; import styles from './styles.scss'; -import { type LockfileEntry, LockfileEntryFilter } from '../../packlets/lfx-shared'; +import { type LfxGraphEntry, LfxGraphEntryKind } from '../../packlets/lfx-shared'; import { ReactNull } from '../../types/ReactNull'; import { useAppDispatch, useAppSelector } from '../../store/hooks'; import { @@ -17,7 +17,7 @@ import { Tabs, Checkbox, ScrollArea, Input, Text } from '@rushstack/rush-themed- interface ILockfileEntryGroup { entryName: string; - versions: LockfileEntry[]; + versions: LfxGraphEntry[]; } const LockfileEntryLi = ({ group }: { group: ILockfileEntryGroup }): JSX.Element => { @@ -26,7 +26,7 @@ const LockfileEntryLi = ({ group }: { group: ILockfileEntryGroup }): JSX.Element const dispatch = useAppDispatch(); const fieldRef = useRef() as React.MutableRefObject; const clear = useCallback( - (entry: LockfileEntry) => () => { + (entry: LfxGraphEntry) => () => { dispatch(pushToStack(entry)); }, [dispatch] @@ -40,7 +40,7 @@ const LockfileEntryLi = ({ group }: { group: ILockfileEntryGroup }): JSX.Element } }, [selectedEntry, group]); - if (activeFilters[LockfileEntryFilter.Project]) { + if (activeFilters[LfxGraphEntryKind.Project]) { return (
{group.versions.map((entry) => ( @@ -80,7 +80,7 @@ const LockfileEntryLi = ({ group }: { group: ILockfileEntryGroup }): JSX.Element ); }; -const multipleVersions = (entries: LockfileEntry[]): boolean => { +const multipleVersions = (entries: LfxGraphEntry[]): boolean => { const set = new Set(); for (const entry of entries) { if (set.has(entry.entryPackageVersion)) return true; @@ -96,8 +96,8 @@ export const LockfileViewer = (): JSX.Element | ReactNull => { const entries = useAppSelector(selectFilteredEntries); const activeFilters = useAppSelector((state) => state.entry.filters); const updateFilter = useCallback( - (type: LockfileEntryFilter) => (e: React.ChangeEvent) => { - if (type === LockfileEntryFilter.Project) { + (type: LfxGraphEntryKind) => (e: React.ChangeEvent) => { + if (type === LfxGraphEntryKind.Project) { setProjectFilter(e.target.value); } else { setPackageFilter(e.target.value); @@ -108,19 +108,19 @@ export const LockfileViewer = (): JSX.Element | ReactNull => { ); useEffect(() => { - setProjectFilter(getFilterFromLocalStorage(LockfileEntryFilter.Project)); - setPackageFilter(getFilterFromLocalStorage(LockfileEntryFilter.Package)); + setProjectFilter(getFilterFromLocalStorage(LfxGraphEntryKind.Project)); + setPackageFilter(getFilterFromLocalStorage(LfxGraphEntryKind.Package)); }, []); const getEntriesToShow = (): ILockfileEntryGroup[] => { - let filteredEntries: LockfileEntry[] = entries; - if (projectFilter && activeFilters[LockfileEntryFilter.Project]) { + let filteredEntries: LfxGraphEntry[] = entries; + if (projectFilter && activeFilters[LfxGraphEntryKind.Project]) { filteredEntries = entries.filter((entry) => entry.entryPackageName.indexOf(projectFilter) !== -1); - } else if (packageFilter && activeFilters[LockfileEntryFilter.Package]) { + } else if (packageFilter && activeFilters[LfxGraphEntryKind.Package]) { filteredEntries = entries.filter((entry) => entry.entryPackageName.indexOf(packageFilter) !== -1); } - const reducedEntries = filteredEntries.reduce((groups: { [key: string]: LockfileEntry[] }, item) => { + const reducedEntries = filteredEntries.reduce((groups: { [key: string]: LfxGraphEntry[] }, item) => { const group = groups[item.entryPackageName] || []; group.push(item); groups[item.entryPackageName] = group; @@ -134,14 +134,14 @@ export const LockfileViewer = (): JSX.Element | ReactNull => { }); } - if (activeFilters[LockfileEntryFilter.SideBySide]) { + if (activeFilters[LfxGraphEntryKind.SideBySide]) { groupedEntries = groupedEntries.filter((entry) => entry.versions.length > 1); } - if (activeFilters[LockfileEntryFilter.Doppelganger]) { + if (activeFilters[LfxGraphEntryKind.Doppelganger]) { groupedEntries = groupedEntries.filter((entry) => multipleVersions(entry.versions)); } - if (activeFilters[LockfileEntryFilter.Project]) { + if (activeFilters[LfxGraphEntryKind.Project]) { groupedEntries = groupedEntries.sort((a, b) => a.entryName > b.entryName ? 1 : b.entryName > a.entryName ? -1 : 0 ); @@ -151,7 +151,7 @@ export const LockfileViewer = (): JSX.Element | ReactNull => { }; const changeFilter = useCallback( - (filter: LockfileEntryFilter, enabled: boolean) => (): void => { + (filter: LfxGraphEntryKind, enabled: boolean) => (): void => { dispatch(selectFilter({ filter, state: enabled })); }, [dispatch] @@ -160,11 +160,11 @@ export const LockfileViewer = (): JSX.Element | ReactNull => { const togglePackageView = useCallback( (selected: string) => { if (selected === 'Projects') { - dispatch(selectFilter({ filter: LockfileEntryFilter.Project, state: true })); - dispatch(selectFilter({ filter: LockfileEntryFilter.Package, state: false })); + dispatch(selectFilter({ filter: LfxGraphEntryKind.Project, state: true })); + dispatch(selectFilter({ filter: LfxGraphEntryKind.Package, state: false })); } else { - dispatch(selectFilter({ filter: LockfileEntryFilter.Package, state: true })); - dispatch(selectFilter({ filter: LockfileEntryFilter.Project, state: false })); + dispatch(selectFilter({ filter: LfxGraphEntryKind.Package, state: true })); + dispatch(selectFilter({ filter: LfxGraphEntryKind.Project, state: false })); } }, // eslint-disable-next-line react-hooks/exhaustive-deps @@ -186,17 +186,15 @@ export const LockfileViewer = (): JSX.Element | ReactNull => { header: 'Packages' } ]} - value={activeFilters[LockfileEntryFilter.Project] ? 'Projects' : 'Packages'} + value={activeFilters[LfxGraphEntryKind.Project] ? 'Projects' : 'Packages'} onChange={togglePackageView} /> @@ -204,25 +202,25 @@ export const LockfileViewer = (): JSX.Element | ReactNull => { ))} - {activeFilters[LockfileEntryFilter.Package] ? ( + {activeFilters[LfxGraphEntryKind.Package] ? (
Filters
diff --git a/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/index.tsx b/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/index.tsx index 8eebff05ee3..b7588f360a7 100644 --- a/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/index.tsx +++ b/apps/lockfile-explorer-web/src/containers/PackageJsonViewer/index.tsx @@ -12,7 +12,7 @@ import { loadSpecChanges } from '../../store/slices/workspaceSlice'; import { displaySpecChanges } from '../../helpers/displaySpecChanges'; import { isEntryModified } from '../../helpers/isEntryModified'; import { ScrollArea, Tabs, Text } from '@rushstack/rush-themed-ui'; -import { LockfileEntryFilter } from '../../packlets/lfx-shared'; +import { LfxGraphEntryKind } from '../../packlets/lfx-shared'; const PackageView: { [key: string]: string } = { PACKAGE_JSON: 'PACKAGE_JSON', @@ -186,7 +186,7 @@ export const PackageJsonViewer = (): JSX.Element => { Package Name: - {selectedEntry?.kind === LockfileEntryFilter.Project + {selectedEntry?.kind === LfxGraphEntryKind.Project ? parsedPackageJSON.name : selectedEntry?.displayText} diff --git a/apps/lockfile-explorer-web/src/helpers/isEntryModified.ts b/apps/lockfile-explorer-web/src/helpers/isEntryModified.ts index 20ea680d7d2..9750281021a 100644 --- a/apps/lockfile-explorer-web/src/helpers/isEntryModified.ts +++ b/apps/lockfile-explorer-web/src/helpers/isEntryModified.ts @@ -2,10 +2,10 @@ // See LICENSE in the project root for license information. import type { ISpecChange } from '../parsing/compareSpec'; -import type { LockfileEntry } from '../packlets/lfx-shared'; +import type { LfxGraphEntry } from '../packlets/lfx-shared'; export const isEntryModified = ( - entry: LockfileEntry | undefined, + entry: LfxGraphEntry | undefined, specChanges: Map ): boolean => { if (!entry) return false; diff --git a/apps/lockfile-explorer-web/src/helpers/localStorage.ts b/apps/lockfile-explorer-web/src/helpers/localStorage.ts index 12c447f2170..5242b4e368b 100644 --- a/apps/lockfile-explorer-web/src/helpers/localStorage.ts +++ b/apps/lockfile-explorer-web/src/helpers/localStorage.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import { type LockfileEntry, LockfileEntryFilter } from '../packlets/lfx-shared'; +import { type LfxGraphEntry, LfxGraphEntryKind } from '../packlets/lfx-shared'; const BOOKMARK_KEY: string = 'LOCKFILE_EXPLORER_BOOKMARKS'; @@ -14,14 +14,14 @@ export const getBookmarksFromStorage = (): Set => { return bookmarkSet; }; -export const saveBookmarkToLocalStorage = (entry: LockfileEntry): void => { +export const saveBookmarkToLocalStorage = (entry: LfxGraphEntry): void => { const key = entry.rawEntryId; const currBookmarks = JSON.parse(localStorage.getItem(BOOKMARK_KEY) || '{}'); currBookmarks[key] = true; localStorage.setItem(BOOKMARK_KEY, JSON.stringify(currBookmarks)); }; -export const removeBookmarkFromLocalStorage = (entry: LockfileEntry): void => { +export const removeBookmarkFromLocalStorage = (entry: LfxGraphEntry): void => { const key = entry.rawEntryId; const currBookmarks = JSON.parse(localStorage.getItem(BOOKMARK_KEY) || '{}'); delete currBookmarks[key]; @@ -30,16 +30,16 @@ export const removeBookmarkFromLocalStorage = (entry: LockfileEntry): void => { const PROJECT_FILTER_KEY: string = 'LOCKFILE_EXPLORER_PROJECT_FILTER'; const PACKAGE_FILTER_KEY: string = 'LOCKFILE_EXPLORER_PACKAGE_FILTER'; -export const saveFilterToLocalStorage = (filter: string, type: LockfileEntryFilter): void => { - if (type === LockfileEntryFilter.Project) { +export const saveFilterToLocalStorage = (filter: string, type: LfxGraphEntryKind): void => { + if (type === LfxGraphEntryKind.Project) { localStorage.setItem(PROJECT_FILTER_KEY, filter); } else { localStorage.setItem(PACKAGE_FILTER_KEY, filter); } }; -export const getFilterFromLocalStorage = (type: LockfileEntryFilter): string => { - if (type === LockfileEntryFilter.Project) { +export const getFilterFromLocalStorage = (type: LfxGraphEntryKind): string => { + if (type === LfxGraphEntryKind.Project) { return localStorage.getItem(PROJECT_FILTER_KEY) || ''; } else { return localStorage.getItem(PACKAGE_FILTER_KEY) || ''; diff --git a/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxGraph.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxGraph.ts index 4bb82873b36..6f6c96a11d8 100644 --- a/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxGraph.ts +++ b/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxGraph.ts @@ -1,7 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { DependencyKind, LockfileEntryFilter } from './LfxGraph'; +export enum LfxGraphEntryKind { + Project = 1, + Package = 2, + SideBySide = 3, + Doppelganger = 4 +} export interface IJsonPeerDependencyMeta { name?: string; @@ -13,13 +18,19 @@ export interface IJsonLfxDependency { name: string; version: string; entryId: string; - dependencyType: DependencyKind; + dependencyType: LfxDependencyKind; resolvedEntryJsonId?: number; peerDependencyMeta: IJsonPeerDependencyMeta; } +export enum LfxDependencyKind { + Regular = 'regular', + Dev = 'dev', + Peer = 'peer' +} + export interface IJsonLfxEntry { /** * A unique ID used when serializing graph links. @@ -30,7 +41,7 @@ export interface IJsonLfxEntry { */ jsonId: number; - kind: LockfileEntryFilter; + kind: LfxGraphEntryKind; entryId: string; rawEntryId: string; packageJsonFolderPath: string; diff --git a/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts index 08fe5e7d17c..55817a7e59d 100644 --- a/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts +++ b/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts @@ -1,19 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { IJsonPeerDependencyMeta } from './IJsonLfxGraph'; +import type { LfxDependencyKind, IJsonPeerDependencyMeta, LfxGraphEntryKind } from './IJsonLfxGraph'; -export enum DependencyKind { - DEPENDENCY = 'regular', - DEV_DEPENDENCY = 'dev', - PEER_DEPENDENCY = 'peer' -} - -export interface ILockfileDependencyOptions { +export interface ILfxGraphDependencyOptions { name: string; version: string; - dependencyType: DependencyKind; - containingEntry: LockfileEntry; + dependencyType: LfxDependencyKind; + containingEntry: LfxGraphEntry; peerDependencyMeta: IJsonPeerDependencyMeta; entryId: string; } @@ -27,17 +21,17 @@ export interface ILockfileDependencyOptions { * The "resolvedEntry" field is the corresponding LockfileEntry for this dependency, as all dependencies also have * their own entries in the pnpm lockfile. */ -export class LockfileDependency { +export class LfxGraphDependency { public readonly name: string; public readonly version: string; - public readonly dependencyType: DependencyKind; - public readonly containingEntry: LockfileEntry; + public readonly dependencyType: LfxDependencyKind; + public readonly containingEntry: LfxGraphEntry; public readonly entryId: string; public readonly peerDependencyMeta: IJsonPeerDependencyMeta; - public resolvedEntry: LockfileEntry | undefined = undefined; + public resolvedEntry: LfxGraphEntry | undefined = undefined; - public constructor(options: ILockfileDependencyOptions) { + public constructor(options: ILfxGraphDependencyOptions) { this.name = options.name; this.version = options.version; this.dependencyType = options.dependencyType; @@ -47,15 +41,8 @@ export class LockfileDependency { } } -export enum LockfileEntryFilter { - Project = 1, - Package = 2, - SideBySide = 3, - Doppelganger = 4 -} - -export interface ILockfileEntryOptions { - kind: LockfileEntryFilter; +export interface ILfxGraphEntryOptions { + kind: LfxGraphEntryKind; entryId: string; rawEntryId: string; packageJsonFolderPath: string; @@ -72,11 +59,11 @@ export interface ILockfileEntryOptions { * Each project or package will have its own LockfileEntry, which is created when the lockfile is first parsed. * The fields for the LockfileEntry are outlined below: */ -export class LockfileEntry { +export class LfxGraphEntry { /** * Whether this entry is a project or a package (specified by importers or packages in the lockfile). */ - public readonly kind: LockfileEntryFilter; + public readonly kind: LfxGraphEntryKind; /** * A unique (human-readable) identifier for this lockfile entry. For projects, this is just @@ -112,7 +99,7 @@ export class LockfileEntry { * A list of all the dependencies for this entry. * Note that dependencies, dev dependencies, as well as peer dependencies are all included. */ - public readonly dependencies: LockfileDependency[] = []; + public readonly dependencies: LfxGraphDependency[] = []; /** * A list of dependencies that are listed under the "transitivePeerDependencies" in the pnpm lockfile. @@ -122,9 +109,9 @@ export class LockfileEntry { /** * A list of entries that specify this entry as a dependency. */ - public readonly referrers: LockfileEntry[] = []; + public readonly referrers: LfxGraphEntry[] = []; - public constructor(options: ILockfileEntryOptions) { + public constructor(options: ILfxGraphEntryOptions) { this.kind = options.kind; this.entryId = options.entryId; this.rawEntryId = options.rawEntryId; @@ -137,5 +124,5 @@ export class LockfileEntry { } export class LfxGraph { - public readonly entries: LockfileEntry[] = []; + public readonly entries: LfxGraphEntry[] = []; } diff --git a/apps/lockfile-explorer-web/src/packlets/lfx-shared/lfxGraphSerializer.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/lfxGraphSerializer.ts index f93cb6c1bde..568add1db2f 100644 --- a/apps/lockfile-explorer-web/src/packlets/lfx-shared/lfxGraphSerializer.ts +++ b/apps/lockfile-explorer-web/src/packlets/lfx-shared/lfxGraphSerializer.ts @@ -2,14 +2,14 @@ // See LICENSE in the project root for license information. import type { IJsonLfxDependency, IJsonLfxEntry, IJsonLfxGraph } from './IJsonLfxGraph'; -import { type ILockfileEntryOptions, LfxGraph, LockfileDependency, LockfileEntry } from './LfxGraph'; +import { type ILfxGraphEntryOptions, LfxGraph, LfxGraphDependency, LfxGraphEntry } from './LfxGraph'; export function serializeToJson(graph: LfxGraph): IJsonLfxGraph { const jsonLfxEntries: IJsonLfxEntry[] = []; - const jsonIdByEntry: Map = new Map(); + const jsonIdByEntry: Map = new Map(); - function toJsonId(entry: LockfileEntry): number { + function toJsonId(entry: LfxGraphEntry): number { const result: number | undefined = jsonIdByEntry.get(entry); if (result === undefined) { throw new Error('Attempt to serialize disconnected object'); @@ -46,7 +46,7 @@ export function serializeToJson(graph: LfxGraph): IJsonLfxGraph { // Use the jsonId mapping to serialize the lists for (let i: number = 0; i < jsonLfxEntries.length; ++i) { const jsonLfxEntry: IJsonLfxEntry = jsonLfxEntries[i]; - const entry: LockfileEntry = graph.entries[i]; + const entry: LfxGraphEntry = graph.entries[i]; for (const dependency of entry.dependencies) { const jsonLfxDependency: IJsonLfxDependency = { @@ -76,10 +76,10 @@ export function serializeToJson(graph: LfxGraph): IJsonLfxGraph { export function deserializeFromJson(jsonLfxGraph: IJsonLfxGraph): LfxGraph { const graph: LfxGraph = new LfxGraph(); - const entries: LockfileEntry[] = graph.entries; + const entries: LfxGraphEntry[] = graph.entries; - function fromJsonId(jsonId: number): LockfileEntry { - const result: LockfileEntry | undefined = entries[jsonId]; + function fromJsonId(jsonId: number): LfxGraphEntry { + const result: LfxGraphEntry | undefined = entries[jsonId]; if (result === undefined) { throw new Error('Invalid jsonId'); } @@ -90,7 +90,7 @@ export function deserializeFromJson(jsonLfxGraph: IJsonLfxGraph): LfxGraph { // First create the jsonId mapping for (const jsonLfxEntry of jsonLfxEntries) { - const options: ILockfileEntryOptions = { + const options: ILfxGraphEntryOptions = { kind: jsonLfxEntry.kind, entryId: jsonLfxEntry.entryId, rawEntryId: jsonLfxEntry.rawEntryId, @@ -100,16 +100,16 @@ export function deserializeFromJson(jsonLfxGraph: IJsonLfxGraph): LfxGraph { entryPackageVersion: jsonLfxEntry.entryPackageVersion, entrySuffix: jsonLfxEntry.entrySuffix }; - entries.push(new LockfileEntry(options)); + entries.push(new LfxGraphEntry(options)); } // Use the jsonId mapping to deserialize the lists for (let i: number = 0; i < jsonLfxEntries.length; ++i) { const jsonLfxEntry: IJsonLfxEntry = jsonLfxEntries[i]; - const entry: LockfileEntry = graph.entries[i]; + const entry: LfxGraphEntry = graph.entries[i]; for (const jsonLfxDependency of jsonLfxEntry.dependencies) { - const dependency: LockfileDependency = new LockfileDependency({ + const dependency: LfxGraphDependency = new LfxGraphDependency({ name: jsonLfxDependency.name, version: jsonLfxDependency.version, dependencyType: jsonLfxDependency.dependencyType, diff --git a/apps/lockfile-explorer-web/src/parsing/lfxGraphLoader.ts b/apps/lockfile-explorer-web/src/parsing/lfxGraphLoader.ts index 59670de9273..7e0b70eec49 100644 --- a/apps/lockfile-explorer-web/src/parsing/lfxGraphLoader.ts +++ b/apps/lockfile-explorer-web/src/parsing/lfxGraphLoader.ts @@ -4,13 +4,13 @@ import { Path } from '@lifaon/path'; import { - type ILockfileDependencyOptions, - type ILockfileEntryOptions, + type ILfxGraphDependencyOptions, + type ILfxGraphEntryOptions, LfxGraph, - LockfileEntry, - LockfileEntryFilter, - DependencyKind, - LockfileDependency + LfxGraphEntry, + LfxGraphEntryKind, + LfxDependencyKind, + LfxGraphDependency } from '../packlets/lfx-shared'; enum PnpmLockfileVersion { @@ -77,11 +77,11 @@ const packageEntryIdRegex: RegExp = new RegExp('/(.*)/([^/]+)$'); function createLockfileDependency( name: string, version: string, - dependencyType: DependencyKind, - containingEntry: LockfileEntry, + dependencyType: LfxDependencyKind, + containingEntry: LfxGraphEntry, node?: ILockfileNode -): LockfileDependency { - const result: ILockfileDependencyOptions = { +): LfxGraphDependency { + const result: ILfxGraphDependencyOptions = { name, version, dependencyType, @@ -98,12 +98,12 @@ function createLockfileDependency( if (!rootRelativePath) { // eslint-disable-next-line no-console console.error('No root relative path for dependency!', name); - return new LockfileDependency(result); + return new LfxGraphDependency(result); } result.entryId = 'project:' + rootRelativePath.toString(); } else if (result.version.startsWith('/')) { result.entryId = version; - } else if (result.dependencyType === DependencyKind.PEER_DEPENDENCY) { + } else if (result.dependencyType === LfxDependencyKind.Peer) { if (node?.peerDependencies) { result.peerDependencyMeta = { name: result.name, @@ -121,33 +121,31 @@ function createLockfileDependency( } else { result.entryId = '/' + result.name + '/' + result.version; } - return new LockfileDependency(result); + return new LfxGraphDependency(result); } // node is the yaml entry that we are trying to parse function parseDependencies( - dependencies: LockfileDependency[], - lockfileEntry: LockfileEntry, + dependencies: LfxGraphDependency[], + lockfileEntry: LfxGraphEntry, node: ILockfileNode ): void { if (node.dependencies) { for (const [pkgName, pkgVersion] of Object.entries(node.dependencies)) { dependencies.push( - createLockfileDependency(pkgName, pkgVersion, DependencyKind.DEPENDENCY, lockfileEntry) + createLockfileDependency(pkgName, pkgVersion, LfxDependencyKind.Regular, lockfileEntry) ); } } if (node.devDependencies) { for (const [pkgName, pkgVersion] of Object.entries(node.devDependencies)) { - dependencies.push( - createLockfileDependency(pkgName, pkgVersion, DependencyKind.DEV_DEPENDENCY, lockfileEntry) - ); + dependencies.push(createLockfileDependency(pkgName, pkgVersion, LfxDependencyKind.Dev, lockfileEntry)); } } if (node.peerDependencies) { for (const [pkgName, pkgVersion] of Object.entries(node.peerDependencies)) { dependencies.push( - createLockfileDependency(pkgName, pkgVersion, DependencyKind.PEER_DEPENDENCY, lockfileEntry, node) + createLockfileDependency(pkgName, pkgVersion, LfxDependencyKind.Peer, lockfileEntry, node) ); } } @@ -160,14 +158,14 @@ function parseDependencies( function createLockfileEntry(options: { rawEntryId: string; - kind: LockfileEntryFilter; + kind: LfxGraphEntryKind; rawYamlData: ILockfileNode; duplicates?: Set; subspaceName?: string; -}): LockfileEntry { +}): LfxGraphEntry { const { rawEntryId, kind, rawYamlData, duplicates, subspaceName } = options; - const result: ILockfileEntryOptions = { + const result: ILfxGraphEntryOptions = { kind, entryId: '', rawEntryId: '', @@ -182,10 +180,10 @@ function createLockfileEntry(options: { if (rawEntryId === '.') { // Project Root - return new LockfileEntry(result); + return new LfxGraphEntry(result); } - if (kind === LockfileEntryFilter.Project) { + if (kind === LfxGraphEntryKind.Project) { const rootPackageJsonFolderPath = new Path(`common/temp/${subspaceName}/package.json`).dirname() || ''; const packageJsonFolderPath = new Path('.').relative( new Path(rootPackageJsonFolderPath).concat(rawEntryId) @@ -195,7 +193,7 @@ function createLockfileEntry(options: { if (!packageJsonFolderPath || !packageName) { // eslint-disable-next-line no-console console.error('Could not construct path for entry: ', rawEntryId); - return new LockfileEntry(result); + return new LfxGraphEntry(result); } result.packageJsonFolderPath = packageJsonFolderPath.toString(); @@ -251,7 +249,7 @@ function createLockfileEntry(options: { result.entryPackageName; } - const lockfileEntry = new LockfileEntry(result); + const lockfileEntry = new LfxGraphEntry(result); parseDependencies(lockfileEntry.dependencies, lockfileEntry, rawYamlData); return lockfileEntry; } @@ -299,8 +297,8 @@ export function generateLockfileGraph(lockfile: ILockfilePackageType, subspaceNa pnpmLockfileVersion = PnpmLockfileVersion.V6; } const lfxGraph: LfxGraph = new LfxGraph(); - const allEntries: LockfileEntry[] = lfxGraph.entries; - const allEntriesById: { [key: string]: LockfileEntry } = {}; + const allEntries: LfxGraphEntry[] = lfxGraph.entries; + const allEntriesById: { [key: string]: LfxGraphEntry } = {}; const allImporters = []; if (lockfile.importers) { @@ -321,10 +319,10 @@ export function generateLockfileGraph(lockfile: ILockfilePackageType, subspaceNa // console.log('normalized importer key: ', new Path(importerKey).makeAbsolute('/').toString()); // const normalizedPath = new Path(importerKey).makeAbsolute('/').toString(); - const importer: LockfileEntry = createLockfileEntry({ + const importer: LfxGraphEntry = createLockfileEntry({ // entryId: normalizedPath, rawEntryId: importerKey, - kind: LockfileEntryFilter.Project, + kind: LfxGraphEntryKind.Project, rawYamlData: getImporterValue(importerValue, pnpmLockfileVersion), duplicates, subspaceName @@ -340,10 +338,10 @@ export function generateLockfileGraph(lockfile: ILockfilePackageType, subspaceNa for (const [dependencyKey, dependencyValue] of Object.entries(lockfile.packages)) { // const normalizedPath = new Path(dependencyKey).makeAbsolute('/').toString(); - const currEntry: LockfileEntry = createLockfileEntry({ + const currEntry: LfxGraphEntry = createLockfileEntry({ // entryId: normalizedPath, rawEntryId: dependencyKey, - kind: LockfileEntryFilter.Package, + kind: LfxGraphEntryKind.Package, rawYamlData: dependencyValue, subspaceName }); @@ -358,7 +356,7 @@ export function generateLockfileGraph(lockfile: ILockfilePackageType, subspaceNa for (const entry of allEntries) { for (const dependency of entry.dependencies) { // Peer dependencies do not have a matching entry - if (dependency.dependencyType === DependencyKind.PEER_DEPENDENCY) { + if (dependency.dependencyType === LfxDependencyKind.Peer) { continue; } diff --git a/apps/lockfile-explorer-web/src/parsing/readLockfile.ts b/apps/lockfile-explorer-web/src/parsing/readLockfile.ts index bbd780235b8..a5354dfbb26 100644 --- a/apps/lockfile-explorer-web/src/parsing/readLockfile.ts +++ b/apps/lockfile-explorer-web/src/parsing/readLockfile.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { LockfileEntry } from '../packlets/lfx-shared'; +import type { LfxGraphEntry } from '../packlets/lfx-shared'; import * as lfxGraphLoader from './lfxGraphLoader'; const serviceUrl: string = window.appContext.serviceUrl; -export async function readLockfileAsync(): Promise { +export async function readLockfileAsync(): Promise { const response = await fetch(`${serviceUrl}/api/lockfile`); const lockfile: { doc: lfxGraphLoader.ILockfilePackageType; subspaceName: string } = await response.json(); diff --git a/apps/lockfile-explorer-web/src/parsing/test/lockfile.test.ts b/apps/lockfile-explorer-web/src/parsing/test/lockfile.test.ts index 01af2c3ccf6..97b9a963db4 100644 --- a/apps/lockfile-explorer-web/src/parsing/test/lockfile.test.ts +++ b/apps/lockfile-explorer-web/src/parsing/test/lockfile.test.ts @@ -3,14 +3,14 @@ import { TEST_LOCKFILE } from './testLockfile'; import * as lfxGraphLoader from '../lfxGraphLoader'; -import type { LockfileEntry } from '../../packlets/lfx-shared'; +import type { LfxGraphEntry } from '../../packlets/lfx-shared'; describe('LockfileGeneration', () => { it('creates a valid bi-directional graph', () => { const resolvedPackages = lfxGraphLoader.generateLockfileGraph(TEST_LOCKFILE).entries; // Mapping of all the lockfile entries created by the lockfile - const resolvedPackagesMap: { [key: string]: LockfileEntry } = {}; + const resolvedPackagesMap: { [key: string]: LfxGraphEntry } = {}; for (const resolvedPackage of resolvedPackages) { resolvedPackagesMap[resolvedPackage.entryPackageName] = resolvedPackage; } diff --git a/apps/lockfile-explorer-web/src/store/slices/entrySlice.ts b/apps/lockfile-explorer-web/src/store/slices/entrySlice.ts index f25d3bff424..6c3f4c8de50 100644 --- a/apps/lockfile-explorer-web/src/store/slices/entrySlice.ts +++ b/apps/lockfile-explorer-web/src/store/slices/entrySlice.ts @@ -2,7 +2,7 @@ // See LICENSE in the project root for license information. import { createSlice, type PayloadAction, type Reducer } from '@reduxjs/toolkit'; -import { type LockfileEntry, LockfileEntryFilter } from '../../packlets/lfx-shared'; +import { type LfxGraphEntry, LfxGraphEntryKind } from '../../packlets/lfx-shared'; import type { RootState } from '../index'; import { getBookmarksFromStorage, @@ -12,22 +12,22 @@ import { // eslint-disable-next-line @typescript-eslint/consistent-type-definitions type EntryState = { - allEntries: LockfileEntry[]; + allEntries: LfxGraphEntry[]; filters: { - [key in LockfileEntryFilter]: boolean; + [key in LfxGraphEntryKind]: boolean; }; - selectedEntryStack: LockfileEntry[]; - selectedEntryForwardStack: LockfileEntry[]; - bookmarkedEntries: LockfileEntry[]; + selectedEntryStack: LfxGraphEntry[]; + selectedEntryForwardStack: LfxGraphEntry[]; + bookmarkedEntries: LfxGraphEntry[]; }; const initialState: EntryState = { allEntries: [], filters: { - [LockfileEntryFilter.Project]: false, - [LockfileEntryFilter.Package]: true, - [LockfileEntryFilter.SideBySide]: false, - [LockfileEntryFilter.Doppelganger]: false + [LfxGraphEntryKind.Project]: false, + [LfxGraphEntryKind.Package]: true, + [LfxGraphEntryKind.SideBySide]: false, + [LfxGraphEntryKind.Doppelganger]: false }, selectedEntryStack: [], selectedEntryForwardStack: [], @@ -39,7 +39,7 @@ const entrySlice = createSlice({ name: 'entry', initialState, reducers: { - loadEntries: (state, payload: PayloadAction) => { + loadEntries: (state, payload: PayloadAction) => { state.allEntries = payload.payload; // Hydrate the bookmarks state const bookmarkSet = getBookmarksFromStorage(); @@ -49,70 +49,70 @@ const entrySlice = createSlice({ } } }, - setFilter: (state, payload: PayloadAction<{ filter: LockfileEntryFilter; state: boolean }>) => { + setFilter: (state, payload: PayloadAction<{ filter: LfxGraphEntryKind; state: boolean }>) => { state.filters[payload.payload.filter] = payload.payload.state; }, - clearStackAndPush: (state, payload: PayloadAction) => { + clearStackAndPush: (state, payload: PayloadAction) => { state.selectedEntryStack = [payload.payload]; state.selectedEntryForwardStack = []; }, - pushToStack: (state, payload: PayloadAction) => { + pushToStack: (state, payload: PayloadAction) => { state.selectedEntryStack.push(payload.payload); state.selectedEntryForwardStack = []; - if (payload.payload.kind === LockfileEntryFilter.Package) { - state.filters[LockfileEntryFilter.Project] = false; - state.filters[LockfileEntryFilter.Package] = true; + if (payload.payload.kind === LfxGraphEntryKind.Package) { + state.filters[LfxGraphEntryKind.Project] = false; + state.filters[LfxGraphEntryKind.Package] = true; } else { - state.filters[LockfileEntryFilter.Project] = true; - state.filters[LockfileEntryFilter.Package] = false; + state.filters[LfxGraphEntryKind.Project] = true; + state.filters[LfxGraphEntryKind.Package] = false; } }, popStack: (state) => { if (state.selectedEntryStack.length > 1) { - const poppedEntry = state.selectedEntryStack.pop() as LockfileEntry; + const poppedEntry = state.selectedEntryStack.pop() as LfxGraphEntry; state.selectedEntryForwardStack.push(poppedEntry); if (state.selectedEntryStack.length >= 1) { const currEntry = state.selectedEntryStack[state.selectedEntryStack.length - 1]; - if (currEntry.kind === LockfileEntryFilter.Package) { - state.filters[LockfileEntryFilter.Project] = false; - state.filters[LockfileEntryFilter.Package] = true; + if (currEntry.kind === LfxGraphEntryKind.Package) { + state.filters[LfxGraphEntryKind.Project] = false; + state.filters[LfxGraphEntryKind.Package] = true; } else { - state.filters[LockfileEntryFilter.Project] = true; - state.filters[LockfileEntryFilter.Package] = false; + state.filters[LfxGraphEntryKind.Project] = true; + state.filters[LfxGraphEntryKind.Package] = false; } } } }, forwardStack: (state) => { if (state.selectedEntryForwardStack.length > 0) { - const poppedEntry = state.selectedEntryForwardStack.pop() as LockfileEntry; + const poppedEntry = state.selectedEntryForwardStack.pop() as LfxGraphEntry; state.selectedEntryStack.push(poppedEntry); - if (poppedEntry.kind === LockfileEntryFilter.Package) { - state.filters[LockfileEntryFilter.Project] = false; - state.filters[LockfileEntryFilter.Package] = true; + if (poppedEntry.kind === LfxGraphEntryKind.Package) { + state.filters[LfxGraphEntryKind.Project] = false; + state.filters[LfxGraphEntryKind.Package] = true; } else { - state.filters[LockfileEntryFilter.Project] = true; - state.filters[LockfileEntryFilter.Package] = false; + state.filters[LfxGraphEntryKind.Project] = true; + state.filters[LfxGraphEntryKind.Package] = false; } } }, - addBookmark: (state, payload: PayloadAction) => { + addBookmark: (state, payload: PayloadAction) => { if (!state.bookmarkedEntries.includes(payload.payload)) { state.bookmarkedEntries.push(payload.payload); saveBookmarkToLocalStorage(payload.payload); } }, - removeBookmark: (state, payload: PayloadAction) => { + removeBookmark: (state, payload: PayloadAction) => { state.bookmarkedEntries = state.bookmarkedEntries.filter( - (entry: LockfileEntry) => entry.rawEntryId !== payload.payload.rawEntryId + (entry: LfxGraphEntry) => entry.rawEntryId !== payload.payload.rawEntryId ); removeBookmarkFromLocalStorage(payload.payload); } } }); -export const selectCurrentEntry = (state: RootState): LockfileEntry | undefined => { +export const selectCurrentEntry = (state: RootState): LfxGraphEntry | undefined => { if (state.entry.selectedEntryStack.length) { return state.entry.selectedEntryStack[state.entry.selectedEntryStack.length - 1]; } else { @@ -120,15 +120,15 @@ export const selectCurrentEntry = (state: RootState): LockfileEntry | undefined } }; -export const selectFilteredEntries = (state: RootState): LockfileEntry[] => { - const filteredEntries: LockfileEntry[] = []; - if (state.entry.filters[LockfileEntryFilter.Package]) { +export const selectFilteredEntries = (state: RootState): LfxGraphEntry[] => { + const filteredEntries: LfxGraphEntry[] = []; + if (state.entry.filters[LfxGraphEntryKind.Package]) { filteredEntries.push( - ...state.entry.allEntries.filter((entry) => entry.kind === LockfileEntryFilter.Package) + ...state.entry.allEntries.filter((entry) => entry.kind === LfxGraphEntryKind.Package) ); - } else if (state.entry.filters[LockfileEntryFilter.Project]) { + } else if (state.entry.filters[LfxGraphEntryKind.Project]) { filteredEntries.push( - ...state.entry.allEntries.filter((entry) => entry.kind === LockfileEntryFilter.Project) + ...state.entry.allEntries.filter((entry) => entry.kind === LfxGraphEntryKind.Project) ); } return filteredEntries; diff --git a/apps/lockfile-explorer/src/state/index.ts b/apps/lockfile-explorer/src/state/index.ts index 5cb346ae230..8cb889602e3 100644 --- a/apps/lockfile-explorer/src/state/index.ts +++ b/apps/lockfile-explorer/src/state/index.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import { type IJsonLfxWorkspace } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; +import type { IJsonLfxWorkspace } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; export interface IAppState { lockfileExplorerProjectRoot: string; From bd95813878171d12821ca18091817c7101d5df53 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 21:35:23 -0700 Subject: [PATCH 04/26] Move lfxGraphLoader.ts from client to server --- apps/lockfile-explorer-web/src/parsing/readLockfile.ts | 1 - .../src/graph}/lfxGraphLoader.ts | 9 ++------- .../src/graph}/test/lockfile.test.ts | 2 +- .../src/graph}/test/serializeToJson.test.ts | 6 +++--- .../src/graph}/test/testLockfile.ts | 0 5 files changed, 6 insertions(+), 12 deletions(-) rename apps/{lockfile-explorer-web/src/parsing => lockfile-explorer/src/graph}/lfxGraphLoader.ts (98%) rename apps/{lockfile-explorer-web/src/parsing => lockfile-explorer/src/graph}/test/lockfile.test.ts (95%) rename apps/{lockfile-explorer-web/src/parsing => lockfile-explorer/src/graph}/test/serializeToJson.test.ts (96%) rename apps/{lockfile-explorer-web/src/parsing => lockfile-explorer/src/graph}/test/testLockfile.ts (100%) diff --git a/apps/lockfile-explorer-web/src/parsing/readLockfile.ts b/apps/lockfile-explorer-web/src/parsing/readLockfile.ts index a5354dfbb26..160d915b4d7 100644 --- a/apps/lockfile-explorer-web/src/parsing/readLockfile.ts +++ b/apps/lockfile-explorer-web/src/parsing/readLockfile.ts @@ -2,7 +2,6 @@ // See LICENSE in the project root for license information. import type { LfxGraphEntry } from '../packlets/lfx-shared'; -import * as lfxGraphLoader from './lfxGraphLoader'; const serviceUrl: string = window.appContext.serviceUrl; diff --git a/apps/lockfile-explorer-web/src/parsing/lfxGraphLoader.ts b/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts similarity index 98% rename from apps/lockfile-explorer-web/src/parsing/lfxGraphLoader.ts rename to apps/lockfile-explorer/src/graph/lfxGraphLoader.ts index 7e0b70eec49..63992ef38fc 100644 --- a/apps/lockfile-explorer-web/src/parsing/lfxGraphLoader.ts +++ b/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import { Path } from '@lifaon/path'; - import { type ILfxGraphDependencyOptions, type ILfxGraphEntryOptions, @@ -11,7 +9,8 @@ import { LfxGraphEntryKind, LfxDependencyKind, LfxGraphDependency -} from '../packlets/lfx-shared'; +} from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; +import { Path } from '@lifaon/path'; enum PnpmLockfileVersion { V6, @@ -96,7 +95,6 @@ function createLockfileDependency( new Path(containingEntry.packageJsonFolderPath).concat(relativePath) ); if (!rootRelativePath) { - // eslint-disable-next-line no-console console.error('No root relative path for dependency!', name); return new LfxGraphDependency(result); } @@ -115,7 +113,6 @@ function createLockfileDependency( }; result.entryId = 'Peer: ' + result.name; } else { - // eslint-disable-next-line no-console console.error('Peer dependencies info missing!', node); } } else { @@ -191,7 +188,6 @@ function createLockfileEntry(options: { const packageName = new Path(rawEntryId).basename(); if (!packageJsonFolderPath || !packageName) { - // eslint-disable-next-line no-console console.error('Could not construct path for entry: ', rawEntryId); return new LfxGraphEntry(result); } @@ -368,7 +364,6 @@ export function generateLockfileGraph(lockfile: ILockfilePackageType, subspaceNa } else { if (dependency.entryId.startsWith('/')) { // Local package - // eslint-disable-next-line no-console console.error('Could not resolve dependency entryId: ', dependency.entryId, dependency); } } diff --git a/apps/lockfile-explorer-web/src/parsing/test/lockfile.test.ts b/apps/lockfile-explorer/src/graph/test/lockfile.test.ts similarity index 95% rename from apps/lockfile-explorer-web/src/parsing/test/lockfile.test.ts rename to apps/lockfile-explorer/src/graph/test/lockfile.test.ts index 97b9a963db4..fd16905e4c4 100644 --- a/apps/lockfile-explorer-web/src/parsing/test/lockfile.test.ts +++ b/apps/lockfile-explorer/src/graph/test/lockfile.test.ts @@ -3,7 +3,7 @@ import { TEST_LOCKFILE } from './testLockfile'; import * as lfxGraphLoader from '../lfxGraphLoader'; -import type { LfxGraphEntry } from '../../packlets/lfx-shared'; +import type { LfxGraphEntry } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; describe('LockfileGeneration', () => { it('creates a valid bi-directional graph', () => { diff --git a/apps/lockfile-explorer-web/src/parsing/test/serializeToJson.test.ts b/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts similarity index 96% rename from apps/lockfile-explorer-web/src/parsing/test/serializeToJson.test.ts rename to apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts index 2dc9cbfb808..791bd0d3b3b 100644 --- a/apps/lockfile-explorer-web/src/parsing/test/serializeToJson.test.ts +++ b/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import { TEST_LOCKFILE } from './testLockfile'; +import { lfxGraphSerializer, type LfxGraph } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; + import * as lfxGraphLoader from '../lfxGraphLoader'; -import { lfxGraphSerializer } from '../../packlets/lfx-shared'; -import type { LfxGraph } from '../../packlets/lfx-shared'; +import { TEST_LOCKFILE } from './testLockfile'; describe('serializeToJson', () => { it('serializes a simple graph', () => { diff --git a/apps/lockfile-explorer-web/src/parsing/test/testLockfile.ts b/apps/lockfile-explorer/src/graph/test/testLockfile.ts similarity index 100% rename from apps/lockfile-explorer-web/src/parsing/test/testLockfile.ts rename to apps/lockfile-explorer/src/graph/test/testLockfile.ts From d05e88b484cf8b9a531b3dfbaf1021817d128298 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 21:35:54 -0700 Subject: [PATCH 05/26] Move "@lifaon/path" dependency from client to server (we'll probably eliminate it entirely soon) --- apps/lockfile-explorer-web/package.json | 1 - apps/lockfile-explorer/package.json | 1 + common/config/subspaces/default/pnpm-lock.yaml | 6 +++--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/lockfile-explorer-web/package.json b/apps/lockfile-explorer-web/package.json index 683e6a8c844..c7b8c3561aa 100644 --- a/apps/lockfile-explorer-web/package.json +++ b/apps/lockfile-explorer-web/package.json @@ -22,7 +22,6 @@ } }, "dependencies": { - "@lifaon/path": "~2.1.0", "@reduxjs/toolkit": "~1.8.6", "@rushstack/rush-themed-ui": "workspace:*", "react-dom": "~17.0.2", diff --git a/apps/lockfile-explorer/package.json b/apps/lockfile-explorer/package.json index 0110d91bd00..67e847a8b14 100644 --- a/apps/lockfile-explorer/package.json +++ b/apps/lockfile-explorer/package.json @@ -60,6 +60,7 @@ }, "dependencies": { "@microsoft/rush-lib": "workspace:*", + "@lifaon/path": "~2.1.0", "@rushstack/node-core-library": "workspace:*", "@rushstack/terminal": "workspace:*", "cors": "~2.8.5", diff --git a/common/config/subspaces/default/pnpm-lock.yaml b/common/config/subspaces/default/pnpm-lock.yaml index 8331a3ef056..e4e613f0800 100644 --- a/common/config/subspaces/default/pnpm-lock.yaml +++ b/common/config/subspaces/default/pnpm-lock.yaml @@ -193,6 +193,9 @@ importers: ../../../apps/lockfile-explorer: dependencies: + '@lifaon/path': + specifier: ~2.1.0 + version: 2.1.0 '@microsoft/rush-lib': specifier: workspace:* version: link:../../libraries/rush-lib @@ -263,9 +266,6 @@ importers: ../../../apps/lockfile-explorer-web: dependencies: - '@lifaon/path': - specifier: ~2.1.0 - version: 2.1.0 '@reduxjs/toolkit': specifier: ~1.8.6 version: 1.8.6(react-redux@8.0.7)(react@17.0.2) From 1349c78f4b5df3d64f49a6aa22f243be8b3170ec Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 21:49:56 -0700 Subject: [PATCH 06/26] Integrate IJsonLfxWorkspace as part of the graph --- .../src/packlets/lfx-shared/IJsonLfxGraph.ts | 3 +++ .../src/packlets/lfx-shared/IJsonLfxWorkspace.ts | 10 +++++----- .../src/packlets/lfx-shared/LfxGraph.ts | 6 ++++++ .../src/packlets/lfx-shared/lfxGraphSerializer.ts | 4 ++-- apps/lockfile-explorer/src/graph/lfxGraphLoader.ts | 11 ++++++++--- .../lockfile-explorer/src/graph/test/lockfile.test.ts | 7 ++++--- .../src/graph/test/serializeToJson.test.ts | 11 ++++++++--- apps/lockfile-explorer/src/graph/test/testLockfile.ts | 8 ++++++++ apps/lockfile-explorer/src/utils/init.ts | 2 +- 9 files changed, 45 insertions(+), 17 deletions(-) diff --git a/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxGraph.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxGraph.ts index 6f6c96a11d8..7632e332f8f 100644 --- a/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxGraph.ts +++ b/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxGraph.ts @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. +import type { IJsonLfxWorkspace } from './IJsonLfxWorkspace'; + export enum LfxGraphEntryKind { Project = 1, Package = 2, @@ -57,5 +59,6 @@ export interface IJsonLfxEntry { } export interface IJsonLfxGraph { + workspace: IJsonLfxWorkspace; entries: IJsonLfxEntry[]; } diff --git a/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxWorkspace.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxWorkspace.ts index c9ad00998c5..31c081d1c91 100644 --- a/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxWorkspace.ts +++ b/apps/lockfile-explorer-web/src/packlets/lfx-shared/IJsonLfxWorkspace.ts @@ -5,13 +5,13 @@ export interface IJsonLfxWorkspaceRushConfig { /** * The rushVersion from rush.json. */ - rushVersion: string; + readonly rushVersion: string; /** * If the subspaces feature is enabled and a subspace was loaded, the name of the subspace. * Otherwise this will be an empty string. */ - subspaceName: string; + readonly subspaceName: string; } export interface IJsonLfxWorkspace { @@ -19,16 +19,16 @@ export interface IJsonLfxWorkspace { * Absolute path to the workspace folder that is opened by the app. * Relative paths are generally relative to this path. */ - workspaceRootFolder: string; + readonly workspaceRootFolder: string; /** * The path to the pnpm-lock.yaml file. */ - pnpmLockfilePath: string; + readonly pnpmLockfilePath: string; /** * If this is a Rush workspace (versus a plain PNPM workspace), then * this section will be defined. */ - rushConfig: IJsonLfxWorkspaceRushConfig | undefined; + readonly rushConfig: IJsonLfxWorkspaceRushConfig | undefined; } diff --git a/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts index 55817a7e59d..05a733df473 100644 --- a/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts +++ b/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts @@ -2,6 +2,7 @@ // See LICENSE in the project root for license information. import type { LfxDependencyKind, IJsonPeerDependencyMeta, LfxGraphEntryKind } from './IJsonLfxGraph'; +import type { IJsonLfxWorkspace } from './IJsonLfxWorkspace'; export interface ILfxGraphDependencyOptions { name: string; @@ -124,5 +125,10 @@ export class LfxGraphEntry { } export class LfxGraph { + public workspace: IJsonLfxWorkspace; public readonly entries: LfxGraphEntry[] = []; + + public constructor(workspace: IJsonLfxWorkspace) { + this.workspace = { ...workspace }; + } } diff --git a/apps/lockfile-explorer-web/src/packlets/lfx-shared/lfxGraphSerializer.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/lfxGraphSerializer.ts index 568add1db2f..b175dbd2080 100644 --- a/apps/lockfile-explorer-web/src/packlets/lfx-shared/lfxGraphSerializer.ts +++ b/apps/lockfile-explorer-web/src/packlets/lfx-shared/lfxGraphSerializer.ts @@ -70,11 +70,11 @@ export function serializeToJson(graph: LfxGraph): IJsonLfxGraph { jsonLfxEntry.referrerJsonIds = entry.referrers.map((x) => toJsonId(x)); } - return { entries: jsonLfxEntries }; + return { workspace: graph.workspace, entries: jsonLfxEntries }; } export function deserializeFromJson(jsonLfxGraph: IJsonLfxGraph): LfxGraph { - const graph: LfxGraph = new LfxGraph(); + const graph: LfxGraph = new LfxGraph(jsonLfxGraph.workspace); const entries: LfxGraphEntry[] = graph.entries; diff --git a/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts b/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts index 63992ef38fc..a8c2611310a 100644 --- a/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts +++ b/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts @@ -8,7 +8,8 @@ import { LfxGraphEntry, LfxGraphEntryKind, LfxDependencyKind, - LfxGraphDependency + LfxGraphDependency, + type IJsonLfxWorkspace } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; import { Path } from '@lifaon/path'; @@ -287,12 +288,16 @@ function getImporterValue( * * @returns A list of all the LockfileEntries in the lockfile. */ -export function generateLockfileGraph(lockfile: ILockfilePackageType, subspaceName?: string): LfxGraph { +export function generateLockfileGraph( + workspace: IJsonLfxWorkspace, + lockfile: ILockfilePackageType, + subspaceName?: string +): LfxGraph { let pnpmLockfileVersion: PnpmLockfileVersion = PnpmLockfileVersion.V5; if (parseInt(lockfile.lockfileVersion.toString(), 10) === 6) { pnpmLockfileVersion = PnpmLockfileVersion.V6; } - const lfxGraph: LfxGraph = new LfxGraph(); + const lfxGraph: LfxGraph = new LfxGraph(workspace); const allEntries: LfxGraphEntry[] = lfxGraph.entries; const allEntriesById: { [key: string]: LfxGraphEntry } = {}; diff --git a/apps/lockfile-explorer/src/graph/test/lockfile.test.ts b/apps/lockfile-explorer/src/graph/test/lockfile.test.ts index fd16905e4c4..fc2ac961cd8 100644 --- a/apps/lockfile-explorer/src/graph/test/lockfile.test.ts +++ b/apps/lockfile-explorer/src/graph/test/lockfile.test.ts @@ -1,13 +1,14 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import { TEST_LOCKFILE } from './testLockfile'; -import * as lfxGraphLoader from '../lfxGraphLoader'; import type { LfxGraphEntry } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; +import { TEST_WORKSPACE, TEST_LOCKFILE } from './testLockfile'; +import * as lfxGraphLoader from '../lfxGraphLoader'; + describe('LockfileGeneration', () => { it('creates a valid bi-directional graph', () => { - const resolvedPackages = lfxGraphLoader.generateLockfileGraph(TEST_LOCKFILE).entries; + const resolvedPackages = lfxGraphLoader.generateLockfileGraph(TEST_WORKSPACE, TEST_LOCKFILE).entries; // Mapping of all the lockfile entries created by the lockfile const resolvedPackagesMap: { [key: string]: LfxGraphEntry } = {}; diff --git a/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts b/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts index 791bd0d3b3b..6fdfd97a6e2 100644 --- a/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts +++ b/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts @@ -4,11 +4,11 @@ import { lfxGraphSerializer, type LfxGraph } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; import * as lfxGraphLoader from '../lfxGraphLoader'; -import { TEST_LOCKFILE } from './testLockfile'; +import { TEST_WORKSPACE, TEST_LOCKFILE } from './testLockfile'; describe('serializeToJson', () => { it('serializes a simple graph', () => { - const graph = lfxGraphLoader.generateLockfileGraph(TEST_LOCKFILE); + const graph = lfxGraphLoader.generateLockfileGraph(TEST_WORKSPACE, TEST_LOCKFILE); expect(lfxGraphSerializer.serializeToJson(graph)).toMatchInlineSnapshot(` Object { @@ -99,12 +99,17 @@ Object { "transitivePeerDependencies": Array [], }, ], + "workspace": Object { + "pnpmLockfilePath": "/test/pnpm-lock.yaml", + "rushConfig": undefined, + "workspaceRootFolder": "/test", + }, } `); }); it('deserializes a simple graph', () => { - const originalGraph = lfxGraphLoader.generateLockfileGraph(TEST_LOCKFILE); + const originalGraph = lfxGraphLoader.generateLockfileGraph(TEST_WORKSPACE, TEST_LOCKFILE); const serialized: string = JSON.stringify( lfxGraphSerializer.serializeToJson(originalGraph), diff --git a/apps/lockfile-explorer/src/graph/test/testLockfile.ts b/apps/lockfile-explorer/src/graph/test/testLockfile.ts index cd364697874..c1c76bf183b 100644 --- a/apps/lockfile-explorer/src/graph/test/testLockfile.ts +++ b/apps/lockfile-explorer/src/graph/test/testLockfile.ts @@ -1,6 +1,14 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. +import type { IJsonLfxWorkspace } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; + +export const TEST_WORKSPACE: IJsonLfxWorkspace = { + workspaceRootFolder: '/test', + pnpmLockfilePath: '/test/pnpm-lock.yaml', + rushConfig: undefined +}; + export const TEST_LOCKFILE = { lockfileVersion: 5.3, importers: { diff --git a/apps/lockfile-explorer/src/utils/init.ts b/apps/lockfile-explorer/src/utils/init.ts index 7cf20374902..73856ea7943 100644 --- a/apps/lockfile-explorer/src/utils/init.ts +++ b/apps/lockfile-explorer/src/utils/init.ts @@ -16,7 +16,7 @@ export const init = (options: { appVersion: string; debugMode: boolean; subspaceName: string; -}): IAppState => { +}): Omit => { const { lockfileExplorerProjectRoot, appVersion, debugMode, subspaceName } = options; const currentWorkingDirectory: string = path.resolve(process.cwd()); From eca298e1ead801edf05c6c24dd9809de18d963f2 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 22:09:46 -0700 Subject: [PATCH 07/26] Copy the "lfx-shared" because lockfile-explorer-web is a devDependency --- apps/lockfile-explorer-web/package.json | 10 ------- apps/lockfile-explorer/config/heft.json | 27 +++++++++++++++++++ .../cli/explorer/ExplorerCommandLineParser.ts | 2 +- .../src/graph/lfxGraphLoader.ts | 5 ++-- .../src/graph/test/lockfile.test.ts | 2 +- .../src/graph/test/serializeToJson.test.ts | 2 +- .../src/graph/test/testLockfile.ts | 2 +- apps/lockfile-explorer/src/state/index.ts | 2 +- 8 files changed, 35 insertions(+), 17 deletions(-) diff --git a/apps/lockfile-explorer-web/package.json b/apps/lockfile-explorer-web/package.json index c7b8c3561aa..59923434733 100644 --- a/apps/lockfile-explorer-web/package.json +++ b/apps/lockfile-explorer-web/package.json @@ -11,16 +11,6 @@ "_phase:build": "heft run --only build -- --clean", "_phase:test": "heft run --only test -- --clean" }, - "exports": { - "./packlets/lfx-shared": "./lib-commonjs/packlets/lfx-shared/index.js" - }, - "typesVersions": { - "*": { - "packlets/lfx-shared": [ - "lib/packlets/lfx-shared/index.d.ts" - ] - } - }, "dependencies": { "@reduxjs/toolkit": "~1.8.6", "@rushstack/rush-themed-ui": "workspace:*", diff --git a/apps/lockfile-explorer/config/heft.json b/apps/lockfile-explorer/config/heft.json index 425aa0a60d9..7150e66582b 100644 --- a/apps/lockfile-explorer/config/heft.json +++ b/apps/lockfile-explorer/config/heft.json @@ -14,6 +14,8 @@ "phasesByName": { "build": { + "cleanFiles": [{ "includeGlobs": ["temp/lfx-shared"] }], + "tasksByName": { "copy-app-bundle": { "taskPlugin": { @@ -34,6 +36,31 @@ ] } } + }, + + "pre-compile-copy": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft", + "pluginName": "copy-files-plugin", + "options": { + "copyOperations": [ + { + "sourcePath": "node_modules/@rushstack/lockfile-explorer-web/lib/packlets/lfx-shared", + "destinationFolders": ["temp/lfx-shared"], + "includeGlobs": ["*.d.ts"] + }, + { + "sourcePath": "node_modules/@rushstack/lockfile-explorer-web/lib-commonjs/packlets/lfx-shared", + "destinationFolders": ["temp/lfx-shared"], + "includeGlobs": ["*.js", "*.map"] + } + ] + } + } + }, + "typescript": { + // The "typescript" task should not run until after "pre-compile-copy" completes. + "taskDependencies": ["pre-compile-copy"] } } } diff --git a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts index fe8d92765d9..cbfe72e7cc5 100644 --- a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts +++ b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts @@ -16,7 +16,7 @@ import { type IRequiredCommandLineStringParameter } from '@rushstack/ts-command-line'; import type { Lockfile } from '@pnpm/lockfile-types'; -import type { IAppContext } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; +import type { IAppContext } from '../../../temp/lfx-shared'; import type { IAppState } from '../../state'; import { init } from '../../utils/init'; diff --git a/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts b/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts index a8c2611310a..bdeeb4ff49b 100644 --- a/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts +++ b/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. +import { Path } from '@lifaon/path'; + import { type ILfxGraphDependencyOptions, type ILfxGraphEntryOptions, @@ -10,8 +12,7 @@ import { LfxDependencyKind, LfxGraphDependency, type IJsonLfxWorkspace -} from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; -import { Path } from '@lifaon/path'; +} from '../../temp/lfx-shared'; enum PnpmLockfileVersion { V6, diff --git a/apps/lockfile-explorer/src/graph/test/lockfile.test.ts b/apps/lockfile-explorer/src/graph/test/lockfile.test.ts index fc2ac961cd8..01d7acdbb23 100644 --- a/apps/lockfile-explorer/src/graph/test/lockfile.test.ts +++ b/apps/lockfile-explorer/src/graph/test/lockfile.test.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { LfxGraphEntry } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; +import type { LfxGraphEntry } from '../../../temp/lfx-shared'; import { TEST_WORKSPACE, TEST_LOCKFILE } from './testLockfile'; import * as lfxGraphLoader from '../lfxGraphLoader'; diff --git a/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts b/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts index 6fdfd97a6e2..d298903d61f 100644 --- a/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts +++ b/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import { lfxGraphSerializer, type LfxGraph } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; +import { lfxGraphSerializer, type LfxGraph } from '../../../temp/lfx-shared'; import * as lfxGraphLoader from '../lfxGraphLoader'; import { TEST_WORKSPACE, TEST_LOCKFILE } from './testLockfile'; diff --git a/apps/lockfile-explorer/src/graph/test/testLockfile.ts b/apps/lockfile-explorer/src/graph/test/testLockfile.ts index c1c76bf183b..3f8a7bfca06 100644 --- a/apps/lockfile-explorer/src/graph/test/testLockfile.ts +++ b/apps/lockfile-explorer/src/graph/test/testLockfile.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { IJsonLfxWorkspace } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; +import type { IJsonLfxWorkspace } from '../../../temp/lfx-shared'; export const TEST_WORKSPACE: IJsonLfxWorkspace = { workspaceRootFolder: '/test', diff --git a/apps/lockfile-explorer/src/state/index.ts b/apps/lockfile-explorer/src/state/index.ts index 8cb889602e3..529211b045d 100644 --- a/apps/lockfile-explorer/src/state/index.ts +++ b/apps/lockfile-explorer/src/state/index.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { IJsonLfxWorkspace } from '@rushstack/lockfile-explorer-web/packlets/lfx-shared'; +import type { IJsonLfxWorkspace } from '../../temp/lfx-shared'; export interface IAppState { lockfileExplorerProjectRoot: string; From 56113cfedc73391f8f827551d7136a8c7409fd97 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 22:22:44 -0700 Subject: [PATCH 08/26] Add "tslib" dependency for the server --- apps/lockfile-explorer/package.json | 11 ++++++----- common/config/subspaces/default/pnpm-lock.yaml | 3 +++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/lockfile-explorer/package.json b/apps/lockfile-explorer/package.json index 67e847a8b14..6969a39773d 100644 --- a/apps/lockfile-explorer/package.json +++ b/apps/lockfile-explorer/package.json @@ -59,18 +59,19 @@ "@types/semver": "7.5.0" }, "dependencies": { - "@microsoft/rush-lib": "workspace:*", + "tslib": "~2.8.1", "@lifaon/path": "~2.1.0", + "@microsoft/rush-lib": "workspace:*", + "@pnpm/dependency-path-lockfile-pre-v9": "npm:@pnpm/dependency-path@~2.1.2", "@rushstack/node-core-library": "workspace:*", + "@rushstack/rush-sdk": "workspace:*", "@rushstack/terminal": "workspace:*", + "@rushstack/ts-command-line": "workspace:*", "cors": "~2.8.5", "express": "4.20.0", "js-yaml": "~3.13.1", "open": "~8.4.0", - "update-notifier": "~5.1.0", - "@pnpm/dependency-path-lockfile-pre-v9": "npm:@pnpm/dependency-path@~2.1.2", "semver": "~7.5.4", - "@rushstack/rush-sdk": "workspace:*", - "@rushstack/ts-command-line": "workspace:*" + "update-notifier": "~5.1.0" } } diff --git a/common/config/subspaces/default/pnpm-lock.yaml b/common/config/subspaces/default/pnpm-lock.yaml index e4e613f0800..03956e606a4 100644 --- a/common/config/subspaces/default/pnpm-lock.yaml +++ b/common/config/subspaces/default/pnpm-lock.yaml @@ -229,6 +229,9 @@ importers: semver: specifier: ~7.5.4 version: 7.5.4 + tslib: + specifier: ~2.8.1 + version: 2.8.1 update-notifier: specifier: ~5.1.0 version: 5.1.0 From bf30048511a8fc9501376b47f28d9ff15d035d97 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 22:27:55 -0700 Subject: [PATCH 09/26] Wire up readLockfileAsync() again --- .../src/parsing/readLockfile.ts | 16 ++++++--- .../cli/explorer/ExplorerCommandLineParser.ts | 34 +++++++++++++++++-- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/apps/lockfile-explorer-web/src/parsing/readLockfile.ts b/apps/lockfile-explorer-web/src/parsing/readLockfile.ts index 160d915b4d7..5c44f0887c6 100644 --- a/apps/lockfile-explorer-web/src/parsing/readLockfile.ts +++ b/apps/lockfile-explorer-web/src/parsing/readLockfile.ts @@ -1,13 +1,21 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { LfxGraphEntry } from '../packlets/lfx-shared'; +import { + type LfxGraph, + lfxGraphSerializer, + type IJsonLfxGraph, + type LfxGraphEntry +} from '../packlets/lfx-shared'; const serviceUrl: string = window.appContext.serviceUrl; export async function readLockfileAsync(): Promise { - const response = await fetch(`${serviceUrl}/api/lockfile`); - const lockfile: { doc: lfxGraphLoader.ILockfilePackageType; subspaceName: string } = await response.json(); + // eslint-disable-next-line no-console + console.log('Loading graph'); - return lfxGraphLoader.generateLockfileGraph(lockfile.doc, lockfile.subspaceName).entries; + const response = await fetch(`${serviceUrl}/api/graph`); + const jsonGraph: IJsonLfxGraph = await response.json(); + const graph: LfxGraph = lfxGraphSerializer.deserializeFromJson(jsonGraph); + return graph.entries; } diff --git a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts index cbfe72e7cc5..75ac056ca32 100644 --- a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts +++ b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts @@ -16,11 +16,17 @@ import { type IRequiredCommandLineStringParameter } from '@rushstack/ts-command-line'; import type { Lockfile } from '@pnpm/lockfile-types'; -import type { IAppContext } from '../../../temp/lfx-shared'; +import { + type LfxGraph, + lfxGraphSerializer, + type IAppContext, + type IJsonLfxGraph +} from '../../../temp/lfx-shared'; import type { IAppState } from '../../state'; import { init } from '../../utils/init'; import { convertLockfileV6DepPathToV5DepPath, getShrinkwrapFileMajorVersion } from '../../utils/shrinkwrap'; +import * as lfxGraphLoader from '../../graph/lfxGraphLoader'; const EXPLORER_TOOL_FILENAME: 'lockfile-explorer' = 'lockfile-explorer'; @@ -166,8 +172,30 @@ export class ExplorerCommandLineParser extends CommandLineParser { res.status(200).send(); }); - app.get('/api/workspace', (req: express.Request, res: express.Response) => { - res.type('application/javascript').send(appState.lfxWorkspace); + app.get('/api/graph', async (req: express.Request, res: express.Response) => { + const pnpmLockfileText: string = await FileSystem.readFileAsync(appState.pnpmLockfileLocation); + const doc = yaml.load(pnpmLockfileText) as Lockfile; + + const { packages, lockfileVersion } = doc; + + const shrinkwrapFileMajorVersion: number = getShrinkwrapFileMajorVersion(lockfileVersion); + + if (packages && shrinkwrapFileMajorVersion === 6) { + const updatedPackages: Lockfile['packages'] = {}; + for (const [dependencyPath, dependency] of Object.entries(packages)) { + updatedPackages[convertLockfileV6DepPathToV5DepPath(dependencyPath)] = dependency; + } + doc.packages = updatedPackages; + } + + const graph: LfxGraph = lfxGraphLoader.generateLockfileGraph( + appState.lfxWorkspace, + doc as lfxGraphLoader.ILockfilePackageType, + appState.lfxWorkspace.rushConfig?.subspaceName ?? '' + ); + + const jsonGraph: IJsonLfxGraph = lfxGraphSerializer.serializeToJson(graph); + res.type('application/json').send(jsonGraph); }); app.post( From aeb41084427da97dbf1afa65d83ad7832fe2881a Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 22:29:05 -0700 Subject: [PATCH 10/26] Revert launch.json change --- apps/lockfile-explorer/.vscode/launch.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/lockfile-explorer/.vscode/launch.json b/apps/lockfile-explorer/.vscode/launch.json index 10b8aff39f2..f1cdf885db1 100644 --- a/apps/lockfile-explorer/.vscode/launch.json +++ b/apps/lockfile-explorer/.vscode/launch.json @@ -19,8 +19,8 @@ "request": "launch", "name": "Run in specified folder", "program": "${workspaceFolder}/lib/start-explorer.js", - "cwd": "C:\\Git\\lockfile-explorer-demos", - //"cwd": "(your project path)", + //"cwd": "C:\\Git\\lockfile-explorer-demos", + "cwd": "(your project path)", "args": ["--debug"], "sourceMaps": true } From c55a7b6661ba83f26d0fc5c4811c5e28068f9f40 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 22:30:12 -0700 Subject: [PATCH 11/26] rush change --- .../octogonz-lfx-fixes2_2025-09-14-05-29.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 common/changes/@rushstack/lockfile-explorer/octogonz-lfx-fixes2_2025-09-14-05-29.json diff --git a/common/changes/@rushstack/lockfile-explorer/octogonz-lfx-fixes2_2025-09-14-05-29.json b/common/changes/@rushstack/lockfile-explorer/octogonz-lfx-fixes2_2025-09-14-05-29.json new file mode 100644 index 00000000000..22d17643a68 --- /dev/null +++ b/common/changes/@rushstack/lockfile-explorer/octogonz-lfx-fixes2_2025-09-14-05-29.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@rushstack/lockfile-explorer", + "comment": "", + "type": "none" + } + ], + "packageName": "@rushstack/lockfile-explorer" +} \ No newline at end of file From 9608782955e3159f857d5b308230069211724fc6 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 22:43:42 -0700 Subject: [PATCH 12/26] Include new files in published package --- apps/lockfile-explorer/.npmignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/lockfile-explorer/.npmignore b/apps/lockfile-explorer/.npmignore index bc349f9a4be..97a5f164d30 100644 --- a/apps/lockfile-explorer/.npmignore +++ b/apps/lockfile-explorer/.npmignore @@ -30,3 +30,6 @@ # --------------------------------------------------------------------------- # DO NOT MODIFY ABOVE THIS LINE! Add any project-specific overrides below. # --------------------------------------------------------------------------- + +# heft.json copies this folder from lockfile-explorer-web: +!/temp/lfx-shared/** From 33794a01394cdf807921bde9ab51a654430e2a0c Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sat, 13 Sep 2025 23:27:51 -0700 Subject: [PATCH 13/26] Delete the obsolete /api/lockfile endpoint --- .../cli/explorer/ExplorerCommandLineParser.ts | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts index 75ac056ca32..2b63674d936 100644 --- a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts +++ b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts @@ -141,27 +141,6 @@ export class ExplorerCommandLineParser extends CommandLineParser { app.use('/favicon.ico', express.static(distFolderPath, { index: 'favicon.ico' })); - app.get('/api/lockfile', async (req: express.Request, res: express.Response) => { - const pnpmLockfileText: string = await FileSystem.readFileAsync(appState.pnpmLockfileLocation); - const doc = yaml.load(pnpmLockfileText) as Lockfile; - const { packages, lockfileVersion } = doc; - - const shrinkwrapFileMajorVersion: number = getShrinkwrapFileMajorVersion(lockfileVersion); - - if (packages && shrinkwrapFileMajorVersion === 6) { - const updatedPackages: Lockfile['packages'] = {}; - for (const [dependencyPath, dependency] of Object.entries(packages)) { - updatedPackages[convertLockfileV6DepPathToV5DepPath(dependencyPath)] = dependency; - } - doc.packages = updatedPackages; - } - - res.send({ - doc, - subspaceName: this._subspaceParameter.value - }); - }); - app.get('/api/health', (req: express.Request, res: express.Response) => { awaitingFirstConnect = false; isClientConnected = true; From 87880d485386762e7ffc69ce79b0f5dd16259ed9 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 12:05:56 -0700 Subject: [PATCH 14/26] Add unit tests --- apps/lockfile-explorer/.vscode/launch.json | 16 +- .../lfxGraphLoader54.test.ts.snap | 389 ++++++++++++++++++ .../lfxGraphLoader60.test.ts.snap | 306 ++++++++++++++ .../website-sample-1/pnpm-lock-pnpm-9.0.yaml | 123 ++++++ .../website-sample-1/pnpm-lock-rush-5.4.yaml | 134 ++++++ .../website-sample-1/pnpm-lock-rush-6.0.yaml | 115 ++++++ .../website-sample-1/website-sample-1.md | 12 + .../src/graph/test/graphTestHelpers.ts | 31 ++ .../src/graph/test/lfxGraphLoader54.test.ts | 25 ++ .../src/graph/test/lfxGraphLoader60.test.ts | 25 ++ 10 files changed, 1173 insertions(+), 3 deletions(-) create mode 100644 apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap create mode 100644 apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap create mode 100644 apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-pnpm-9.0.yaml create mode 100644 apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-rush-5.4.yaml create mode 100644 apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-rush-6.0.yaml create mode 100644 apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/website-sample-1.md create mode 100644 apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts create mode 100644 apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts create mode 100644 apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts diff --git a/apps/lockfile-explorer/.vscode/launch.json b/apps/lockfile-explorer/.vscode/launch.json index f1cdf885db1..9cc2fd9f58d 100644 --- a/apps/lockfile-explorer/.vscode/launch.json +++ b/apps/lockfile-explorer/.vscode/launch.json @@ -7,20 +7,30 @@ { "type": "node", "request": "launch", - "name": "Debug Jest tests", + "name": "All Jest tests", "program": "${workspaceFolder}/node_modules/@rushstack/heft/lib/start.js", "cwd": "${workspaceFolder}", "args": ["--debug", "test", "--clean"], "console": "integratedTerminal", "sourceMaps": true + }, + { + "type": "node", + "request": "launch", + "name": "Single Jest test", + "program": "${workspaceFolder}/node_modules/@rushstack/heft/lib/start.js", + "cwd": "${workspaceFolder}", + "args": ["--debug", "test", "--clean", "-u", "--test-path-pattern", "lfxGraphLoader60"], + "console": "integratedTerminal", + "sourceMaps": true }, { "type": "node", "request": "launch", - "name": "Run in specified folder", + "name": "Run LAST BUILD in specified folder", "program": "${workspaceFolder}/lib/start-explorer.js", - //"cwd": "C:\\Git\\lockfile-explorer-demos", "cwd": "(your project path)", + //"cwd": "C:\\Git\\lockfile-explorer-demos", "args": ["--debug"], "sourceMaps": true } diff --git a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap new file mode 100644 index 00000000000..1cefce4d51f --- /dev/null +++ b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap @@ -0,0 +1,389 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` +"workspace: + workspaceRootFolder: /repo + pnpmLockfilePath: common/temp/pnpm-lock.yaml + rushConfig: + rushVersion: 5.83.3 + subspaceName: '' +entries: + - jsonId: 0 + kind: 1 + entryId: '' + rawEntryId: . + packageJsonFolderPath: '' + entryPackageName: '' + displayText: '' + entryPackageVersion: '' + entrySuffix: '' + dependencies: [] + transitivePeerDependencies: [] + referrerJsonIds: [] + - jsonId: 1 + kind: 1 + entryId: 'project:./common/projects/a' + rawEntryId: ../../projects/a + packageJsonFolderPath: ./common/projects/a + entryPackageName: a + displayText: 'Project: a' + entryPackageVersion: '' + entrySuffix: '' + dependencies: + - name: '@rushstack/d' + version: 'link:../d' + entryId: 'project:./common/projects/d' + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 4 + transitivePeerDependencies: [] + referrerJsonIds: [] + - jsonId: 2 + kind: 1 + entryId: 'project:./common/projects/b' + rawEntryId: ../../projects/b + packageJsonFolderPath: ./common/projects/b + entryPackageName: b + displayText: 'Project: b' + entryPackageVersion: '' + entrySuffix: '' + dependencies: + - name: '@rushstack/d' + version: 'link:../d' + entryId: 'project:./common/projects/d' + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 4 + - name: '@rushstack/n' + version: 2.0.0 + entryId: /@rushstack/n/2.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 12 + transitivePeerDependencies: [] + referrerJsonIds: [] + - jsonId: 3 + kind: 1 + entryId: 'project:./common/projects/c' + rawEntryId: ../../projects/c + packageJsonFolderPath: ./common/projects/c + entryPackageName: c + displayText: 'Project: c' + entryPackageVersion: '' + entrySuffix: '' + dependencies: + - name: '@rushstack/e' + version: 'link:../e' + entryId: 'project:./common/projects/e' + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 5 + - name: '@rushstack/k' + version: 1.0.0_@rushstack+m@1.0.0 + entryId: /@rushstack/k/1.0.0_@rushstack+m@1.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 7 + - name: '@rushstack/m' + version: 1.0.0 + entryId: /@rushstack/m/1.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 11 + transitivePeerDependencies: [] + referrerJsonIds: [] + - jsonId: 4 + kind: 1 + entryId: 'project:./common/projects/d' + rawEntryId: ../../projects/d + packageJsonFolderPath: ./common/projects/d + entryPackageName: d + displayText: 'Project: d' + entryPackageVersion: '' + entrySuffix: '' + dependencies: + - name: '@rushstack/e' + version: 'link:../e' + entryId: 'project:./common/projects/e' + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 5 + - name: '@rushstack/j' + version: 1.0.0_@rushstack+n@2.0.0 + entryId: /@rushstack/j/1.0.0_@rushstack+n@2.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 6 + - name: '@rushstack/n' + version: 2.0.0 + entryId: /@rushstack/n/2.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 12 + transitivePeerDependencies: [] + referrerJsonIds: + - 1 + - 2 + - jsonId: 5 + kind: 1 + entryId: 'project:./common/projects/e' + rawEntryId: ../../projects/e + packageJsonFolderPath: ./common/projects/e + entryPackageName: e + displayText: 'Project: e' + entryPackageVersion: '' + entrySuffix: '' + dependencies: + - name: '@rushstack/n' + version: 3.0.0 + entryId: /@rushstack/n/3.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 13 + transitivePeerDependencies: [] + referrerJsonIds: + - 3 + - 4 + - jsonId: 6 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/j/1.0.0_@rushstack+n@2.0.0 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+j@1.0.0_@rushstack+n@2.0.0/node_modules/@rushstack/j + entryPackageName: '@rushstack/j' + displayText: '@rushstack/j 1.0.0 (@rushstack+n@2.0.0)' + entryPackageVersion: 1.0.0 + entrySuffix: '@rushstack+n@2.0.0' + dependencies: + - name: '@rushstack/k' + version: 1.0.0_wxpgugna4ivthu7yyu4fmciltu + entryId: /@rushstack/k/1.0.0_wxpgugna4ivthu7yyu4fmciltu + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 8 + - name: '@rushstack/m' + version: 1.0.0 + entryId: /@rushstack/m/1.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 11 + transitivePeerDependencies: + - '@rushstack/n' + referrerJsonIds: + - 4 + - jsonId: 7 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/k/1.0.0_@rushstack+m@1.0.0 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+k@1.0.0_@rushstack+m@1.0.0/node_modules/@rushstack/k + entryPackageName: '@rushstack/k' + displayText: '@rushstack/k 1.0.0 (@rushstack+m@1.0.0)' + entryPackageVersion: 1.0.0 + entrySuffix: '@rushstack+m@1.0.0' + dependencies: + - name: '@rushstack/l' + version: 1.0.0_@rushstack+m@1.0.0 + entryId: /@rushstack/l/1.0.0_@rushstack+m@1.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 9 + transitivePeerDependencies: + - '@rushstack/m' + - '@rushstack/n' + referrerJsonIds: + - 3 + - jsonId: 8 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/k/1.0.0_wxpgugna4ivthu7yyu4fmciltu + packageJsonFolderPath: >- + common/temp/undefined/node_modules/.pnpm/@rushstack+k@1.0.0_wxpgugna4ivthu7yyu4fmciltu/node_modules/@rushstack/k + entryPackageName: '@rushstack/k' + displayText: '@rushstack/k 1.0.0 (wxpgugna4ivthu7yyu4fmciltu)' + entryPackageVersion: 1.0.0 + entrySuffix: wxpgugna4ivthu7yyu4fmciltu + dependencies: + - name: '@rushstack/l' + version: 1.0.0_wxpgugna4ivthu7yyu4fmciltu + entryId: /@rushstack/l/1.0.0_wxpgugna4ivthu7yyu4fmciltu + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 10 + transitivePeerDependencies: + - '@rushstack/m' + - '@rushstack/n' + referrerJsonIds: + - 6 + - jsonId: 9 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/l/1.0.0_@rushstack+m@1.0.0 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+l@1.0.0_@rushstack+m@1.0.0/node_modules/@rushstack/l + entryPackageName: '@rushstack/l' + displayText: '@rushstack/l 1.0.0 (@rushstack+m@1.0.0)' + entryPackageVersion: 1.0.0 + entrySuffix: '@rushstack+m@1.0.0' + dependencies: + - name: '@rushstack/m' + version: 1.0.0 + entryId: /@rushstack/m/1.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 11 + - name: '@rushstack/m' + version: ^1.0.0 + entryId: 'Peer: @rushstack/m' + dependencyType: peer + peerDependencyMeta: + name: '@rushstack/m' + version: ^1.0.0 + optional: false + - name: '@rushstack/n' + version: ^2.0.0 + entryId: 'Peer: @rushstack/n' + dependencyType: peer + peerDependencyMeta: + name: '@rushstack/n' + version: ^2.0.0 + optional: true + transitivePeerDependencies: [] + referrerJsonIds: + - 7 + - jsonId: 10 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/l/1.0.0_wxpgugna4ivthu7yyu4fmciltu + packageJsonFolderPath: >- + common/temp/undefined/node_modules/.pnpm/@rushstack+l@1.0.0_wxpgugna4ivthu7yyu4fmciltu/node_modules/@rushstack/l + entryPackageName: '@rushstack/l' + displayText: '@rushstack/l 1.0.0 (wxpgugna4ivthu7yyu4fmciltu)' + entryPackageVersion: 1.0.0 + entrySuffix: wxpgugna4ivthu7yyu4fmciltu + dependencies: + - name: '@rushstack/m' + version: 1.0.0 + entryId: /@rushstack/m/1.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 11 + - name: '@rushstack/n' + version: 2.0.0 + entryId: /@rushstack/n/2.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 12 + - name: '@rushstack/m' + version: ^1.0.0 + entryId: 'Peer: @rushstack/m' + dependencyType: peer + peerDependencyMeta: + name: '@rushstack/m' + version: ^1.0.0 + optional: false + - name: '@rushstack/n' + version: ^2.0.0 + entryId: 'Peer: @rushstack/n' + dependencyType: peer + peerDependencyMeta: + name: '@rushstack/n' + version: ^2.0.0 + optional: true + transitivePeerDependencies: [] + referrerJsonIds: + - 8 + - jsonId: 11 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/m/1.0.0 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+m@1.0.0/node_modules/@rushstack/m + entryPackageName: '@rushstack/m' + displayText: '@rushstack/m 1.0.0' + entryPackageVersion: 1.0.0 + entrySuffix: '' + dependencies: [] + transitivePeerDependencies: [] + referrerJsonIds: + - 3 + - 6 + - 9 + - 10 + - jsonId: 12 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/n/2.0.0 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+n@2.0.0/node_modules/@rushstack/n + entryPackageName: '@rushstack/n' + displayText: '@rushstack/n 2.0.0' + entryPackageVersion: 2.0.0 + entrySuffix: '' + dependencies: [] + transitivePeerDependencies: [] + referrerJsonIds: + - 2 + - 4 + - 10 + - jsonId: 13 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/n/3.0.0 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+n@3.0.0/node_modules/@rushstack/n + entryPackageName: '@rushstack/n' + displayText: '@rushstack/n 3.0.0' + entryPackageVersion: 3.0.0 + entrySuffix: '' + dependencies: [] + transitivePeerDependencies: [] + referrerJsonIds: + - 5 +" +`; diff --git a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap new file mode 100644 index 00000000000..8f6b4529d7a --- /dev/null +++ b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap @@ -0,0 +1,306 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`lfxGraphLoader 6.0 loads a workspace 1`] = ` +"workspace: + workspaceRootFolder: /repo + pnpmLockfilePath: common/temp/pnpm-lock.yaml + rushConfig: + rushVersion: 5.158.1 + subspaceName: '' +entries: + - jsonId: 0 + kind: 1 + entryId: '' + rawEntryId: . + packageJsonFolderPath: '' + entryPackageName: '' + displayText: '' + entryPackageVersion: '' + entrySuffix: '' + dependencies: [] + transitivePeerDependencies: [] + referrerJsonIds: [] + - jsonId: 1 + kind: 1 + entryId: 'project:./common/projects/a' + rawEntryId: ../../projects/a + packageJsonFolderPath: ./common/projects/a + entryPackageName: a + displayText: 'Project: a' + entryPackageVersion: '' + entrySuffix: '' + dependencies: + - name: '@rushstack/d' + version: 'link:../d' + entryId: 'project:./common/projects/d' + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 4 + transitivePeerDependencies: [] + referrerJsonIds: [] + - jsonId: 2 + kind: 1 + entryId: 'project:./common/projects/b' + rawEntryId: ../../projects/b + packageJsonFolderPath: ./common/projects/b + entryPackageName: b + displayText: 'Project: b' + entryPackageVersion: '' + entrySuffix: '' + dependencies: + - name: '@rushstack/d' + version: 'link:../d' + entryId: 'project:./common/projects/d' + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 4 + - name: '@rushstack/n' + version: 2.0.0 + entryId: /@rushstack/n/2.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + transitivePeerDependencies: [] + referrerJsonIds: [] + - jsonId: 3 + kind: 1 + entryId: 'project:./common/projects/c' + rawEntryId: ../../projects/c + packageJsonFolderPath: ./common/projects/c + entryPackageName: c + displayText: 'Project: c' + entryPackageVersion: '' + entrySuffix: '' + dependencies: + - name: '@rushstack/e' + version: 'link:../e' + entryId: 'project:./common/projects/e' + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 5 + - name: '@rushstack/k' + version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + entryId: /@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + - name: '@rushstack/m' + version: 1.0.0 + entryId: /@rushstack/m/1.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + transitivePeerDependencies: [] + referrerJsonIds: [] + - jsonId: 4 + kind: 1 + entryId: 'project:./common/projects/d' + rawEntryId: ../../projects/d + packageJsonFolderPath: ./common/projects/d + entryPackageName: d + displayText: 'Project: d' + entryPackageVersion: '' + entrySuffix: '' + dependencies: + - name: '@rushstack/e' + version: 'link:../e' + entryId: 'project:./common/projects/e' + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + resolvedEntryJsonId: 5 + - name: '@rushstack/j' + version: 1.0.0(@rushstack/n@2.0.0) + entryId: /@rushstack/j/1.0.0(@rushstack/n@2.0.0) + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + - name: '@rushstack/n' + version: 2.0.0 + entryId: /@rushstack/n/2.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + transitivePeerDependencies: [] + referrerJsonIds: + - 1 + - 2 + - jsonId: 5 + kind: 1 + entryId: 'project:./common/projects/e' + rawEntryId: ../../projects/e + packageJsonFolderPath: ./common/projects/e + entryPackageName: e + displayText: 'Project: e' + entryPackageVersion: '' + entrySuffix: '' + dependencies: + - name: '@rushstack/n' + version: 3.0.0 + entryId: /@rushstack/n/3.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + transitivePeerDependencies: [] + referrerJsonIds: + - 3 + - 4 + - jsonId: 6 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/j@1.0.0(@rushstack/n@2.0.0) + packageJsonFolderPath: >- + common/temp/undefined/node_modules/.pnpm/@rushstack+j@1.0.0(@rushstack@n@2.0.0)/node_modules/@rushstack/j@1.0.0(@rushstack + entryPackageName: '@rushstack/j@1.0.0(@rushstack' + displayText: '@rushstack/j@1.0.0(@rushstack n@2.0.0)' + entryPackageVersion: n@2.0.0) + entrySuffix: '' + dependencies: + - name: '@rushstack/k' + version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + entryId: /@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + - name: '@rushstack/m' + version: 1.0.0 + entryId: /@rushstack/m/1.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + transitivePeerDependencies: + - '@rushstack/n' + referrerJsonIds: [] + - jsonId: 7 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/k@1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + packageJsonFolderPath: >- + common/temp/undefined/node_modules/.pnpm/@rushstack+k@1.0.0(@rushstack/m@1.0.0)(@rushstack@n@2.0.0)/node_modules/@rushstack/k@1.0.0(@rushstack/m@1.0.0)(@rushstack + entryPackageName: '@rushstack/k@1.0.0(@rushstack/m@1.0.0)(@rushstack' + displayText: '@rushstack/k@1.0.0(@rushstack/m@1.0.0)(@rushstack n@2.0.0)' + entryPackageVersion: n@2.0.0) + entrySuffix: '' + dependencies: + - name: '@rushstack/l' + version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + entryId: /@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + transitivePeerDependencies: + - '@rushstack/m' + - '@rushstack/n' + referrerJsonIds: [] + - jsonId: 8 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/l@1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + packageJsonFolderPath: >- + common/temp/undefined/node_modules/.pnpm/@rushstack+l@1.0.0(@rushstack/m@1.0.0)(@rushstack@n@2.0.0)/node_modules/@rushstack/l@1.0.0(@rushstack/m@1.0.0)(@rushstack + entryPackageName: '@rushstack/l@1.0.0(@rushstack/m@1.0.0)(@rushstack' + displayText: '@rushstack/l@1.0.0(@rushstack/m@1.0.0)(@rushstack n@2.0.0)' + entryPackageVersion: n@2.0.0) + entrySuffix: '' + dependencies: + - name: '@rushstack/m' + version: 1.0.0 + entryId: /@rushstack/m/1.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + - name: '@rushstack/n' + version: 2.0.0 + entryId: /@rushstack/n/2.0.0 + dependencyType: regular + peerDependencyMeta: + name: ! '' + version: ! '' + optional: ! '' + - name: '@rushstack/m' + version: ^1.0.0 + entryId: 'Peer: @rushstack/m' + dependencyType: peer + peerDependencyMeta: + name: '@rushstack/m' + version: ^1.0.0 + optional: false + - name: '@rushstack/n' + version: ^2.0.0 + entryId: 'Peer: @rushstack/n' + dependencyType: peer + peerDependencyMeta: + name: '@rushstack/n' + version: ^2.0.0 + optional: true + transitivePeerDependencies: [] + referrerJsonIds: [] + - jsonId: 9 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/m@1.0.0 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack@m@1.0.0/node_modules/@rushstack + entryPackageName: '@rushstack' + displayText: '@rushstack m@1.0.0' + entryPackageVersion: m@1.0.0 + entrySuffix: '' + dependencies: [] + transitivePeerDependencies: [] + referrerJsonIds: [] + - jsonId: 10 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/n@2.0.0 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack@n@2.0.0/node_modules/@rushstack + entryPackageName: '@rushstack' + displayText: '@rushstack n@2.0.0' + entryPackageVersion: n@2.0.0 + entrySuffix: '' + dependencies: [] + transitivePeerDependencies: [] + referrerJsonIds: [] + - jsonId: 11 + kind: 2 + entryId: '' + rawEntryId: /@rushstack/n@3.0.0 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack@n@3.0.0/node_modules/@rushstack + entryPackageName: '@rushstack' + displayText: '@rushstack n@3.0.0' + entryPackageVersion: n@3.0.0 + entrySuffix: '' + dependencies: [] + transitivePeerDependencies: [] + referrerJsonIds: [] +" +`; diff --git a/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-pnpm-9.0.yaml b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-pnpm-9.0.yaml new file mode 100644 index 00000000000..60de289e509 --- /dev/null +++ b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-pnpm-9.0.yaml @@ -0,0 +1,123 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +pnpmfileChecksum: sha256-6Cq2BFB3826lbTciEnsPowoZ1qvFZeM4wkoGwobxneY= + +importers: + projects/a: + dependencies: + '@rushstack/d': + specifier: workspace:* + version: link:../d + + projects/b: + dependencies: + '@rushstack/d': + specifier: workspace:* + version: link:../d + '@rushstack/n': + specifier: ^2.0.0 + version: 2.0.0 + + projects/c: + dependencies: + '@rushstack/e': + specifier: workspace:* + version: link:../e + '@rushstack/k': + specifier: ^1.0.0 + version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + '@rushstack/m': + specifier: ~1.0.0 + version: 1.0.0 + + projects/d: + dependencies: + '@rushstack/e': + specifier: workspace:* + version: link:../e + '@rushstack/j': + specifier: ^1.0.0 + version: 1.0.0(@rushstack/n@2.0.0) + '@rushstack/n': + specifier: ^2.0.0 + version: 2.0.0 + + projects/e: + dependencies: + '@rushstack/n': + specifier: ^3.0.0 + version: 3.0.0 + +packages: + '@rushstack/j@1.0.0': + resolution: + { + integrity: sha512-D799Tv8advqKGl9u/j1x1cTG1pef6uY9CE7ETPqz9RHSNTRBL4Ftw98M95EK/dWS41OFlJ+eNGVwzWn3PjL85g== + } + + '@rushstack/k@1.0.0': + resolution: + { + integrity: sha512-HIap/n3FPoZMx+J6GbzziJTaVd8Q0FpHXUgYU1EHSM7Sy6suMbCxx6KSRuuM0Iv2BB3rht5jn6yv2l7pGBpXAA== + } + + '@rushstack/l@1.0.0': + resolution: + { + integrity: sha512-qJvPD0WLK6P+4KmczcuKA0f/6oUpZXYWYPIvMNJfasFy3DGMoUHg+3TSpisqQQb7OuWzf1mHQCG/suYiIeXQaQ== + } + peerDependencies: + '@rushstack/m': ^1.0.0 + '@rushstack/n': ^2.0.0 + peerDependenciesMeta: + '@rushstack/n': + optional: true + + '@rushstack/m@1.0.0': + resolution: + { + integrity: sha512-iZtUynf07U6UNf4QeYFdCNq7t+VTB3YyRb66v2U0uc3yP486dbXFO4LCCyqPpCsRlkwt4y/hKJH7lsODB+ISMA== + } + + '@rushstack/n@2.0.0': + resolution: + { + integrity: sha512-cOGhNwbSaZv6hcfuUtut43vENNyGAPlhNU7r2kixj7dKKeyiQ1XlyhABxvFya2qEyFDRjbFW7/gSMrFmtLAxRg== + } + + '@rushstack/n@3.0.0': + resolution: + { + integrity: sha512-GyiYvYT2KHlVlsiQ1Z+Lgt7lB5SR6axKASYKaj9qM+ycvpHTs8MoHJGp/Mbt+Iqrjfjlk3t4cXzLvftqFbPWuw== + } + +snapshots: + '@rushstack/j@1.0.0(@rushstack/n@2.0.0)': + dependencies: + '@rushstack/k': 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + '@rushstack/m': 1.0.0 + transitivePeerDependencies: + - '@rushstack/n' + + '@rushstack/k@1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0)': + dependencies: + '@rushstack/l': 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + transitivePeerDependencies: + - '@rushstack/m' + - '@rushstack/n' + + '@rushstack/l@1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0)': + dependencies: + '@rushstack/m': 1.0.0 + optionalDependencies: + '@rushstack/n': 2.0.0 + + '@rushstack/m@1.0.0': {} + + '@rushstack/n@2.0.0': {} + + '@rushstack/n@3.0.0': {} diff --git a/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-rush-5.4.yaml b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-rush-5.4.yaml new file mode 100644 index 00000000000..f1fb1554c57 --- /dev/null +++ b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-rush-5.4.yaml @@ -0,0 +1,134 @@ +lockfileVersion: 5.4 + +importers: + .: + specifiers: {} + + ../../projects/a: + specifiers: + '@rushstack/d': workspace:* + dependencies: + '@rushstack/d': link:../d + + ../../projects/b: + specifiers: + '@rushstack/d': workspace:* + '@rushstack/n': ^2.0.0 + dependencies: + '@rushstack/d': link:../d + '@rushstack/n': 2.0.0 + + ../../projects/c: + specifiers: + '@rushstack/e': workspace:* + '@rushstack/k': ^1.0.0 + '@rushstack/m': ~1.0.0 + dependencies: + '@rushstack/e': link:../e + '@rushstack/k': 1.0.0_@rushstack+m@1.0.0 + '@rushstack/m': 1.0.0 + + ../../projects/d: + specifiers: + '@rushstack/e': workspace:* + '@rushstack/j': ^1.0.0 + '@rushstack/n': ^2.0.0 + dependencies: + '@rushstack/e': link:../e + '@rushstack/j': 1.0.0_@rushstack+n@2.0.0 + '@rushstack/n': 2.0.0 + + ../../projects/e: + specifiers: + '@rushstack/n': ^3.0.0 + dependencies: + '@rushstack/n': 3.0.0 + +packages: + /@rushstack/j/1.0.0_@rushstack+n@2.0.0: + resolution: + { + integrity: sha512-D799Tv8advqKGl9u/j1x1cTG1pef6uY9CE7ETPqz9RHSNTRBL4Ftw98M95EK/dWS41OFlJ+eNGVwzWn3PjL85g== + } + dependencies: + '@rushstack/k': 1.0.0_wxpgugna4ivthu7yyu4fmciltu + '@rushstack/m': 1.0.0 + transitivePeerDependencies: + - '@rushstack/n' + dev: false + + /@rushstack/k/1.0.0_@rushstack+m@1.0.0: + resolution: + { + integrity: sha512-HIap/n3FPoZMx+J6GbzziJTaVd8Q0FpHXUgYU1EHSM7Sy6suMbCxx6KSRuuM0Iv2BB3rht5jn6yv2l7pGBpXAA== + } + dependencies: + '@rushstack/l': 1.0.0_@rushstack+m@1.0.0 + transitivePeerDependencies: + - '@rushstack/m' + - '@rushstack/n' + dev: false + + /@rushstack/k/1.0.0_wxpgugna4ivthu7yyu4fmciltu: + resolution: + { + integrity: sha512-HIap/n3FPoZMx+J6GbzziJTaVd8Q0FpHXUgYU1EHSM7Sy6suMbCxx6KSRuuM0Iv2BB3rht5jn6yv2l7pGBpXAA== + } + dependencies: + '@rushstack/l': 1.0.0_wxpgugna4ivthu7yyu4fmciltu + transitivePeerDependencies: + - '@rushstack/m' + - '@rushstack/n' + dev: false + + /@rushstack/l/1.0.0_@rushstack+m@1.0.0: + resolution: + { + integrity: sha512-qJvPD0WLK6P+4KmczcuKA0f/6oUpZXYWYPIvMNJfasFy3DGMoUHg+3TSpisqQQb7OuWzf1mHQCG/suYiIeXQaQ== + } + peerDependencies: + '@rushstack/m': ^1.0.0 + '@rushstack/n': ^2.0.0 + peerDependenciesMeta: + '@rushstack/n': + optional: true + dependencies: + '@rushstack/m': 1.0.0 + dev: false + + /@rushstack/l/1.0.0_wxpgugna4ivthu7yyu4fmciltu: + resolution: + { + integrity: sha512-qJvPD0WLK6P+4KmczcuKA0f/6oUpZXYWYPIvMNJfasFy3DGMoUHg+3TSpisqQQb7OuWzf1mHQCG/suYiIeXQaQ== + } + peerDependencies: + '@rushstack/m': ^1.0.0 + '@rushstack/n': ^2.0.0 + peerDependenciesMeta: + '@rushstack/n': + optional: true + dependencies: + '@rushstack/m': 1.0.0 + '@rushstack/n': 2.0.0 + dev: false + + /@rushstack/m/1.0.0: + resolution: + { + integrity: sha512-iZtUynf07U6UNf4QeYFdCNq7t+VTB3YyRb66v2U0uc3yP486dbXFO4LCCyqPpCsRlkwt4y/hKJH7lsODB+ISMA== + } + dev: false + + /@rushstack/n/2.0.0: + resolution: + { + integrity: sha512-cOGhNwbSaZv6hcfuUtut43vENNyGAPlhNU7r2kixj7dKKeyiQ1XlyhABxvFya2qEyFDRjbFW7/gSMrFmtLAxRg== + } + dev: false + + /@rushstack/n/3.0.0: + resolution: + { + integrity: sha512-GyiYvYT2KHlVlsiQ1Z+Lgt7lB5SR6axKASYKaj9qM+ycvpHTs8MoHJGp/Mbt+Iqrjfjlk3t4cXzLvftqFbPWuw== + } + dev: false diff --git a/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-rush-6.0.yaml b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-rush-6.0.yaml new file mode 100644 index 00000000000..8a8bc8077ac --- /dev/null +++ b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-rush-6.0.yaml @@ -0,0 +1,115 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: false + excludeLinksFromLockfile: false + +importers: + .: {} + + ../../projects/a: + dependencies: + '@rushstack/d': + specifier: workspace:* + version: link:../d + + ../../projects/b: + dependencies: + '@rushstack/d': + specifier: workspace:* + version: link:../d + '@rushstack/n': + specifier: ^2.0.0 + version: 2.0.0 + + ../../projects/c: + dependencies: + '@rushstack/e': + specifier: workspace:* + version: link:../e + '@rushstack/k': + specifier: ^1.0.0 + version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + '@rushstack/m': + specifier: ~1.0.0 + version: 1.0.0 + + ../../projects/d: + dependencies: + '@rushstack/e': + specifier: workspace:* + version: link:../e + '@rushstack/j': + specifier: ^1.0.0 + version: 1.0.0(@rushstack/n@2.0.0) + '@rushstack/n': + specifier: ^2.0.0 + version: 2.0.0 + + ../../projects/e: + dependencies: + '@rushstack/n': + specifier: ^3.0.0 + version: 3.0.0 + +packages: + /@rushstack/j@1.0.0(@rushstack/n@2.0.0): + resolution: + { + integrity: sha512-D799Tv8advqKGl9u/j1x1cTG1pef6uY9CE7ETPqz9RHSNTRBL4Ftw98M95EK/dWS41OFlJ+eNGVwzWn3PjL85g== + } + dependencies: + '@rushstack/k': 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + '@rushstack/m': 1.0.0 + transitivePeerDependencies: + - '@rushstack/n' + dev: false + + /@rushstack/k@1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0): + resolution: + { + integrity: sha512-HIap/n3FPoZMx+J6GbzziJTaVd8Q0FpHXUgYU1EHSM7Sy6suMbCxx6KSRuuM0Iv2BB3rht5jn6yv2l7pGBpXAA== + } + dependencies: + '@rushstack/l': 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + transitivePeerDependencies: + - '@rushstack/m' + - '@rushstack/n' + dev: false + + /@rushstack/l@1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0): + resolution: + { + integrity: sha512-qJvPD0WLK6P+4KmczcuKA0f/6oUpZXYWYPIvMNJfasFy3DGMoUHg+3TSpisqQQb7OuWzf1mHQCG/suYiIeXQaQ== + } + peerDependencies: + '@rushstack/m': ^1.0.0 + '@rushstack/n': ^2.0.0 + peerDependenciesMeta: + '@rushstack/n': + optional: true + dependencies: + '@rushstack/m': 1.0.0 + '@rushstack/n': 2.0.0 + dev: false + + /@rushstack/m@1.0.0: + resolution: + { + integrity: sha512-iZtUynf07U6UNf4QeYFdCNq7t+VTB3YyRb66v2U0uc3yP486dbXFO4LCCyqPpCsRlkwt4y/hKJH7lsODB+ISMA== + } + dev: false + + /@rushstack/n@2.0.0: + resolution: + { + integrity: sha512-cOGhNwbSaZv6hcfuUtut43vENNyGAPlhNU7r2kixj7dKKeyiQ1XlyhABxvFya2qEyFDRjbFW7/gSMrFmtLAxRg== + } + dev: false + + /@rushstack/n@3.0.0: + resolution: + { + integrity: sha512-GyiYvYT2KHlVlsiQ1Z+Lgt7lB5SR6axKASYKaj9qM+ycvpHTs8MoHJGp/Mbt+Iqrjfjlk3t4cXzLvftqFbPWuw== + } + dev: false diff --git a/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/website-sample-1.md b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/website-sample-1.md new file mode 100644 index 00000000000..3370009c089 --- /dev/null +++ b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/website-sample-1.md @@ -0,0 +1,12 @@ +# fixtures/website-sample-1 + +This test fixture uses the `demos/sample-1` branch from the Lockfile Explorer website demos repistory: + +https://github.com/microsoft/lockfile-explorer-demos/tree/demo/sample-1 + +There are three versions of the lockfile: + + +- `pnpm-lock-rush-5.4.yaml`: The old 5.4 YAML format generated using PNPM 7.16.1 and Rush 5.83.3 from [`ee8a06e`](https://github.com/microsoft/lockfile-explorer-demos/commit/ee8a06e71b63feb806f240de01e57d42854d02af). +- `pnpm-lock-rush-6.0.yaml`: The 6.0 YAML format generated using PNPM 8.15.9 and Rush 5.158.1 from [`8c3ad3c`](https://github.com/microsoft/lockfile-explorer-demos/commit/8c3ad3cad68a921baa4eb6d264d293e928a962f5) +- `pnpm-lock-pnpm-9.0.yaml`: For comparison, a lockfile generated using a PNPM 9.15.9 with a plain PNPM workspace (without Rush). Rush doesn't support this format yet. diff --git a/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts b/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts new file mode 100644 index 00000000000..46e1214eb26 --- /dev/null +++ b/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +import * as path from 'path'; +import yaml from 'js-yaml'; +import { FileSystem, NewlineKind } from '@rushstack/node-core-library'; +import { + type IJsonLfxGraph, + type IJsonLfxWorkspace, + lfxGraphSerializer, + type LfxGraph +} from '../../../temp/lfx-shared'; + +import * as lfxGraphLoader from '../lfxGraphLoader'; + +const FIXTURES_FOLDER: string = path.resolve(__dirname, '../../../src/graph/test/fixtures/'); + +export async function loadAndSerializeLFxGraph(options: { + workspace: IJsonLfxWorkspace; + lockfilePathUnderFixtures: string; +}): Promise { + const lockfileYaml: string = await FileSystem.readFileAsync( + FIXTURES_FOLDER + options.lockfilePathUnderFixtures, + { convertLineEndings: NewlineKind.Lf } + ); + const lockfileObject = yaml.load(lockfileYaml) as lfxGraphLoader.ILockfilePackageType; + const graph: LfxGraph = lfxGraphLoader.generateLockfileGraph(options.workspace, lockfileObject); + const serializedObject: IJsonLfxGraph = lfxGraphSerializer.serializeToJson(graph); + const serializedYaml: string = yaml.dump(serializedObject, { noRefs: true, lineWidth: 110 }); + return serializedYaml; +} diff --git a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts b/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts new file mode 100644 index 00000000000..7a01f6dbc36 --- /dev/null +++ b/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +import type { IJsonLfxWorkspace } from '../../../temp/lfx-shared'; + +import * as graphTestHelpers from './graphTestHelpers'; + +export const workspace: IJsonLfxWorkspace = { + workspaceRootFolder: '/repo', + pnpmLockfilePath: 'common/temp/pnpm-lock.yaml', + rushConfig: { + rushVersion: '5.83.3', + subspaceName: '' + } +}; + +describe('lfxGraphLoader 5.4', () => { + it('loads a workspace', async () => { + const serializedYaml: string = await graphTestHelpers.loadAndSerializeLFxGraph({ + lockfilePathUnderFixtures: '/website-sample-1/pnpm-lock-rush-5.4.yaml', + workspace: workspace + }); + expect(serializedYaml).toMatchSnapshot(); + }); +}); diff --git a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts b/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts new file mode 100644 index 00000000000..3c89d2b616e --- /dev/null +++ b/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +import type { IJsonLfxWorkspace } from '../../../temp/lfx-shared'; + +import * as graphTestHelpers from './graphTestHelpers'; + +export const workspace: IJsonLfxWorkspace = { + workspaceRootFolder: '/repo', + pnpmLockfilePath: 'common/temp/pnpm-lock.yaml', + rushConfig: { + rushVersion: '5.158.1', + subspaceName: '' + } +}; + +describe('lfxGraphLoader 6.0', () => { + it('loads a workspace', async () => { + const serializedYaml: string = await graphTestHelpers.loadAndSerializeLFxGraph({ + lockfilePathUnderFixtures: '/website-sample-1/pnpm-lock-rush-6.0.yaml', + workspace: workspace + }); + expect(serializedYaml).toMatchSnapshot(); + }); +}); From 5be51f141a43454725b772f6f05745148b0534d4 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 12:18:40 -0700 Subject: [PATCH 15/26] Enable Rush Stack lint rules for "lockfile-explorer" project --- apps/lockfile-explorer/eslint.config.js | 6 ++- .../cli/explorer/ExplorerCommandLineParser.ts | 14 +++---- .../src/cli/lint/actions/CheckAction.ts | 4 +- .../src/graph/lfxGraphLoader.ts | 37 ++++++++++--------- .../lockfile-explorer/src/utils/shrinkwrap.ts | 12 ++++-- 5 files changed, 40 insertions(+), 33 deletions(-) diff --git a/apps/lockfile-explorer/eslint.config.js b/apps/lockfile-explorer/eslint.config.js index 0c26ce1ce48..ceb5a1bee40 100644 --- a/apps/lockfile-explorer/eslint.config.js +++ b/apps/lockfile-explorer/eslint.config.js @@ -1,10 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -const nodeProfile = require('local-node-rig/profiles/default/includes/eslint/flat/profile/node'); +const nodeTrustedToolProfile = require('local-node-rig/profiles/default/includes/eslint/flat/profile/node-trusted-tool'); +const friendlyLocalsMixin = require('local-node-rig/profiles/default/includes/eslint/flat/mixins/friendly-locals'); module.exports = [ - ...nodeProfile, + ...nodeTrustedToolProfile, + ...friendlyLocalsMixin, { files: ['**/*.ts', '**/*.tsx'], languageOptions: { diff --git a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts index 2b63674d936..2529563ee78 100644 --- a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts +++ b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts @@ -153,9 +153,9 @@ export class ExplorerCommandLineParser extends CommandLineParser { app.get('/api/graph', async (req: express.Request, res: express.Response) => { const pnpmLockfileText: string = await FileSystem.readFileAsync(appState.pnpmLockfileLocation); - const doc = yaml.load(pnpmLockfileText) as Lockfile; + const lockfile: Lockfile = yaml.load(pnpmLockfileText) as Lockfile; - const { packages, lockfileVersion } = doc; + const { packages, lockfileVersion } = lockfile; const shrinkwrapFileMajorVersion: number = getShrinkwrapFileMajorVersion(lockfileVersion); @@ -164,12 +164,12 @@ export class ExplorerCommandLineParser extends CommandLineParser { for (const [dependencyPath, dependency] of Object.entries(packages)) { updatedPackages[convertLockfileV6DepPathToV5DepPath(dependencyPath)] = dependency; } - doc.packages = updatedPackages; + lockfile.packages = updatedPackages; } const graph: LfxGraph = lfxGraphLoader.generateLockfileGraph( appState.lfxWorkspace, - doc as lfxGraphLoader.ILockfilePackageType, + lockfile as lfxGraphLoader.ILockfilePackageType, appState.lfxWorkspace.rushConfig?.subspaceName ?? '' ); @@ -181,7 +181,7 @@ export class ExplorerCommandLineParser extends CommandLineParser { '/api/package-json', async (req: express.Request<{}, {}, { projectPath: string }, {}>, res: express.Response) => { const { projectPath } = req.body; - const fileLocation = `${appState.projectRoot}/${projectPath}/package.json`; + const fileLocation: string = `${appState.projectRoot}/${projectPath}/package.json`; let packageJsonText: string; try { packageJsonText = await FileSystem.readFileAsync(fileLocation); @@ -222,7 +222,7 @@ export class ExplorerCommandLineParser extends CommandLineParser { '/api/package-spec', async (req: express.Request<{}, {}, { projectPath: string }, {}>, res: express.Response) => { const { projectPath } = req.body; - const fileLocation = `${appState.projectRoot}/${projectPath}/package.json`; + const fileLocation: string = `${appState.projectRoot}/${projectPath}/package.json`; let packageJson: IPackageJson; try { packageJson = await JsonFile.loadAsync(fileLocation); @@ -239,7 +239,7 @@ export class ExplorerCommandLineParser extends CommandLineParser { const { hooks: { readPackage } } = require(appState.pnpmfileLocation); - const parsedPackage = readPackage(packageJson, {}); + const parsedPackage: {} = readPackage(packageJson, {}); res.send(parsedPackage); } ); diff --git a/apps/lockfile-explorer/src/cli/lint/actions/CheckAction.ts b/apps/lockfile-explorer/src/cli/lint/actions/CheckAction.ts index 2903d0e8575..389bb27001b 100644 --- a/apps/lockfile-explorer/src/cli/lint/actions/CheckAction.ts +++ b/apps/lockfile-explorer/src/cli/lint/actions/CheckAction.ts @@ -118,9 +118,9 @@ export class CheckAction extends CommandLineAction { await Promise.all( Object.entries(importers).map(async ([relativePath, { dependencies }]) => { if (path.resolve(projectFolder, relativePath) === projectFolder) { - const dependenciesEntries = Object.entries(dependencies ?? {}); + const dependenciesEntries: [string, unknown][] = Object.entries(dependencies ?? {}); for (const [dependencyName, dependencyValue] of dependenciesEntries) { - const fullDependencyPath = splicePackageWithVersion( + const fullDependencyPath: string = splicePackageWithVersion( shrinkwrapFileMajorVersion, dependencyName, typeof dependencyValue === 'string' diff --git a/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts b/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts index bdeeb4ff49b..77ce289a125 100644 --- a/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts +++ b/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts @@ -92,8 +92,8 @@ function createLockfileDependency( }; if (version.startsWith('link:')) { - const relativePath = version.substring('link:'.length); - const rootRelativePath = new Path('.').relative( + const relativePath: string = version.substring('link:'.length); + const rootRelativePath: Path | null = new Path('.').relative( new Path(containingEntry.packageJsonFolderPath).concat(relativePath) ); if (!rootRelativePath) { @@ -183,11 +183,12 @@ function createLockfileEntry(options: { } if (kind === LfxGraphEntryKind.Project) { - const rootPackageJsonFolderPath = new Path(`common/temp/${subspaceName}/package.json`).dirname() || ''; - const packageJsonFolderPath = new Path('.').relative( + const rootPackageJsonFolderPath: '' | Path = + new Path(`common/temp/${subspaceName}/package.json`).dirname() || ''; + const packageJsonFolderPath: Path | null = new Path('.').relative( new Path(rootPackageJsonFolderPath).concat(rawEntryId) ); - const packageName = new Path(rawEntryId).basename(); + const packageName: string | null = new Path(rawEntryId).basename(); if (!packageJsonFolderPath || !packageName) { console.error('Could not construct path for entry: ', rawEntryId); @@ -198,7 +199,7 @@ function createLockfileEntry(options: { result.entryId = 'project:' + result.packageJsonFolderPath; result.entryPackageName = packageName.toString(); if (duplicates?.has(result.entryPackageName)) { - const fullPath = new Path(rawEntryId).makeAbsolute('/').toString().substring(1); + const fullPath: string = new Path(rawEntryId).makeAbsolute('/').toString().substring(1); result.displayText = `Project: ${result.entryPackageName} (${fullPath})`; result.entryPackageName = `${result.entryPackageName} (${fullPath})`; } else { @@ -207,16 +208,16 @@ function createLockfileEntry(options: { } else { result.displayText = rawEntryId; - const match = packageEntryIdRegex.exec(rawEntryId); + const match: RegExpExecArray | null = packageEntryIdRegex.exec(rawEntryId); if (match) { const [, packageName, versionPart] = match; result.entryPackageName = packageName; - const underscoreIndex = versionPart.indexOf('_'); + const underscoreIndex: number = versionPart.indexOf('_'); if (underscoreIndex >= 0) { - const version = versionPart.substring(0, underscoreIndex); - const suffix = versionPart.substring(underscoreIndex + 1); + const version: string = versionPart.substring(0, underscoreIndex); + const suffix: string = versionPart.substring(underscoreIndex + 1); result.entryPackageVersion = version; result.entrySuffix = suffix; @@ -247,7 +248,7 @@ function createLockfileEntry(options: { result.entryPackageName; } - const lockfileEntry = new LfxGraphEntry(result); + const lockfileEntry: LfxGraphEntry = new LfxGraphEntry(result); parseDependencies(lockfileEntry.dependencies, lockfileEntry, rawYamlData); return lockfileEntry; } @@ -263,7 +264,7 @@ function getImporterValue( pnpmLockfileVersion: PnpmLockfileVersion ): ILockfileImporterV5 { if (pnpmLockfileVersion === PnpmLockfileVersion.V6) { - const v6ImporterValue = importerValue as ILockfileImporterV6; + const v6ImporterValue: ILockfileImporterV6 = importerValue as ILockfileImporterV6; const v5ImporterValue: ILockfileImporterV5 = { specifiers: {}, dependencies: {}, @@ -302,13 +303,13 @@ export function generateLockfileGraph( const allEntries: LfxGraphEntry[] = lfxGraph.entries; const allEntriesById: { [key: string]: LfxGraphEntry } = {}; - const allImporters = []; + const allImporters: LfxGraphEntry[] = []; if (lockfile.importers) { // Find duplicate importer names - const baseNames = new Set(); - const duplicates = new Set(); + const baseNames: Set = new Set(); + const duplicates: Set = new Set(); for (const importerKey of Object.keys(lockfile.importers)) { - const baseName = new Path(importerKey).basename(); + const baseName: string | null = new Path(importerKey).basename(); if (baseName) { if (baseNames.has(baseName)) { duplicates.add(baseName); @@ -335,7 +336,7 @@ export function generateLockfileGraph( } } - const allPackages = []; + const allPackages: LfxGraphEntry[] = []; if (lockfile.packages) { for (const [dependencyKey, dependencyValue] of Object.entries(lockfile.packages)) { // const normalizedPath = new Path(dependencyKey).makeAbsolute('/').toString(); @@ -362,7 +363,7 @@ export function generateLockfileGraph( continue; } - const matchedEntry = allEntriesById[dependency.entryId]; + const matchedEntry: LfxGraphEntry = allEntriesById[dependency.entryId]; if (matchedEntry) { // Create a two-way link between the dependency and the entry dependency.resolvedEntry = matchedEntry; diff --git a/apps/lockfile-explorer/src/utils/shrinkwrap.ts b/apps/lockfile-explorer/src/utils/shrinkwrap.ts index 8cb289fc1e6..12792e3cebd 100644 --- a/apps/lockfile-explorer/src/utils/shrinkwrap.ts +++ b/apps/lockfile-explorer/src/utils/shrinkwrap.ts @@ -11,8 +11,9 @@ interface IPackageInfo { export function convertLockfileV6DepPathToV5DepPath(newDepPath: string): string { if (!newDepPath.includes('@', 2) || newDepPath.startsWith('file:')) return newDepPath; - const index = newDepPath.indexOf('@', newDepPath.indexOf('/@') + 2); - if (newDepPath.includes('(') && index > dependencyPathLockfilePreV9.indexOfPeersSuffix(newDepPath)) return newDepPath; + const index: number = newDepPath.indexOf('@', newDepPath.indexOf('/@') + 2); + if (newDepPath.includes('(') && index > dependencyPathLockfilePreV9.indexOfPeersSuffix(newDepPath)) + return newDepPath; return `${newDepPath.substring(0, index)}/${newDepPath.substring(index + 1)}`; } @@ -21,7 +22,8 @@ export function parseDependencyPath(shrinkwrapFileMajorVersion: number, newDepPa if (shrinkwrapFileMajorVersion === 6) { dependencyPath = convertLockfileV6DepPathToV5DepPath(newDepPath); } - const packageInfo = dependencyPathLockfilePreV9.parse(dependencyPath); + const packageInfo: ReturnType = + dependencyPathLockfilePreV9.parse(dependencyPath); return { name: packageInfo.name as string, peersSuffix: packageInfo.peersSuffix, @@ -55,5 +57,7 @@ export function splicePackageWithVersion( dependencyPackageName: string, dependencyPackageVersion: string ): string { - return `/${dependencyPackageName}${shrinkwrapFileMajorVersion === 6 ? '@' : '/'}${dependencyPackageVersion}`; + return `/${dependencyPackageName}${ + shrinkwrapFileMajorVersion === 6 ? '@' : '/' + }${dependencyPackageVersion}`; } From 7a209d608bc7049fb139932fba53f72c7c523268 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 12:33:32 -0700 Subject: [PATCH 16/26] Move the convertLockfileV6DepPathToV5DepPath() kludge down into lfxGraphLoader.generateLockfileGraph() so the test now passes --- .../cli/explorer/ExplorerCommandLineParser.ts | 13 --- .../src/graph/lfxGraphLoader.ts | 11 +++ .../lfxGraphLoader60.test.ts.snap | 88 ++++++++++++------- 3 files changed, 66 insertions(+), 46 deletions(-) diff --git a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts index 2529563ee78..e52fe440db2 100644 --- a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts +++ b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts @@ -25,7 +25,6 @@ import { import type { IAppState } from '../../state'; import { init } from '../../utils/init'; -import { convertLockfileV6DepPathToV5DepPath, getShrinkwrapFileMajorVersion } from '../../utils/shrinkwrap'; import * as lfxGraphLoader from '../../graph/lfxGraphLoader'; const EXPLORER_TOOL_FILENAME: 'lockfile-explorer' = 'lockfile-explorer'; @@ -155,18 +154,6 @@ export class ExplorerCommandLineParser extends CommandLineParser { const pnpmLockfileText: string = await FileSystem.readFileAsync(appState.pnpmLockfileLocation); const lockfile: Lockfile = yaml.load(pnpmLockfileText) as Lockfile; - const { packages, lockfileVersion } = lockfile; - - const shrinkwrapFileMajorVersion: number = getShrinkwrapFileMajorVersion(lockfileVersion); - - if (packages && shrinkwrapFileMajorVersion === 6) { - const updatedPackages: Lockfile['packages'] = {}; - for (const [dependencyPath, dependency] of Object.entries(packages)) { - updatedPackages[convertLockfileV6DepPathToV5DepPath(dependencyPath)] = dependency; - } - lockfile.packages = updatedPackages; - } - const graph: LfxGraph = lfxGraphLoader.generateLockfileGraph( appState.lfxWorkspace, lockfile as lfxGraphLoader.ILockfilePackageType, diff --git a/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts b/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts index 77ce289a125..5ab04345d10 100644 --- a/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts +++ b/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts @@ -14,6 +14,8 @@ import { type IJsonLfxWorkspace } from '../../temp/lfx-shared'; +import { convertLockfileV6DepPathToV5DepPath } from '../utils/shrinkwrap'; + enum PnpmLockfileVersion { V6, V5 @@ -299,6 +301,15 @@ export function generateLockfileGraph( if (parseInt(lockfile.lockfileVersion.toString(), 10) === 6) { pnpmLockfileVersion = PnpmLockfileVersion.V6; } + + if (lockfile.packages && pnpmLockfileVersion === PnpmLockfileVersion.V6) { + const updatedPackages: ILockfilePackageType['packages'] = {}; + for (const [dependencyPath, dependency] of Object.entries(lockfile.packages)) { + updatedPackages[convertLockfileV6DepPathToV5DepPath(dependencyPath)] = dependency; + } + lockfile.packages = updatedPackages; + } + const lfxGraph: LfxGraph = new LfxGraph(workspace); const allEntries: LfxGraphEntry[] = lfxGraph.entries; const allEntriesById: { [key: string]: LfxGraphEntry } = {}; diff --git a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap index 8f6b4529d7a..552498ed322 100644 --- a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap +++ b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap @@ -68,6 +68,7 @@ entries: name: ! '' version: ! '' optional: ! '' + resolvedEntryJsonId: 10 transitivePeerDependencies: [] referrerJsonIds: [] - jsonId: 3 @@ -97,6 +98,7 @@ entries: name: ! '' version: ! '' optional: ! '' + resolvedEntryJsonId: 7 - name: '@rushstack/m' version: 1.0.0 entryId: /@rushstack/m/1.0.0 @@ -105,6 +107,7 @@ entries: name: ! '' version: ! '' optional: ! '' + resolvedEntryJsonId: 9 transitivePeerDependencies: [] referrerJsonIds: [] - jsonId: 4 @@ -134,6 +137,7 @@ entries: name: ! '' version: ! '' optional: ! '' + resolvedEntryJsonId: 6 - name: '@rushstack/n' version: 2.0.0 entryId: /@rushstack/n/2.0.0 @@ -142,6 +146,7 @@ entries: name: ! '' version: ! '' optional: ! '' + resolvedEntryJsonId: 10 transitivePeerDependencies: [] referrerJsonIds: - 1 @@ -164,6 +169,7 @@ entries: name: ! '' version: ! '' optional: ! '' + resolvedEntryJsonId: 11 transitivePeerDependencies: [] referrerJsonIds: - 3 @@ -171,11 +177,11 @@ entries: - jsonId: 6 kind: 2 entryId: '' - rawEntryId: /@rushstack/j@1.0.0(@rushstack/n@2.0.0) + rawEntryId: /@rushstack/j/1.0.0(@rushstack/n@2.0.0) packageJsonFolderPath: >- - common/temp/undefined/node_modules/.pnpm/@rushstack+j@1.0.0(@rushstack@n@2.0.0)/node_modules/@rushstack/j@1.0.0(@rushstack - entryPackageName: '@rushstack/j@1.0.0(@rushstack' - displayText: '@rushstack/j@1.0.0(@rushstack n@2.0.0)' + common/temp/undefined/node_modules/.pnpm/@rushstack+j/1.0.0(@rushstack@n@2.0.0)/node_modules/@rushstack/j/1.0.0(@rushstack + entryPackageName: '@rushstack/j/1.0.0(@rushstack' + displayText: '@rushstack/j/1.0.0(@rushstack n@2.0.0)' entryPackageVersion: n@2.0.0) entrySuffix: '' dependencies: @@ -187,6 +193,7 @@ entries: name: ! '' version: ! '' optional: ! '' + resolvedEntryJsonId: 7 - name: '@rushstack/m' version: 1.0.0 entryId: /@rushstack/m/1.0.0 @@ -195,17 +202,19 @@ entries: name: ! '' version: ! '' optional: ! '' + resolvedEntryJsonId: 9 transitivePeerDependencies: - '@rushstack/n' - referrerJsonIds: [] + referrerJsonIds: + - 4 - jsonId: 7 kind: 2 entryId: '' - rawEntryId: /@rushstack/k@1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + rawEntryId: /@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) packageJsonFolderPath: >- - common/temp/undefined/node_modules/.pnpm/@rushstack+k@1.0.0(@rushstack/m@1.0.0)(@rushstack@n@2.0.0)/node_modules/@rushstack/k@1.0.0(@rushstack/m@1.0.0)(@rushstack - entryPackageName: '@rushstack/k@1.0.0(@rushstack/m@1.0.0)(@rushstack' - displayText: '@rushstack/k@1.0.0(@rushstack/m@1.0.0)(@rushstack n@2.0.0)' + common/temp/undefined/node_modules/.pnpm/@rushstack+k/1.0.0(@rushstack/m@1.0.0)(@rushstack@n@2.0.0)/node_modules/@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack + entryPackageName: '@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack' + displayText: '@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack n@2.0.0)' entryPackageVersion: n@2.0.0) entrySuffix: '' dependencies: @@ -217,18 +226,21 @@ entries: name: ! '' version: ! '' optional: ! '' + resolvedEntryJsonId: 8 transitivePeerDependencies: - '@rushstack/m' - '@rushstack/n' - referrerJsonIds: [] + referrerJsonIds: + - 3 + - 6 - jsonId: 8 kind: 2 entryId: '' - rawEntryId: /@rushstack/l@1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + rawEntryId: /@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) packageJsonFolderPath: >- - common/temp/undefined/node_modules/.pnpm/@rushstack+l@1.0.0(@rushstack/m@1.0.0)(@rushstack@n@2.0.0)/node_modules/@rushstack/l@1.0.0(@rushstack/m@1.0.0)(@rushstack - entryPackageName: '@rushstack/l@1.0.0(@rushstack/m@1.0.0)(@rushstack' - displayText: '@rushstack/l@1.0.0(@rushstack/m@1.0.0)(@rushstack n@2.0.0)' + common/temp/undefined/node_modules/.pnpm/@rushstack+l/1.0.0(@rushstack/m@1.0.0)(@rushstack@n@2.0.0)/node_modules/@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack + entryPackageName: '@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack' + displayText: '@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack n@2.0.0)' entryPackageVersion: n@2.0.0) entrySuffix: '' dependencies: @@ -240,6 +252,7 @@ entries: name: ! '' version: ! '' optional: ! '' + resolvedEntryJsonId: 9 - name: '@rushstack/n' version: 2.0.0 entryId: /@rushstack/n/2.0.0 @@ -248,6 +261,7 @@ entries: name: ! '' version: ! '' optional: ! '' + resolvedEntryJsonId: 10 - name: '@rushstack/m' version: ^1.0.0 entryId: 'Peer: @rushstack/m' @@ -265,42 +279,50 @@ entries: version: ^2.0.0 optional: true transitivePeerDependencies: [] - referrerJsonIds: [] + referrerJsonIds: + - 7 - jsonId: 9 kind: 2 entryId: '' - rawEntryId: /@rushstack/m@1.0.0 - packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack@m@1.0.0/node_modules/@rushstack - entryPackageName: '@rushstack' - displayText: '@rushstack m@1.0.0' - entryPackageVersion: m@1.0.0 + rawEntryId: /@rushstack/m/1.0.0 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+m@1.0.0/node_modules/@rushstack/m + entryPackageName: '@rushstack/m' + displayText: '@rushstack/m 1.0.0' + entryPackageVersion: 1.0.0 entrySuffix: '' dependencies: [] transitivePeerDependencies: [] - referrerJsonIds: [] + referrerJsonIds: + - 3 + - 6 + - 8 - jsonId: 10 kind: 2 entryId: '' - rawEntryId: /@rushstack/n@2.0.0 - packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack@n@2.0.0/node_modules/@rushstack - entryPackageName: '@rushstack' - displayText: '@rushstack n@2.0.0' - entryPackageVersion: n@2.0.0 + rawEntryId: /@rushstack/n/2.0.0 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+n@2.0.0/node_modules/@rushstack/n + entryPackageName: '@rushstack/n' + displayText: '@rushstack/n 2.0.0' + entryPackageVersion: 2.0.0 entrySuffix: '' dependencies: [] transitivePeerDependencies: [] - referrerJsonIds: [] + referrerJsonIds: + - 2 + - 4 + - 8 - jsonId: 11 kind: 2 entryId: '' - rawEntryId: /@rushstack/n@3.0.0 - packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack@n@3.0.0/node_modules/@rushstack - entryPackageName: '@rushstack' - displayText: '@rushstack n@3.0.0' - entryPackageVersion: n@3.0.0 + rawEntryId: /@rushstack/n/3.0.0 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+n@3.0.0/node_modules/@rushstack/n + entryPackageName: '@rushstack/n' + displayText: '@rushstack/n 3.0.0' + entryPackageVersion: 3.0.0 entrySuffix: '' dependencies: [] transitivePeerDependencies: [] - referrerJsonIds: [] + referrerJsonIds: + - 5 " `; From d9e5c11f718bb2ec3b17c697720d92025336cec5 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 12:50:20 -0700 Subject: [PATCH 17/26] Sort YAML to make snapshots more stable --- .../lfxGraphLoader54.test.ts.snap | 460 +++++++++--------- .../lfxGraphLoader60.test.ts.snap | 386 +++++++-------- .../src/graph/test/graphTestHelpers.ts | 7 +- 3 files changed, 429 insertions(+), 424 deletions(-) diff --git a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap index 1cefce4d51f..7dfc13409ad 100644 --- a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap +++ b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap @@ -1,389 +1,389 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` -"workspace: - workspaceRootFolder: /repo - pnpmLockfilePath: common/temp/pnpm-lock.yaml - rushConfig: - rushVersion: 5.83.3 - subspaceName: '' -entries: - - jsonId: 0 - kind: 1 +"entries: + - dependencies: [] + displayText: '' entryId: '' - rawEntryId: . - packageJsonFolderPath: '' entryPackageName: '' - displayText: '' entryPackageVersion: '' entrySuffix: '' - dependencies: [] - transitivePeerDependencies: [] - referrerJsonIds: [] - - jsonId: 1 + jsonId: 0 kind: 1 - entryId: 'project:./common/projects/a' - rawEntryId: ../../projects/a - packageJsonFolderPath: ./common/projects/a - entryPackageName: a - displayText: 'Project: a' - entryPackageVersion: '' - entrySuffix: '' - dependencies: - - name: '@rushstack/d' - version: 'link:../d' + packageJsonFolderPath: '' + rawEntryId: . + referrerJsonIds: [] + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: 'project:./common/projects/d' - dependencyType: regular + name: '@rushstack/d' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 4 - transitivePeerDependencies: [] - referrerJsonIds: [] - - jsonId: 2 - kind: 1 - entryId: 'project:./common/projects/b' - rawEntryId: ../../projects/b - packageJsonFolderPath: ./common/projects/b - entryPackageName: b - displayText: 'Project: b' + version: 'link:../d' + displayText: 'Project: a' + entryId: 'project:./common/projects/a' + entryPackageName: a entryPackageVersion: '' entrySuffix: '' - dependencies: - - name: '@rushstack/d' - version: 'link:../d' + jsonId: 1 + kind: 1 + packageJsonFolderPath: ./common/projects/a + rawEntryId: ../../projects/a + referrerJsonIds: [] + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: 'project:./common/projects/d' - dependencyType: regular + name: '@rushstack/d' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 4 - - name: '@rushstack/n' - version: 2.0.0 + version: 'link:../d' + - dependencyType: regular entryId: /@rushstack/n/2.0.0 - dependencyType: regular + name: '@rushstack/n' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 12 - transitivePeerDependencies: [] - referrerJsonIds: [] - - jsonId: 3 - kind: 1 - entryId: 'project:./common/projects/c' - rawEntryId: ../../projects/c - packageJsonFolderPath: ./common/projects/c - entryPackageName: c - displayText: 'Project: c' + version: 2.0.0 + displayText: 'Project: b' + entryId: 'project:./common/projects/b' + entryPackageName: b entryPackageVersion: '' entrySuffix: '' - dependencies: - - name: '@rushstack/e' - version: 'link:../e' + jsonId: 2 + kind: 1 + packageJsonFolderPath: ./common/projects/b + rawEntryId: ../../projects/b + referrerJsonIds: [] + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: 'project:./common/projects/e' - dependencyType: regular + name: '@rushstack/e' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 5 - - name: '@rushstack/k' - version: 1.0.0_@rushstack+m@1.0.0 + version: 'link:../e' + - dependencyType: regular entryId: /@rushstack/k/1.0.0_@rushstack+m@1.0.0 - dependencyType: regular + name: '@rushstack/k' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 7 - - name: '@rushstack/m' - version: 1.0.0 + version: 1.0.0_@rushstack+m@1.0.0 + - dependencyType: regular entryId: /@rushstack/m/1.0.0 - dependencyType: regular + name: '@rushstack/m' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 11 - transitivePeerDependencies: [] - referrerJsonIds: [] - - jsonId: 4 - kind: 1 - entryId: 'project:./common/projects/d' - rawEntryId: ../../projects/d - packageJsonFolderPath: ./common/projects/d - entryPackageName: d - displayText: 'Project: d' + version: 1.0.0 + displayText: 'Project: c' + entryId: 'project:./common/projects/c' + entryPackageName: c entryPackageVersion: '' entrySuffix: '' - dependencies: - - name: '@rushstack/e' - version: 'link:../e' + jsonId: 3 + kind: 1 + packageJsonFolderPath: ./common/projects/c + rawEntryId: ../../projects/c + referrerJsonIds: [] + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: 'project:./common/projects/e' - dependencyType: regular + name: '@rushstack/e' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 5 - - name: '@rushstack/j' - version: 1.0.0_@rushstack+n@2.0.0 + version: 'link:../e' + - dependencyType: regular entryId: /@rushstack/j/1.0.0_@rushstack+n@2.0.0 - dependencyType: regular + name: '@rushstack/j' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 6 - - name: '@rushstack/n' - version: 2.0.0 + version: 1.0.0_@rushstack+n@2.0.0 + - dependencyType: regular entryId: /@rushstack/n/2.0.0 - dependencyType: regular + name: '@rushstack/n' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 12 - transitivePeerDependencies: [] + version: 2.0.0 + displayText: 'Project: d' + entryId: 'project:./common/projects/d' + entryPackageName: d + entryPackageVersion: '' + entrySuffix: '' + jsonId: 4 + kind: 1 + packageJsonFolderPath: ./common/projects/d + rawEntryId: ../../projects/d referrerJsonIds: - 1 - 2 - - jsonId: 5 - kind: 1 - entryId: 'project:./common/projects/e' - rawEntryId: ../../projects/e - packageJsonFolderPath: ./common/projects/e - entryPackageName: e - displayText: 'Project: e' - entryPackageVersion: '' - entrySuffix: '' - dependencies: - - name: '@rushstack/n' - version: 3.0.0 + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: /@rushstack/n/3.0.0 - dependencyType: regular + name: '@rushstack/n' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 13 - transitivePeerDependencies: [] + version: 3.0.0 + displayText: 'Project: e' + entryId: 'project:./common/projects/e' + entryPackageName: e + entryPackageVersion: '' + entrySuffix: '' + jsonId: 5 + kind: 1 + packageJsonFolderPath: ./common/projects/e + rawEntryId: ../../projects/e referrerJsonIds: - 3 - 4 - - jsonId: 6 - kind: 2 - entryId: '' - rawEntryId: /@rushstack/j/1.0.0_@rushstack+n@2.0.0 - packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+j@1.0.0_@rushstack+n@2.0.0/node_modules/@rushstack/j - entryPackageName: '@rushstack/j' - displayText: '@rushstack/j 1.0.0 (@rushstack+n@2.0.0)' - entryPackageVersion: 1.0.0 - entrySuffix: '@rushstack+n@2.0.0' - dependencies: - - name: '@rushstack/k' - version: 1.0.0_wxpgugna4ivthu7yyu4fmciltu + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: /@rushstack/k/1.0.0_wxpgugna4ivthu7yyu4fmciltu - dependencyType: regular + name: '@rushstack/k' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 8 - - name: '@rushstack/m' - version: 1.0.0 + version: 1.0.0_wxpgugna4ivthu7yyu4fmciltu + - dependencyType: regular entryId: /@rushstack/m/1.0.0 - dependencyType: regular + name: '@rushstack/m' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 11 - transitivePeerDependencies: - - '@rushstack/n' - referrerJsonIds: - - 4 - - jsonId: 7 - kind: 2 + version: 1.0.0 + displayText: '@rushstack/j 1.0.0 (@rushstack+n@2.0.0)' entryId: '' - rawEntryId: /@rushstack/k/1.0.0_@rushstack+m@1.0.0 - packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+k@1.0.0_@rushstack+m@1.0.0/node_modules/@rushstack/k - entryPackageName: '@rushstack/k' - displayText: '@rushstack/k 1.0.0 (@rushstack+m@1.0.0)' + entryPackageName: '@rushstack/j' entryPackageVersion: 1.0.0 - entrySuffix: '@rushstack+m@1.0.0' - dependencies: - - name: '@rushstack/l' - version: 1.0.0_@rushstack+m@1.0.0 + entrySuffix: '@rushstack+n@2.0.0' + jsonId: 6 + kind: 2 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+j@1.0.0_@rushstack+n@2.0.0/node_modules/@rushstack/j + rawEntryId: /@rushstack/j/1.0.0_@rushstack+n@2.0.0 + referrerJsonIds: + - 4 + transitivePeerDependencies: + - '@rushstack/n' + - dependencies: + - dependencyType: regular entryId: /@rushstack/l/1.0.0_@rushstack+m@1.0.0 - dependencyType: regular + name: '@rushstack/l' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 9 - transitivePeerDependencies: - - '@rushstack/m' - - '@rushstack/n' - referrerJsonIds: - - 3 - - jsonId: 8 - kind: 2 + version: 1.0.0_@rushstack+m@1.0.0 + displayText: '@rushstack/k 1.0.0 (@rushstack+m@1.0.0)' entryId: '' - rawEntryId: /@rushstack/k/1.0.0_wxpgugna4ivthu7yyu4fmciltu - packageJsonFolderPath: >- - common/temp/undefined/node_modules/.pnpm/@rushstack+k@1.0.0_wxpgugna4ivthu7yyu4fmciltu/node_modules/@rushstack/k entryPackageName: '@rushstack/k' - displayText: '@rushstack/k 1.0.0 (wxpgugna4ivthu7yyu4fmciltu)' entryPackageVersion: 1.0.0 - entrySuffix: wxpgugna4ivthu7yyu4fmciltu - dependencies: - - name: '@rushstack/l' - version: 1.0.0_wxpgugna4ivthu7yyu4fmciltu + entrySuffix: '@rushstack+m@1.0.0' + jsonId: 7 + kind: 2 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+k@1.0.0_@rushstack+m@1.0.0/node_modules/@rushstack/k + rawEntryId: /@rushstack/k/1.0.0_@rushstack+m@1.0.0 + referrerJsonIds: + - 3 + transitivePeerDependencies: + - '@rushstack/m' + - '@rushstack/n' + - dependencies: + - dependencyType: regular entryId: /@rushstack/l/1.0.0_wxpgugna4ivthu7yyu4fmciltu - dependencyType: regular + name: '@rushstack/l' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 10 + version: 1.0.0_wxpgugna4ivthu7yyu4fmciltu + displayText: '@rushstack/k 1.0.0 (wxpgugna4ivthu7yyu4fmciltu)' + entryId: '' + entryPackageName: '@rushstack/k' + entryPackageVersion: 1.0.0 + entrySuffix: wxpgugna4ivthu7yyu4fmciltu + jsonId: 8 + kind: 2 + packageJsonFolderPath: >- + common/temp/undefined/node_modules/.pnpm/@rushstack+k@1.0.0_wxpgugna4ivthu7yyu4fmciltu/node_modules/@rushstack/k + rawEntryId: /@rushstack/k/1.0.0_wxpgugna4ivthu7yyu4fmciltu + referrerJsonIds: + - 6 transitivePeerDependencies: - '@rushstack/m' - '@rushstack/n' - referrerJsonIds: - - 6 - - jsonId: 9 - kind: 2 - entryId: '' - rawEntryId: /@rushstack/l/1.0.0_@rushstack+m@1.0.0 - packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+l@1.0.0_@rushstack+m@1.0.0/node_modules/@rushstack/l - entryPackageName: '@rushstack/l' - displayText: '@rushstack/l 1.0.0 (@rushstack+m@1.0.0)' - entryPackageVersion: 1.0.0 - entrySuffix: '@rushstack+m@1.0.0' - dependencies: - - name: '@rushstack/m' - version: 1.0.0 + - dependencies: + - dependencyType: regular entryId: /@rushstack/m/1.0.0 - dependencyType: regular + name: '@rushstack/m' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 11 - - name: '@rushstack/m' - version: ^1.0.0 + version: 1.0.0 + - dependencyType: peer entryId: 'Peer: @rushstack/m' - dependencyType: peer + name: '@rushstack/m' peerDependencyMeta: name: '@rushstack/m' - version: ^1.0.0 optional: false - - name: '@rushstack/n' - version: ^2.0.0 + version: ^1.0.0 + version: ^1.0.0 + - dependencyType: peer entryId: 'Peer: @rushstack/n' - dependencyType: peer + name: '@rushstack/n' peerDependencyMeta: name: '@rushstack/n' - version: ^2.0.0 optional: true - transitivePeerDependencies: [] - referrerJsonIds: - - 7 - - jsonId: 10 - kind: 2 + version: ^2.0.0 + version: ^2.0.0 + displayText: '@rushstack/l 1.0.0 (@rushstack+m@1.0.0)' entryId: '' - rawEntryId: /@rushstack/l/1.0.0_wxpgugna4ivthu7yyu4fmciltu - packageJsonFolderPath: >- - common/temp/undefined/node_modules/.pnpm/@rushstack+l@1.0.0_wxpgugna4ivthu7yyu4fmciltu/node_modules/@rushstack/l entryPackageName: '@rushstack/l' - displayText: '@rushstack/l 1.0.0 (wxpgugna4ivthu7yyu4fmciltu)' entryPackageVersion: 1.0.0 - entrySuffix: wxpgugna4ivthu7yyu4fmciltu - dependencies: - - name: '@rushstack/m' - version: 1.0.0 + entrySuffix: '@rushstack+m@1.0.0' + jsonId: 9 + kind: 2 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+l@1.0.0_@rushstack+m@1.0.0/node_modules/@rushstack/l + rawEntryId: /@rushstack/l/1.0.0_@rushstack+m@1.0.0 + referrerJsonIds: + - 7 + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: /@rushstack/m/1.0.0 - dependencyType: regular + name: '@rushstack/m' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 11 - - name: '@rushstack/n' - version: 2.0.0 + version: 1.0.0 + - dependencyType: regular entryId: /@rushstack/n/2.0.0 - dependencyType: regular + name: '@rushstack/n' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 12 - - name: '@rushstack/m' - version: ^1.0.0 + version: 2.0.0 + - dependencyType: peer entryId: 'Peer: @rushstack/m' - dependencyType: peer + name: '@rushstack/m' peerDependencyMeta: name: '@rushstack/m' - version: ^1.0.0 optional: false - - name: '@rushstack/n' - version: ^2.0.0 + version: ^1.0.0 + version: ^1.0.0 + - dependencyType: peer entryId: 'Peer: @rushstack/n' - dependencyType: peer + name: '@rushstack/n' peerDependencyMeta: name: '@rushstack/n' - version: ^2.0.0 optional: true - transitivePeerDependencies: [] + version: ^2.0.0 + version: ^2.0.0 + displayText: '@rushstack/l 1.0.0 (wxpgugna4ivthu7yyu4fmciltu)' + entryId: '' + entryPackageName: '@rushstack/l' + entryPackageVersion: 1.0.0 + entrySuffix: wxpgugna4ivthu7yyu4fmciltu + jsonId: 10 + kind: 2 + packageJsonFolderPath: >- + common/temp/undefined/node_modules/.pnpm/@rushstack+l@1.0.0_wxpgugna4ivthu7yyu4fmciltu/node_modules/@rushstack/l + rawEntryId: /@rushstack/l/1.0.0_wxpgugna4ivthu7yyu4fmciltu referrerJsonIds: - 8 - - jsonId: 11 - kind: 2 + transitivePeerDependencies: [] + - dependencies: [] + displayText: '@rushstack/m 1.0.0' entryId: '' - rawEntryId: /@rushstack/m/1.0.0 - packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+m@1.0.0/node_modules/@rushstack/m entryPackageName: '@rushstack/m' - displayText: '@rushstack/m 1.0.0' entryPackageVersion: 1.0.0 entrySuffix: '' - dependencies: [] - transitivePeerDependencies: [] + jsonId: 11 + kind: 2 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+m@1.0.0/node_modules/@rushstack/m + rawEntryId: /@rushstack/m/1.0.0 referrerJsonIds: - 3 - 6 - 9 - 10 - - jsonId: 12 - kind: 2 + transitivePeerDependencies: [] + - dependencies: [] + displayText: '@rushstack/n 2.0.0' entryId: '' - rawEntryId: /@rushstack/n/2.0.0 - packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+n@2.0.0/node_modules/@rushstack/n entryPackageName: '@rushstack/n' - displayText: '@rushstack/n 2.0.0' entryPackageVersion: 2.0.0 entrySuffix: '' - dependencies: [] - transitivePeerDependencies: [] + jsonId: 12 + kind: 2 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+n@2.0.0/node_modules/@rushstack/n + rawEntryId: /@rushstack/n/2.0.0 referrerJsonIds: - 2 - 4 - 10 - - jsonId: 13 - kind: 2 + transitivePeerDependencies: [] + - dependencies: [] + displayText: '@rushstack/n 3.0.0' entryId: '' - rawEntryId: /@rushstack/n/3.0.0 - packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+n@3.0.0/node_modules/@rushstack/n entryPackageName: '@rushstack/n' - displayText: '@rushstack/n 3.0.0' entryPackageVersion: 3.0.0 entrySuffix: '' - dependencies: [] - transitivePeerDependencies: [] + jsonId: 13 + kind: 2 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+n@3.0.0/node_modules/@rushstack/n + rawEntryId: /@rushstack/n/3.0.0 referrerJsonIds: - 5 + transitivePeerDependencies: [] +workspace: + pnpmLockfilePath: common/temp/pnpm-lock.yaml + rushConfig: + rushVersion: 5.83.3 + subspaceName: '' + workspaceRootFolder: /repo " `; diff --git a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap index 552498ed322..c2330867ab2 100644 --- a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap +++ b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap @@ -1,328 +1,328 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`lfxGraphLoader 6.0 loads a workspace 1`] = ` -"workspace: - workspaceRootFolder: /repo - pnpmLockfilePath: common/temp/pnpm-lock.yaml - rushConfig: - rushVersion: 5.158.1 - subspaceName: '' -entries: - - jsonId: 0 - kind: 1 +"entries: + - dependencies: [] + displayText: '' entryId: '' - rawEntryId: . - packageJsonFolderPath: '' entryPackageName: '' - displayText: '' entryPackageVersion: '' entrySuffix: '' - dependencies: [] - transitivePeerDependencies: [] - referrerJsonIds: [] - - jsonId: 1 + jsonId: 0 kind: 1 - entryId: 'project:./common/projects/a' - rawEntryId: ../../projects/a - packageJsonFolderPath: ./common/projects/a - entryPackageName: a - displayText: 'Project: a' - entryPackageVersion: '' - entrySuffix: '' - dependencies: - - name: '@rushstack/d' - version: 'link:../d' + packageJsonFolderPath: '' + rawEntryId: . + referrerJsonIds: [] + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: 'project:./common/projects/d' - dependencyType: regular + name: '@rushstack/d' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 4 - transitivePeerDependencies: [] - referrerJsonIds: [] - - jsonId: 2 - kind: 1 - entryId: 'project:./common/projects/b' - rawEntryId: ../../projects/b - packageJsonFolderPath: ./common/projects/b - entryPackageName: b - displayText: 'Project: b' + version: 'link:../d' + displayText: 'Project: a' + entryId: 'project:./common/projects/a' + entryPackageName: a entryPackageVersion: '' entrySuffix: '' - dependencies: - - name: '@rushstack/d' - version: 'link:../d' + jsonId: 1 + kind: 1 + packageJsonFolderPath: ./common/projects/a + rawEntryId: ../../projects/a + referrerJsonIds: [] + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: 'project:./common/projects/d' - dependencyType: regular + name: '@rushstack/d' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 4 - - name: '@rushstack/n' - version: 2.0.0 + version: 'link:../d' + - dependencyType: regular entryId: /@rushstack/n/2.0.0 - dependencyType: regular + name: '@rushstack/n' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 10 - transitivePeerDependencies: [] - referrerJsonIds: [] - - jsonId: 3 - kind: 1 - entryId: 'project:./common/projects/c' - rawEntryId: ../../projects/c - packageJsonFolderPath: ./common/projects/c - entryPackageName: c - displayText: 'Project: c' + version: 2.0.0 + displayText: 'Project: b' + entryId: 'project:./common/projects/b' + entryPackageName: b entryPackageVersion: '' entrySuffix: '' - dependencies: - - name: '@rushstack/e' - version: 'link:../e' + jsonId: 2 + kind: 1 + packageJsonFolderPath: ./common/projects/b + rawEntryId: ../../projects/b + referrerJsonIds: [] + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: 'project:./common/projects/e' - dependencyType: regular + name: '@rushstack/e' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 5 - - name: '@rushstack/k' - version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + version: 'link:../e' + - dependencyType: regular entryId: /@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) - dependencyType: regular + name: '@rushstack/k' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 7 - - name: '@rushstack/m' - version: 1.0.0 + version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + - dependencyType: regular entryId: /@rushstack/m/1.0.0 - dependencyType: regular + name: '@rushstack/m' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 9 - transitivePeerDependencies: [] - referrerJsonIds: [] - - jsonId: 4 - kind: 1 - entryId: 'project:./common/projects/d' - rawEntryId: ../../projects/d - packageJsonFolderPath: ./common/projects/d - entryPackageName: d - displayText: 'Project: d' + version: 1.0.0 + displayText: 'Project: c' + entryId: 'project:./common/projects/c' + entryPackageName: c entryPackageVersion: '' entrySuffix: '' - dependencies: - - name: '@rushstack/e' - version: 'link:../e' + jsonId: 3 + kind: 1 + packageJsonFolderPath: ./common/projects/c + rawEntryId: ../../projects/c + referrerJsonIds: [] + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: 'project:./common/projects/e' - dependencyType: regular + name: '@rushstack/e' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 5 - - name: '@rushstack/j' - version: 1.0.0(@rushstack/n@2.0.0) + version: 'link:../e' + - dependencyType: regular entryId: /@rushstack/j/1.0.0(@rushstack/n@2.0.0) - dependencyType: regular + name: '@rushstack/j' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 6 - - name: '@rushstack/n' - version: 2.0.0 + version: 1.0.0(@rushstack/n@2.0.0) + - dependencyType: regular entryId: /@rushstack/n/2.0.0 - dependencyType: regular + name: '@rushstack/n' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 10 - transitivePeerDependencies: [] + version: 2.0.0 + displayText: 'Project: d' + entryId: 'project:./common/projects/d' + entryPackageName: d + entryPackageVersion: '' + entrySuffix: '' + jsonId: 4 + kind: 1 + packageJsonFolderPath: ./common/projects/d + rawEntryId: ../../projects/d referrerJsonIds: - 1 - 2 - - jsonId: 5 - kind: 1 - entryId: 'project:./common/projects/e' - rawEntryId: ../../projects/e - packageJsonFolderPath: ./common/projects/e - entryPackageName: e - displayText: 'Project: e' - entryPackageVersion: '' - entrySuffix: '' - dependencies: - - name: '@rushstack/n' - version: 3.0.0 + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: /@rushstack/n/3.0.0 - dependencyType: regular + name: '@rushstack/n' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 11 - transitivePeerDependencies: [] + version: 3.0.0 + displayText: 'Project: e' + entryId: 'project:./common/projects/e' + entryPackageName: e + entryPackageVersion: '' + entrySuffix: '' + jsonId: 5 + kind: 1 + packageJsonFolderPath: ./common/projects/e + rawEntryId: ../../projects/e referrerJsonIds: - 3 - 4 - - jsonId: 6 - kind: 2 - entryId: '' - rawEntryId: /@rushstack/j/1.0.0(@rushstack/n@2.0.0) - packageJsonFolderPath: >- - common/temp/undefined/node_modules/.pnpm/@rushstack+j/1.0.0(@rushstack@n@2.0.0)/node_modules/@rushstack/j/1.0.0(@rushstack - entryPackageName: '@rushstack/j/1.0.0(@rushstack' - displayText: '@rushstack/j/1.0.0(@rushstack n@2.0.0)' - entryPackageVersion: n@2.0.0) - entrySuffix: '' - dependencies: - - name: '@rushstack/k' - version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + transitivePeerDependencies: [] + - dependencies: + - dependencyType: regular entryId: /@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) - dependencyType: regular + name: '@rushstack/k' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 7 - - name: '@rushstack/m' - version: 1.0.0 + version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + - dependencyType: regular entryId: /@rushstack/m/1.0.0 - dependencyType: regular + name: '@rushstack/m' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 9 - transitivePeerDependencies: - - '@rushstack/n' - referrerJsonIds: - - 4 - - jsonId: 7 - kind: 2 + version: 1.0.0 + displayText: '@rushstack/j/1.0.0(@rushstack n@2.0.0)' entryId: '' - rawEntryId: /@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) - packageJsonFolderPath: >- - common/temp/undefined/node_modules/.pnpm/@rushstack+k/1.0.0(@rushstack/m@1.0.0)(@rushstack@n@2.0.0)/node_modules/@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack - entryPackageName: '@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack' - displayText: '@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack n@2.0.0)' + entryPackageName: '@rushstack/j/1.0.0(@rushstack' entryPackageVersion: n@2.0.0) entrySuffix: '' - dependencies: - - name: '@rushstack/l' - version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + jsonId: 6 + kind: 2 + packageJsonFolderPath: >- + common/temp/undefined/node_modules/.pnpm/@rushstack+j/1.0.0(@rushstack@n@2.0.0)/node_modules/@rushstack/j/1.0.0(@rushstack + rawEntryId: /@rushstack/j/1.0.0(@rushstack/n@2.0.0) + referrerJsonIds: + - 4 + transitivePeerDependencies: + - '@rushstack/n' + - dependencies: + - dependencyType: regular entryId: /@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) - dependencyType: regular + name: '@rushstack/l' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 8 - transitivePeerDependencies: - - '@rushstack/m' - - '@rushstack/n' - referrerJsonIds: - - 3 - - 6 - - jsonId: 8 - kind: 2 + version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + displayText: '@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack n@2.0.0)' entryId: '' - rawEntryId: /@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) - packageJsonFolderPath: >- - common/temp/undefined/node_modules/.pnpm/@rushstack+l/1.0.0(@rushstack/m@1.0.0)(@rushstack@n@2.0.0)/node_modules/@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack - entryPackageName: '@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack' - displayText: '@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack n@2.0.0)' + entryPackageName: '@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack' entryPackageVersion: n@2.0.0) entrySuffix: '' - dependencies: - - name: '@rushstack/m' - version: 1.0.0 + jsonId: 7 + kind: 2 + packageJsonFolderPath: >- + common/temp/undefined/node_modules/.pnpm/@rushstack+k/1.0.0(@rushstack/m@1.0.0)(@rushstack@n@2.0.0)/node_modules/@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack + rawEntryId: /@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) + referrerJsonIds: + - 3 + - 6 + transitivePeerDependencies: + - '@rushstack/m' + - '@rushstack/n' + - dependencies: + - dependencyType: regular entryId: /@rushstack/m/1.0.0 - dependencyType: regular + name: '@rushstack/m' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 9 - - name: '@rushstack/n' - version: 2.0.0 + version: 1.0.0 + - dependencyType: regular entryId: /@rushstack/n/2.0.0 - dependencyType: regular + name: '@rushstack/n' peerDependencyMeta: name: ! '' - version: ! '' optional: ! '' + version: ! '' resolvedEntryJsonId: 10 - - name: '@rushstack/m' - version: ^1.0.0 + version: 2.0.0 + - dependencyType: peer entryId: 'Peer: @rushstack/m' - dependencyType: peer + name: '@rushstack/m' peerDependencyMeta: name: '@rushstack/m' - version: ^1.0.0 optional: false - - name: '@rushstack/n' - version: ^2.0.0 + version: ^1.0.0 + version: ^1.0.0 + - dependencyType: peer entryId: 'Peer: @rushstack/n' - dependencyType: peer + name: '@rushstack/n' peerDependencyMeta: name: '@rushstack/n' - version: ^2.0.0 optional: true - transitivePeerDependencies: [] + version: ^2.0.0 + version: ^2.0.0 + displayText: '@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack n@2.0.0)' + entryId: '' + entryPackageName: '@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack' + entryPackageVersion: n@2.0.0) + entrySuffix: '' + jsonId: 8 + kind: 2 + packageJsonFolderPath: >- + common/temp/undefined/node_modules/.pnpm/@rushstack+l/1.0.0(@rushstack/m@1.0.0)(@rushstack@n@2.0.0)/node_modules/@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack + rawEntryId: /@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) referrerJsonIds: - 7 - - jsonId: 9 - kind: 2 + transitivePeerDependencies: [] + - dependencies: [] + displayText: '@rushstack/m 1.0.0' entryId: '' - rawEntryId: /@rushstack/m/1.0.0 - packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+m@1.0.0/node_modules/@rushstack/m entryPackageName: '@rushstack/m' - displayText: '@rushstack/m 1.0.0' entryPackageVersion: 1.0.0 entrySuffix: '' - dependencies: [] - transitivePeerDependencies: [] + jsonId: 9 + kind: 2 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+m@1.0.0/node_modules/@rushstack/m + rawEntryId: /@rushstack/m/1.0.0 referrerJsonIds: - 3 - 6 - 8 - - jsonId: 10 - kind: 2 + transitivePeerDependencies: [] + - dependencies: [] + displayText: '@rushstack/n 2.0.0' entryId: '' - rawEntryId: /@rushstack/n/2.0.0 - packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+n@2.0.0/node_modules/@rushstack/n entryPackageName: '@rushstack/n' - displayText: '@rushstack/n 2.0.0' entryPackageVersion: 2.0.0 entrySuffix: '' - dependencies: [] - transitivePeerDependencies: [] + jsonId: 10 + kind: 2 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+n@2.0.0/node_modules/@rushstack/n + rawEntryId: /@rushstack/n/2.0.0 referrerJsonIds: - 2 - 4 - 8 - - jsonId: 11 - kind: 2 + transitivePeerDependencies: [] + - dependencies: [] + displayText: '@rushstack/n 3.0.0' entryId: '' - rawEntryId: /@rushstack/n/3.0.0 - packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+n@3.0.0/node_modules/@rushstack/n entryPackageName: '@rushstack/n' - displayText: '@rushstack/n 3.0.0' entryPackageVersion: 3.0.0 entrySuffix: '' - dependencies: [] - transitivePeerDependencies: [] + jsonId: 11 + kind: 2 + packageJsonFolderPath: common/temp/undefined/node_modules/.pnpm/@rushstack+n@3.0.0/node_modules/@rushstack/n + rawEntryId: /@rushstack/n/3.0.0 referrerJsonIds: - 5 + transitivePeerDependencies: [] +workspace: + pnpmLockfilePath: common/temp/pnpm-lock.yaml + rushConfig: + rushVersion: 5.158.1 + subspaceName: '' + workspaceRootFolder: /repo " `; diff --git a/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts b/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts index 46e1214eb26..37cf193215c 100644 --- a/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts +++ b/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts @@ -26,6 +26,11 @@ export async function loadAndSerializeLFxGraph(options: { const lockfileObject = yaml.load(lockfileYaml) as lfxGraphLoader.ILockfilePackageType; const graph: LfxGraph = lfxGraphLoader.generateLockfileGraph(options.workspace, lockfileObject); const serializedObject: IJsonLfxGraph = lfxGraphSerializer.serializeToJson(graph); - const serializedYaml: string = yaml.dump(serializedObject, { noRefs: true, lineWidth: 110 }); + const serializedYaml: string = yaml.dump(serializedObject, { + noRefs: true, + sortKeys: true, + noCompatMode: true, + lineWidth: 110 + }); return serializedYaml; } From 1ab1eb822227d2e9dd990881b652d73d2503a86a Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 13:09:31 -0700 Subject: [PATCH 18/26] Upgrade "js-yaml" from "~3.13.1" to "~4.1.0" --- apps/api-documenter/package.json | 4 +- apps/lockfile-explorer/package.json | 4 +- .../build-tests-subspace/pnpm-lock.yaml | 33 ++++------ .../build-tests-subspace/repo-state.json | 4 +- .../config/subspaces/default/pnpm-lock.yaml | 66 ++++++++----------- .../config/subspaces/default/repo-state.json | 2 +- libraries/rush-lib/package.json | 4 +- .../doc-plugin-rush-stack/package.json | 4 +- 8 files changed, 53 insertions(+), 68 deletions(-) diff --git a/apps/api-documenter/package.json b/apps/api-documenter/package.json index 0e2e59990da..dedd7522377 100644 --- a/apps/api-documenter/package.json +++ b/apps/api-documenter/package.json @@ -25,12 +25,12 @@ "@rushstack/node-core-library": "workspace:*", "@rushstack/terminal": "workspace:*", "@rushstack/ts-command-line": "workspace:*", - "js-yaml": "~3.13.1", + "js-yaml": "~4.1.0", "resolve": "~1.22.1" }, "devDependencies": { "@rushstack/heft": "workspace:*", - "@types/js-yaml": "3.12.1", + "@types/js-yaml": "4.0.9", "@types/resolve": "1.20.2", "eslint": "~9.25.1", "local-node-rig": "workspace:*" diff --git a/apps/lockfile-explorer/package.json b/apps/lockfile-explorer/package.json index 6969a39773d..4e175cb7851 100644 --- a/apps/lockfile-explorer/package.json +++ b/apps/lockfile-explorer/package.json @@ -51,7 +51,7 @@ "@rushstack/lockfile-explorer-web": "workspace:*", "@types/cors": "~2.8.12", "@types/express": "4.17.21", - "@types/js-yaml": "3.12.1", + "@types/js-yaml": "4.0.9", "@types/update-notifier": "~6.0.1", "eslint": "~9.25.1", "local-node-rig": "workspace:*", @@ -69,7 +69,7 @@ "@rushstack/ts-command-line": "workspace:*", "cors": "~2.8.5", "express": "4.20.0", - "js-yaml": "~3.13.1", + "js-yaml": "~4.1.0", "open": "~8.4.0", "semver": "~7.5.4", "update-notifier": "~5.1.0" diff --git a/common/config/subspaces/build-tests-subspace/pnpm-lock.yaml b/common/config/subspaces/build-tests-subspace/pnpm-lock.yaml index 31209c4ff7f..7c125ac9f67 100644 --- a/common/config/subspaces/build-tests-subspace/pnpm-lock.yaml +++ b/common/config/subspaces/build-tests-subspace/pnpm-lock.yaml @@ -105,10 +105,10 @@ importers: version: file:../../../apps/heft(@types/node@20.17.19) '@rushstack/heft-lint-plugin': specifier: file:../../heft-plugins/heft-lint-plugin - version: file:../../../heft-plugins/heft-lint-plugin(@rushstack/heft@0.74.3)(@types/node@20.17.19) + version: file:../../../heft-plugins/heft-lint-plugin(@rushstack/heft@0.74.5)(@types/node@20.17.19) '@rushstack/heft-typescript-plugin': specifier: file:../../heft-plugins/heft-typescript-plugin - version: file:../../../heft-plugins/heft-typescript-plugin(@rushstack/heft@0.74.3)(@types/node@20.17.19) + version: file:../../../heft-plugins/heft-typescript-plugin(@rushstack/heft@0.74.5)(@types/node@20.17.19) eslint: specifier: ~9.25.1 version: 9.25.1 @@ -4516,13 +4516,6 @@ packages: /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - /js-yaml@3.13.1: - resolution: {integrity: sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -6902,7 +6895,7 @@ packages: - supports-color dev: true - file:../../../heft-plugins/heft-api-extractor-plugin(@rushstack/heft@0.74.3)(@types/node@20.17.19): + file:../../../heft-plugins/heft-api-extractor-plugin(@rushstack/heft@0.74.5)(@types/node@20.17.19): resolution: {directory: ../../../heft-plugins/heft-api-extractor-plugin, type: directory} id: file:../../../heft-plugins/heft-api-extractor-plugin name: '@rushstack/heft-api-extractor-plugin' @@ -6916,7 +6909,7 @@ packages: - '@types/node' dev: true - file:../../../heft-plugins/heft-jest-plugin(@rushstack/heft@0.74.3)(@types/node@20.17.19)(jest-environment-node@29.5.0): + file:../../../heft-plugins/heft-jest-plugin(@rushstack/heft@0.74.5)(@types/node@20.17.19)(jest-environment-node@29.5.0): resolution: {directory: ../../../heft-plugins/heft-jest-plugin, type: directory} id: file:../../../heft-plugins/heft-jest-plugin name: '@rushstack/heft-jest-plugin' @@ -6951,7 +6944,7 @@ packages: - ts-node dev: true - file:../../../heft-plugins/heft-lint-plugin(@rushstack/heft@0.74.3)(@types/node@20.17.19): + file:../../../heft-plugins/heft-lint-plugin(@rushstack/heft@0.74.5)(@types/node@20.17.19): resolution: {directory: ../../../heft-plugins/heft-lint-plugin, type: directory} id: file:../../../heft-plugins/heft-lint-plugin name: '@rushstack/heft-lint-plugin' @@ -6966,7 +6959,7 @@ packages: - '@types/node' dev: true - file:../../../heft-plugins/heft-typescript-plugin(@rushstack/heft@0.74.3)(@types/node@20.17.19): + file:../../../heft-plugins/heft-typescript-plugin(@rushstack/heft@0.74.5)(@types/node@20.17.19): resolution: {directory: ../../../heft-plugins/heft-typescript-plugin, type: directory} id: file:../../../heft-plugins/heft-typescript-plugin name: '@rushstack/heft-typescript-plugin' @@ -7120,7 +7113,7 @@ packages: https-proxy-agent: 5.0.1 ignore: 5.1.9 inquirer: 8.2.7(@types/node@20.17.19) - js-yaml: 3.13.1 + js-yaml: 4.1.0 npm-check: 6.0.1 npm-package-arg: 6.1.1 pnpm-sync-lib: 0.3.2 @@ -7193,7 +7186,7 @@ packages: transitivePeerDependencies: - '@types/node' - file:../../../rigs/heft-node-rig(@rushstack/heft@0.74.3)(@types/node@20.17.19): + file:../../../rigs/heft-node-rig(@rushstack/heft@0.74.5)(@types/node@20.17.19): resolution: {directory: ../../../rigs/heft-node-rig, type: directory} id: file:../../../rigs/heft-node-rig name: '@rushstack/heft-node-rig' @@ -7203,10 +7196,10 @@ packages: '@microsoft/api-extractor': file:../../../apps/api-extractor(@types/node@20.17.19) '@rushstack/eslint-config': file:../../../eslint/eslint-config(eslint@9.25.1)(typescript@5.8.2) '@rushstack/heft': file:../../../apps/heft(@types/node@20.17.19) - '@rushstack/heft-api-extractor-plugin': file:../../../heft-plugins/heft-api-extractor-plugin(@rushstack/heft@0.74.3)(@types/node@20.17.19) - '@rushstack/heft-jest-plugin': file:../../../heft-plugins/heft-jest-plugin(@rushstack/heft@0.74.3)(@types/node@20.17.19)(jest-environment-node@29.5.0) - '@rushstack/heft-lint-plugin': file:../../../heft-plugins/heft-lint-plugin(@rushstack/heft@0.74.3)(@types/node@20.17.19) - '@rushstack/heft-typescript-plugin': file:../../../heft-plugins/heft-typescript-plugin(@rushstack/heft@0.74.3)(@types/node@20.17.19) + '@rushstack/heft-api-extractor-plugin': file:../../../heft-plugins/heft-api-extractor-plugin(@rushstack/heft@0.74.5)(@types/node@20.17.19) + '@rushstack/heft-jest-plugin': file:../../../heft-plugins/heft-jest-plugin(@rushstack/heft@0.74.5)(@types/node@20.17.19)(jest-environment-node@29.5.0) + '@rushstack/heft-lint-plugin': file:../../../heft-plugins/heft-lint-plugin(@rushstack/heft@0.74.5)(@types/node@20.17.19) + '@rushstack/heft-typescript-plugin': file:../../../heft-plugins/heft-typescript-plugin(@rushstack/heft@0.74.5)(@types/node@20.17.19) '@types/heft-jest': 1.0.1 eslint: 9.25.1 jest-environment-node: 29.5.0 @@ -7228,7 +7221,7 @@ packages: '@microsoft/api-extractor': file:../../../apps/api-extractor(@types/node@20.17.19) '@rushstack/eslint-patch': file:../../../eslint/eslint-patch '@rushstack/heft': file:../../../apps/heft(@types/node@20.17.19) - '@rushstack/heft-node-rig': file:../../../rigs/heft-node-rig(@rushstack/heft@0.74.3)(@types/node@20.17.19) + '@rushstack/heft-node-rig': file:../../../rigs/heft-node-rig(@rushstack/heft@0.74.5)(@types/node@20.17.19) '@types/heft-jest': 1.0.1 '@types/node': 20.17.19 eslint: 9.25.1 diff --git a/common/config/subspaces/build-tests-subspace/repo-state.json b/common/config/subspaces/build-tests-subspace/repo-state.json index c8006dca5f9..df8d3168341 100644 --- a/common/config/subspaces/build-tests-subspace/repo-state.json +++ b/common/config/subspaces/build-tests-subspace/repo-state.json @@ -1,6 +1,6 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "79b1140f2f030775f15eb0e2a4a1fc175f8f93e4", + "pnpmShrinkwrapHash": "f89693a88037554bf0c35db4f2295ef771cd2a71", "preferredVersionsHash": "550b4cee0bef4e97db6c6aad726df5149d20e7d9", - "packageJsonInjectedDependenciesHash": "e126030136de647c674c725e365ee7321eb18f72" + "packageJsonInjectedDependenciesHash": "364e001eac655a92be31ddb4bbf0d8b291d1e9cc" } diff --git a/common/config/subspaces/default/pnpm-lock.yaml b/common/config/subspaces/default/pnpm-lock.yaml index 03956e606a4..b19882175df 100644 --- a/common/config/subspaces/default/pnpm-lock.yaml +++ b/common/config/subspaces/default/pnpm-lock.yaml @@ -31,8 +31,8 @@ importers: specifier: workspace:* version: link:../../libraries/ts-command-line js-yaml: - specifier: ~3.13.1 - version: 3.13.1 + specifier: ~4.1.0 + version: 4.1.0 resolve: specifier: ~1.22.1 version: 1.22.8 @@ -41,8 +41,8 @@ importers: specifier: workspace:* version: link:../heft '@types/js-yaml': - specifier: 3.12.1 - version: 3.12.1 + specifier: 4.0.9 + version: 4.0.9 '@types/resolve': specifier: 1.20.2 version: 1.20.2 @@ -221,8 +221,8 @@ importers: specifier: 4.20.0 version: 4.20.0 js-yaml: - specifier: ~3.13.1 - version: 3.13.1 + specifier: ~4.1.0 + version: 4.1.0 open: specifier: ~8.4.0 version: 8.4.2 @@ -252,8 +252,8 @@ importers: specifier: 4.17.21 version: 4.17.21 '@types/js-yaml': - specifier: 3.12.1 - version: 3.12.1 + specifier: 4.0.9 + version: 4.0.9 '@types/semver': specifier: 7.5.0 version: 7.5.0 @@ -3633,8 +3633,8 @@ importers: specifier: ~8.2.7 version: 8.2.7 js-yaml: - specifier: ~3.13.1 - version: 3.13.1 + specifier: ~4.1.0 + version: 4.1.0 npm-check: specifier: ~6.0.1 version: 6.0.1 @@ -3700,8 +3700,8 @@ importers: specifier: 7.3.1 version: 7.3.1 '@types/js-yaml': - specifier: 3.12.1 - version: 3.12.1 + specifier: 4.0.9 + version: 4.0.9 '@types/npm-package-arg': specifier: 6.1.0 version: 6.1.0 @@ -3980,15 +3980,15 @@ importers: specifier: workspace:* version: link:../../libraries/node-core-library js-yaml: - specifier: ~3.13.1 - version: 3.13.1 + specifier: ~4.1.0 + version: 4.1.0 devDependencies: '@rushstack/heft': specifier: workspace:* version: link:../../apps/heft '@types/js-yaml': - specifier: 3.12.1 - version: 3.12.1 + specifier: 4.0.9 + version: 4.0.9 eslint: specifier: ~9.25.1 version: 9.25.1(supports-color@8.1.1) @@ -8026,7 +8026,7 @@ packages: globals: 12.4.0 ignore: 4.0.6 import-fresh: 3.3.0 - js-yaml: 3.13.1 + js-yaml: 3.14.1 lodash: 4.17.21 minimatch: 3.1.2 strip-json-comments: 3.1.1 @@ -8044,7 +8044,7 @@ packages: globals: 13.24.0 ignore: 4.0.6 import-fresh: 3.3.0 - js-yaml: 3.13.1 + js-yaml: 3.14.1 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: @@ -9702,7 +9702,7 @@ packages: camelcase: 5.3.1 find-up: 4.1.0 get-package-type: 0.1.0 - js-yaml: 3.13.1 + js-yaml: 3.14.1 resolve-from: 5.0.0 /@istanbuljs/schema@0.1.3: @@ -13879,8 +13879,8 @@ packages: resolution: {integrity: sha512-LFt+YA7Lv2IZROMwokZKiPNORAV5N3huMs3IKnzlE430HWhWYZ8b+78HiwJXJJP1V2IEjinyJURuRJfGoaFSIA==} dev: true - /@types/js-yaml@3.12.1: - resolution: {integrity: sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==} + /@types/js-yaml@4.0.9: + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} dev: true /@types/jsdom@20.0.1: @@ -19613,7 +19613,7 @@ packages: import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 - js-yaml: 3.13.1 + js-yaml: 3.14.1 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash: 4.17.21 @@ -19663,7 +19663,7 @@ packages: import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 - js-yaml: 3.13.1 + js-yaml: 3.14.1 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash.merge: 4.6.2 @@ -19709,7 +19709,7 @@ packages: import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 - js-yaml: 3.13.1 + js-yaml: 3.14.1 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash: 4.17.21 @@ -23363,20 +23363,12 @@ packages: /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - /js-yaml@3.13.1: - resolution: {integrity: sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true dependencies: argparse: 1.0.10 esprima: 4.0.1 - dev: false /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} @@ -23805,7 +23797,7 @@ packages: engines: {node: '>=6'} dependencies: graceful-fs: 4.2.11 - js-yaml: 3.13.1 + js-yaml: 3.14.1 pify: 4.0.1 strip-bom: 3.0.0 dev: false @@ -29310,7 +29302,7 @@ packages: commander: 2.20.3 diff: 4.0.2 glob: 7.2.3 - js-yaml: 3.13.1 + js-yaml: 3.14.1 minimatch: 3.1.2 mkdirp: 0.5.6 resolve: 1.22.8 @@ -29333,7 +29325,7 @@ packages: commander: 2.20.3 diff: 4.0.2 glob: 7.2.3 - js-yaml: 3.13.1 + js-yaml: 3.14.1 minimatch: 3.1.2 mkdirp: 0.5.6 resolve: 1.22.8 @@ -29356,7 +29348,7 @@ packages: commander: 2.20.3 diff: 4.0.2 glob: 7.2.3 - js-yaml: 3.13.1 + js-yaml: 3.14.1 minimatch: 3.1.2 mkdirp: 0.5.6 resolve: 1.22.8 @@ -29379,7 +29371,7 @@ packages: commander: 2.20.3 diff: 4.0.2 glob: 7.2.3 - js-yaml: 3.13.1 + js-yaml: 3.14.1 minimatch: 3.1.2 mkdirp: 0.5.6 resolve: 1.22.8 diff --git a/common/config/subspaces/default/repo-state.json b/common/config/subspaces/default/repo-state.json index b484328badb..3c852d397ea 100644 --- a/common/config/subspaces/default/repo-state.json +++ b/common/config/subspaces/default/repo-state.json @@ -1,5 +1,5 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "0514179437811ed9b568114b19d8ecf0943f75dc", + "pnpmShrinkwrapHash": "43e8674ca74b9c3f20cf12f03de5ce2968017331", "preferredVersionsHash": "61cd419c533464b580f653eb5f5a7e27fe7055ca" } diff --git a/libraries/rush-lib/package.json b/libraries/rush-lib/package.json index 2fcae0639a1..1c5090d7350 100644 --- a/libraries/rush-lib/package.json +++ b/libraries/rush-lib/package.json @@ -54,7 +54,7 @@ "https-proxy-agent": "~5.0.0", "ignore": "~5.1.6", "inquirer": "~8.2.7", - "js-yaml": "~3.13.1", + "js-yaml": "~4.1.0", "npm-check": "~6.0.1", "npm-package-arg": "~6.1.0", "pnpm-sync-lib": "0.3.2", @@ -80,7 +80,7 @@ "@rushstack/webpack-preserve-dynamic-require-plugin": "workspace:*", "@types/cli-table": "0.3.0", "@types/inquirer": "7.3.1", - "@types/js-yaml": "3.12.1", + "@types/js-yaml": "4.0.9", "@types/npm-package-arg": "6.1.0", "@types/read-package-tree": "5.1.0", "@types/semver": "7.5.0", diff --git a/repo-scripts/doc-plugin-rush-stack/package.json b/repo-scripts/doc-plugin-rush-stack/package.json index 0ec18c28e86..aeaff892a36 100644 --- a/repo-scripts/doc-plugin-rush-stack/package.json +++ b/repo-scripts/doc-plugin-rush-stack/package.json @@ -15,11 +15,11 @@ "@microsoft/api-extractor-model": "workspace:*", "@microsoft/tsdoc": "~0.15.1", "@rushstack/node-core-library": "workspace:*", - "js-yaml": "~3.13.1" + "js-yaml": "~4.1.0" }, "devDependencies": { "@rushstack/heft": "workspace:*", - "@types/js-yaml": "3.12.1", + "@types/js-yaml": "4.0.9", "eslint": "~9.25.1", "local-node-rig": "workspace:*" } From d2100fb8cc4e0b913ecc9b6d9b70da3f201d3589 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 13:10:23 -0700 Subject: [PATCH 19/26] Fix up callers to use the new safe-by-default API --- apps/api-documenter/src/documenters/OfficeYamlDocumenter.ts | 4 ++-- apps/api-documenter/src/documenters/YamlDocumenter.ts | 2 +- apps/api-documenter/src/utils/ToSdpConvertHelper.ts | 4 ++-- libraries/rush-lib/src/logic/ProjectImpactGraphGenerator.ts | 2 +- .../src/logic/installManager/WorkspaceInstallManager.ts | 4 +++- libraries/rush-lib/src/logic/pnpm/PnpmShrinkwrapFile.ts | 4 ++-- libraries/rush-lib/src/logic/pnpm/PnpmWorkspaceFile.ts | 2 +- .../src/logic/pnpm/test/PnpmShrinkwrapConverters.test.ts | 4 ++-- repo-scripts/doc-plugin-rush-stack/src/RushStackFeature.ts | 2 +- 9 files changed, 15 insertions(+), 13 deletions(-) diff --git a/apps/api-documenter/src/documenters/OfficeYamlDocumenter.ts b/apps/api-documenter/src/documenters/OfficeYamlDocumenter.ts index 0050b7147ce..a080458ddb6 100644 --- a/apps/api-documenter/src/documenters/OfficeYamlDocumenter.ts +++ b/apps/api-documenter/src/documenters/OfficeYamlDocumenter.ts @@ -48,8 +48,8 @@ export class OfficeYamlDocumenter extends YamlDocumenter { console.log('Loading snippets from ' + snippetsFilePath); const snippetsContent: string = FileSystem.readFile(snippetsFilePath); - this._snippets = yaml.load(snippetsContent, { filename: snippetsFilePath }); - this._snippetsAll = yaml.load(snippetsContent, { filename: snippetsFilePath }); + this._snippets = yaml.load(snippetsContent, { filename: snippetsFilePath }) as ISnippetsFile; + this._snippetsAll = yaml.load(snippetsContent, { filename: snippetsFilePath }) as ISnippetsFile; } /** @override */ diff --git a/apps/api-documenter/src/documenters/YamlDocumenter.ts b/apps/api-documenter/src/documenters/YamlDocumenter.ts index b165622ce84..0d51be689f6 100644 --- a/apps/api-documenter/src/documenters/YamlDocumenter.ts +++ b/apps/api-documenter/src/documenters/YamlDocumenter.ts @@ -756,7 +756,7 @@ export class YamlDocumenter { ): void { JsonFile.validateNoUndefinedMembers(dataObject); - let stringified: string = yaml.safeDump(dataObject, { + let stringified: string = yaml.dump(dataObject, { lineWidth: 120 }); diff --git a/apps/api-documenter/src/utils/ToSdpConvertHelper.ts b/apps/api-documenter/src/utils/ToSdpConvertHelper.ts index 2de3530d9fc..73815485793 100644 --- a/apps/api-documenter/src/utils/ToSdpConvertHelper.ts +++ b/apps/api-documenter/src/utils/ToSdpConvertHelper.ts @@ -49,10 +49,10 @@ function convert(inputPath: string, outputPath: string): void { console.log(`convert file ${fpath} from udp to sdp`); - const file: IYamlApiFile = yaml.safeLoad(yamlContent) as IYamlApiFile; + const file: IYamlApiFile = yaml.load(yamlContent) as IYamlApiFile; const result: { model: CommonYamlModel; type: string } | undefined = convertToSDP(file); if (result && result.model) { - const stringified: string = `### YamlMime:TS${result.type}\n${yaml.safeDump(result.model, { + const stringified: string = `### YamlMime:TS${result.type}\n${yaml.dump(result.model, { lineWidth: 120 })}`; FileSystem.writeFile(`${outputPath}/${name}`, stringified, { diff --git a/libraries/rush-lib/src/logic/ProjectImpactGraphGenerator.ts b/libraries/rush-lib/src/logic/ProjectImpactGraphGenerator.ts index ecd36bea9fd..9bfb3a888c1 100644 --- a/libraries/rush-lib/src/logic/ProjectImpactGraphGenerator.ts +++ b/libraries/rush-lib/src/logic/ProjectImpactGraphGenerator.ts @@ -141,7 +141,7 @@ export class ProjectImpactGraphGenerator { const projects: Record = Object.fromEntries(projectEntries); const content: IProjectImpactGraphFile = { globalExcludedGlobs, projects }; - await FileSystem.writeFileAsync(this._projectImpactGraphFilePath, yaml.safeDump(content)); + await FileSystem.writeFileAsync(this._projectImpactGraphFilePath, yaml.dump(content)); stopwatch.stop(); this._terminal.writeLine(); diff --git a/libraries/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts b/libraries/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts index ca5f40a1cf5..3846b1217ca 100644 --- a/libraries/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts +++ b/libraries/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts @@ -697,7 +697,9 @@ export class WorkspaceInstallManager extends BaseInstallManager { ) { // Find the .modules.yaml file in the subspace temp/node_modules folder const modulesContent: string = await FileSystem.readFileAsync(modulesFilePath); - const yamlContent: IPnpmModules = yaml.load(modulesContent, { filename: modulesFilePath }); + const yamlContent: IPnpmModules = yaml.load(modulesContent, { + filename: modulesFilePath + }) as IPnpmModules; const { hoistedDependencies } = yamlContent; const subspaceProject: RushConfigurationProject = subspace.getProjects()[0]; const projectNodeModulesPath: string = `${subspaceProject.projectFolder}/node_modules`; diff --git a/libraries/rush-lib/src/logic/pnpm/PnpmShrinkwrapFile.ts b/libraries/rush-lib/src/logic/pnpm/PnpmShrinkwrapFile.ts index f9fac5a2620..5c63d293cd9 100644 --- a/libraries/rush-lib/src/logic/pnpm/PnpmShrinkwrapFile.ts +++ b/libraries/rush-lib/src/logic/pnpm/PnpmShrinkwrapFile.ts @@ -399,7 +399,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { return cached; } - const shrinkwrapJson: IPnpmShrinkwrapYaml = yamlModule.safeLoad(shrinkwrapContent); + const shrinkwrapJson: IPnpmShrinkwrapYaml = yamlModule.load(shrinkwrapContent) as IPnpmShrinkwrapYaml; if ((shrinkwrapJson as LockfileFileV9).snapshots) { const lockfile: IPnpmShrinkwrapYaml | null = convertLockfileV9ToLockfileObject( shrinkwrapJson as LockfileFileV9 @@ -1317,6 +1317,6 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { } } - return yamlModule.safeDump(shrinkwrapToSerialize, PNPM_SHRINKWRAP_YAML_FORMAT); + return yamlModule.dump(shrinkwrapToSerialize, PNPM_SHRINKWRAP_YAML_FORMAT); } } diff --git a/libraries/rush-lib/src/logic/pnpm/PnpmWorkspaceFile.ts b/libraries/rush-lib/src/logic/pnpm/PnpmWorkspaceFile.ts index 0615741be7c..989ad898f77 100644 --- a/libraries/rush-lib/src/logic/pnpm/PnpmWorkspaceFile.ts +++ b/libraries/rush-lib/src/logic/pnpm/PnpmWorkspaceFile.ts @@ -66,6 +66,6 @@ export class PnpmWorkspaceFile extends BaseWorkspaceFile { const workspaceYaml: IPnpmWorkspaceYaml = { packages: Array.from(this._workspacePackages) }; - return yamlModule.safeDump(workspaceYaml, PNPM_SHRINKWRAP_YAML_FORMAT); + return yamlModule.dump(workspaceYaml, PNPM_SHRINKWRAP_YAML_FORMAT); } } diff --git a/libraries/rush-lib/src/logic/pnpm/test/PnpmShrinkwrapConverters.test.ts b/libraries/rush-lib/src/logic/pnpm/test/PnpmShrinkwrapConverters.test.ts index 673bf4826ff..912bbc55b7a 100644 --- a/libraries/rush-lib/src/logic/pnpm/test/PnpmShrinkwrapConverters.test.ts +++ b/libraries/rush-lib/src/logic/pnpm/test/PnpmShrinkwrapConverters.test.ts @@ -10,7 +10,7 @@ describe(convertLockfileV9ToLockfileObject.name, () => { const lockfileContent: string = FileSystem.readFile( `${__dirname}/yamlFiles/pnpm-lock-v9/pnpm-lock-v9.yaml` ); - const lockfileJson: LockfileFileV9 = yamlModule.safeLoad(lockfileContent); + const lockfileJson: LockfileFileV9 = yamlModule.load(lockfileContent) as LockfileFileV9; const lockfile = convertLockfileV9ToLockfileObject(lockfileJson); it('merge packages and snapshots', () => { @@ -39,7 +39,7 @@ describe(convertLockfileV9ToLockfileObject.name, () => { }); }); - it("no nullish values", () => { + it('no nullish values', () => { const importers = new Map(Object.entries(lockfile.importers || {})); const currentPackage = importers.get('.'); diff --git a/repo-scripts/doc-plugin-rush-stack/src/RushStackFeature.ts b/repo-scripts/doc-plugin-rush-stack/src/RushStackFeature.ts index 7de3c775426..d214295a313 100644 --- a/repo-scripts/doc-plugin-rush-stack/src/RushStackFeature.ts +++ b/repo-scripts/doc-plugin-rush-stack/src/RushStackFeature.ts @@ -55,7 +55,7 @@ export class RushStackFeature extends MarkdownDocumenterFeature { this._buildNavigation(navigationFile.api_nav, this.context.apiModel); const navFilePath: string = path.join(this.context.outputFolder, '..', 'api_nav.yaml'); - const navFileContent: string = yaml.safeDump(navigationFile, { lineWidth: 120 }); + const navFileContent: string = yaml.dump(navigationFile, { lineWidth: 120 }); FileSystem.writeFile(navFilePath, navFileContent, { ensureFolderExists: true }); } From 3c36d39f049432acdcbef0d35254957dedfe6887 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 13:13:40 -0700 Subject: [PATCH 20/26] Regenerate snapshot, eliminating `!` garbage --- .../lfxGraphLoader54.test.ts.snap | 111 +++++------------- .../lfxGraphLoader60.test.ts.snap | 101 +++++----------- 2 files changed, 58 insertions(+), 154 deletions(-) diff --git a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap index 7dfc13409ad..9bd8703a16b 100644 --- a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap +++ b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap @@ -16,16 +16,13 @@ exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` transitivePeerDependencies: [] - dependencies: - dependencyType: regular - entryId: 'project:./common/projects/d' + entryId: project:./common/projects/d name: '@rushstack/d' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 4 - version: 'link:../d' + version: link:../d displayText: 'Project: a' - entryId: 'project:./common/projects/a' + entryId: project:./common/projects/a entryPackageName: a entryPackageVersion: '' entrySuffix: '' @@ -37,25 +34,19 @@ exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` transitivePeerDependencies: [] - dependencies: - dependencyType: regular - entryId: 'project:./common/projects/d' + entryId: project:./common/projects/d name: '@rushstack/d' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 4 - version: 'link:../d' + version: link:../d - dependencyType: regular entryId: /@rushstack/n/2.0.0 name: '@rushstack/n' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 12 version: 2.0.0 displayText: 'Project: b' - entryId: 'project:./common/projects/b' + entryId: project:./common/projects/b entryPackageName: b entryPackageVersion: '' entrySuffix: '' @@ -67,34 +58,25 @@ exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` transitivePeerDependencies: [] - dependencies: - dependencyType: regular - entryId: 'project:./common/projects/e' + entryId: project:./common/projects/e name: '@rushstack/e' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 5 - version: 'link:../e' + version: link:../e - dependencyType: regular entryId: /@rushstack/k/1.0.0_@rushstack+m@1.0.0 name: '@rushstack/k' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 7 version: 1.0.0_@rushstack+m@1.0.0 - dependencyType: regular entryId: /@rushstack/m/1.0.0 name: '@rushstack/m' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 11 version: 1.0.0 displayText: 'Project: c' - entryId: 'project:./common/projects/c' + entryId: project:./common/projects/c entryPackageName: c entryPackageVersion: '' entrySuffix: '' @@ -106,34 +88,25 @@ exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` transitivePeerDependencies: [] - dependencies: - dependencyType: regular - entryId: 'project:./common/projects/e' + entryId: project:./common/projects/e name: '@rushstack/e' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 5 - version: 'link:../e' + version: link:../e - dependencyType: regular entryId: /@rushstack/j/1.0.0_@rushstack+n@2.0.0 name: '@rushstack/j' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 6 version: 1.0.0_@rushstack+n@2.0.0 - dependencyType: regular entryId: /@rushstack/n/2.0.0 name: '@rushstack/n' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 12 version: 2.0.0 displayText: 'Project: d' - entryId: 'project:./common/projects/d' + entryId: project:./common/projects/d entryPackageName: d entryPackageVersion: '' entrySuffix: '' @@ -149,14 +122,11 @@ exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` - dependencyType: regular entryId: /@rushstack/n/3.0.0 name: '@rushstack/n' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 13 version: 3.0.0 displayText: 'Project: e' - entryId: 'project:./common/projects/e' + entryId: project:./common/projects/e entryPackageName: e entryPackageVersion: '' entrySuffix: '' @@ -172,19 +142,13 @@ exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` - dependencyType: regular entryId: /@rushstack/k/1.0.0_wxpgugna4ivthu7yyu4fmciltu name: '@rushstack/k' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 8 version: 1.0.0_wxpgugna4ivthu7yyu4fmciltu - dependencyType: regular entryId: /@rushstack/m/1.0.0 name: '@rushstack/m' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 11 version: 1.0.0 displayText: '@rushstack/j 1.0.0 (@rushstack+n@2.0.0)' @@ -204,10 +168,7 @@ exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` - dependencyType: regular entryId: /@rushstack/l/1.0.0_@rushstack+m@1.0.0 name: '@rushstack/l' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 9 version: 1.0.0_@rushstack+m@1.0.0 displayText: '@rushstack/k 1.0.0 (@rushstack+m@1.0.0)' @@ -228,10 +189,7 @@ exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` - dependencyType: regular entryId: /@rushstack/l/1.0.0_wxpgugna4ivthu7yyu4fmciltu name: '@rushstack/l' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 10 version: 1.0.0_wxpgugna4ivthu7yyu4fmciltu displayText: '@rushstack/k 1.0.0 (wxpgugna4ivthu7yyu4fmciltu)' @@ -253,10 +211,7 @@ exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` - dependencyType: regular entryId: /@rushstack/m/1.0.0 name: '@rushstack/m' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 11 version: 1.0.0 - dependencyType: peer @@ -291,19 +246,13 @@ exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` - dependencyType: regular entryId: /@rushstack/m/1.0.0 name: '@rushstack/m' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 11 version: 1.0.0 - dependencyType: regular entryId: /@rushstack/n/2.0.0 name: '@rushstack/n' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 12 version: 2.0.0 - dependencyType: peer diff --git a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap index c2330867ab2..abd0957fda8 100644 --- a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap +++ b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap @@ -16,16 +16,13 @@ exports[`lfxGraphLoader 6.0 loads a workspace 1`] = ` transitivePeerDependencies: [] - dependencies: - dependencyType: regular - entryId: 'project:./common/projects/d' + entryId: project:./common/projects/d name: '@rushstack/d' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 4 - version: 'link:../d' + version: link:../d displayText: 'Project: a' - entryId: 'project:./common/projects/a' + entryId: project:./common/projects/a entryPackageName: a entryPackageVersion: '' entrySuffix: '' @@ -37,25 +34,19 @@ exports[`lfxGraphLoader 6.0 loads a workspace 1`] = ` transitivePeerDependencies: [] - dependencies: - dependencyType: regular - entryId: 'project:./common/projects/d' + entryId: project:./common/projects/d name: '@rushstack/d' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 4 - version: 'link:../d' + version: link:../d - dependencyType: regular entryId: /@rushstack/n/2.0.0 name: '@rushstack/n' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 10 version: 2.0.0 displayText: 'Project: b' - entryId: 'project:./common/projects/b' + entryId: project:./common/projects/b entryPackageName: b entryPackageVersion: '' entrySuffix: '' @@ -67,34 +58,25 @@ exports[`lfxGraphLoader 6.0 loads a workspace 1`] = ` transitivePeerDependencies: [] - dependencies: - dependencyType: regular - entryId: 'project:./common/projects/e' + entryId: project:./common/projects/e name: '@rushstack/e' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 5 - version: 'link:../e' + version: link:../e - dependencyType: regular entryId: /@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) name: '@rushstack/k' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 7 version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) - dependencyType: regular entryId: /@rushstack/m/1.0.0 name: '@rushstack/m' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 9 version: 1.0.0 displayText: 'Project: c' - entryId: 'project:./common/projects/c' + entryId: project:./common/projects/c entryPackageName: c entryPackageVersion: '' entrySuffix: '' @@ -106,34 +88,25 @@ exports[`lfxGraphLoader 6.0 loads a workspace 1`] = ` transitivePeerDependencies: [] - dependencies: - dependencyType: regular - entryId: 'project:./common/projects/e' + entryId: project:./common/projects/e name: '@rushstack/e' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 5 - version: 'link:../e' + version: link:../e - dependencyType: regular entryId: /@rushstack/j/1.0.0(@rushstack/n@2.0.0) name: '@rushstack/j' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 6 version: 1.0.0(@rushstack/n@2.0.0) - dependencyType: regular entryId: /@rushstack/n/2.0.0 name: '@rushstack/n' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 10 version: 2.0.0 displayText: 'Project: d' - entryId: 'project:./common/projects/d' + entryId: project:./common/projects/d entryPackageName: d entryPackageVersion: '' entrySuffix: '' @@ -149,14 +122,11 @@ exports[`lfxGraphLoader 6.0 loads a workspace 1`] = ` - dependencyType: regular entryId: /@rushstack/n/3.0.0 name: '@rushstack/n' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 11 version: 3.0.0 displayText: 'Project: e' - entryId: 'project:./common/projects/e' + entryId: project:./common/projects/e entryPackageName: e entryPackageVersion: '' entrySuffix: '' @@ -172,19 +142,13 @@ exports[`lfxGraphLoader 6.0 loads a workspace 1`] = ` - dependencyType: regular entryId: /@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) name: '@rushstack/k' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 7 version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) - dependencyType: regular entryId: /@rushstack/m/1.0.0 name: '@rushstack/m' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 9 version: 1.0.0 displayText: '@rushstack/j/1.0.0(@rushstack n@2.0.0)' @@ -205,10 +169,7 @@ exports[`lfxGraphLoader 6.0 loads a workspace 1`] = ` - dependencyType: regular entryId: /@rushstack/l/1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) name: '@rushstack/l' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 8 version: 1.0.0(@rushstack/m@1.0.0)(@rushstack/n@2.0.0) displayText: '@rushstack/k/1.0.0(@rushstack/m@1.0.0)(@rushstack n@2.0.0)' @@ -231,19 +192,13 @@ exports[`lfxGraphLoader 6.0 loads a workspace 1`] = ` - dependencyType: regular entryId: /@rushstack/m/1.0.0 name: '@rushstack/m' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 9 version: 1.0.0 - dependencyType: regular entryId: /@rushstack/n/2.0.0 name: '@rushstack/n' - peerDependencyMeta: - name: ! '' - optional: ! '' - version: ! '' + peerDependencyMeta: {} resolvedEntryJsonId: 10 version: 2.0.0 - dependencyType: peer From df2db7196fa1ba25e81cf509610f82f680b1b05f Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 13:17:03 -0700 Subject: [PATCH 21/26] rush change --- .../octogonz-js-yaml-upgrade_2025-09-14-20-16.json | 11 +++++++++++ .../octogonz-js-yaml-upgrade_2025-09-14-20-16.json | 11 +++++++++++ .../octogonz-js-yaml-upgrade_2025-09-14-20-16.json | 11 +++++++++++ 3 files changed, 33 insertions(+) create mode 100644 common/changes/@microsoft/api-documenter/octogonz-js-yaml-upgrade_2025-09-14-20-16.json create mode 100644 common/changes/@microsoft/rush/octogonz-js-yaml-upgrade_2025-09-14-20-16.json create mode 100644 common/changes/@rushstack/lockfile-explorer/octogonz-js-yaml-upgrade_2025-09-14-20-16.json diff --git a/common/changes/@microsoft/api-documenter/octogonz-js-yaml-upgrade_2025-09-14-20-16.json b/common/changes/@microsoft/api-documenter/octogonz-js-yaml-upgrade_2025-09-14-20-16.json new file mode 100644 index 00000000000..a26c6b3afd1 --- /dev/null +++ b/common/changes/@microsoft/api-documenter/octogonz-js-yaml-upgrade_2025-09-14-20-16.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "Upgraded `js-yaml` dependency", + "type": "patch", + "packageName": "@microsoft/api-documenter" + } + ], + "packageName": "@microsoft/api-documenter", + "email": "4673363+octogonz@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@microsoft/rush/octogonz-js-yaml-upgrade_2025-09-14-20-16.json b/common/changes/@microsoft/rush/octogonz-js-yaml-upgrade_2025-09-14-20-16.json new file mode 100644 index 00000000000..bf925b6cda8 --- /dev/null +++ b/common/changes/@microsoft/rush/octogonz-js-yaml-upgrade_2025-09-14-20-16.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "Upgraded `js-yaml` dependency", + "type": "none", + "packageName": "@microsoft/rush" + } + ], + "packageName": "@microsoft/rush", + "email": "4673363+octogonz@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@rushstack/lockfile-explorer/octogonz-js-yaml-upgrade_2025-09-14-20-16.json b/common/changes/@rushstack/lockfile-explorer/octogonz-js-yaml-upgrade_2025-09-14-20-16.json new file mode 100644 index 00000000000..8675acd12cd --- /dev/null +++ b/common/changes/@rushstack/lockfile-explorer/octogonz-js-yaml-upgrade_2025-09-14-20-16.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "Upgraded `js-yaml` dependency", + "type": "patch", + "packageName": "@rushstack/lockfile-explorer" + } + ], + "packageName": "@rushstack/lockfile-explorer", + "email": "4673363+octogonz@users.noreply.github.com" +} \ No newline at end of file From 9153e74c1021c24a2e2e5f8a757ef5a77a1c6d7a Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 13:19:38 -0700 Subject: [PATCH 22/26] Regenerate snapshot --- .../test/__snapshots__/snapshot.test.ts.snap | 318 +++++++++--------- 1 file changed, 159 insertions(+), 159 deletions(-) diff --git a/build-tests/api-documenter-test/src/test/__snapshots__/snapshot.test.ts.snap b/build-tests/api-documenter-test/src/test/__snapshots__/snapshot.test.ts.snap index 06d73c0c646..fabda2846fd 100644 --- a/build-tests/api-documenter-test/src/test/__snapshots__/snapshot.test.ts.snap +++ b/build-tests/api-documenter-test/src/test/__snapshots__/snapshot.test.ts.snap @@ -11,36 +11,36 @@ summary: |- This project tests various documentation generation scenarios and doc comment syntaxes. classes: - - 'api-documenter-test!AbstractClass:class' - - 'api-documenter-test!DecoratorExample:class' - - 'api-documenter-test!DocBaseClass:class' - - 'api-documenter-test!DocClass1:class' - - 'api-documenter-test!DocClassInterfaceMerge:class' - - 'api-documenter-test!Generic:class' - - 'api-documenter-test!SystemEvent:class' + - api-documenter-test!AbstractClass:class + - api-documenter-test!DecoratorExample:class + - api-documenter-test!DocBaseClass:class + - api-documenter-test!DocClass1:class + - api-documenter-test!DocClassInterfaceMerge:class + - api-documenter-test!Generic:class + - api-documenter-test!SystemEvent:class interfaces: - - 'api-documenter-test!Constraint:interface' - - 'api-documenter-test!DefaultType:interface' - - 'api-documenter-test!DocClassInterfaceMerge:interface' - - 'api-documenter-test!IDocInterface1:interface' - - 'api-documenter-test!IDocInterface2:interface' - - 'api-documenter-test!IDocInterface3:interface' - - 'api-documenter-test!IDocInterface4:interface' - - 'api-documenter-test!IDocInterface5:interface' - - 'api-documenter-test!IDocInterface6:interface' - - 'api-documenter-test!IDocInterface7:interface' + - api-documenter-test!Constraint:interface + - api-documenter-test!DefaultType:interface + - api-documenter-test!DocClassInterfaceMerge:interface + - api-documenter-test!IDocInterface1:interface + - api-documenter-test!IDocInterface2:interface + - api-documenter-test!IDocInterface3:interface + - api-documenter-test!IDocInterface4:interface + - api-documenter-test!IDocInterface5:interface + - api-documenter-test!IDocInterface6:interface + - api-documenter-test!IDocInterface7:interface enums: - - 'api-documenter-test!DocEnum:enum' - - 'api-documenter-test!DocEnumNamespaceMerge:enum' + - api-documenter-test!DocEnum:enum + - api-documenter-test!DocEnumNamespaceMerge:enum typeAliases: - - 'api-documenter-test!ExampleDuplicateTypeAlias:type' - - 'api-documenter-test!ExampleTypeAlias:type' - - 'api-documenter-test!ExampleUnionTypeAlias:type' - - 'api-documenter-test!GenericTypeAlias:type' - - 'api-documenter-test!TypeAlias:type' + - api-documenter-test!ExampleDuplicateTypeAlias:type + - api-documenter-test!ExampleTypeAlias:type + - api-documenter-test!ExampleUnionTypeAlias:type + - api-documenter-test!GenericTypeAlias:type + - api-documenter-test!TypeAlias:type functions: - - name: 'exampleFunction(x, y)' - uid: 'api-documenter-test!exampleFunction:function(1)' + - name: exampleFunction(x, y) + uid: api-documenter-test!exampleFunction:function(1) package: api-documenter-test! summary: An exported function with hyperlinked parameters and return value. remarks: '' @@ -52,15 +52,15 @@ functions: parameters: - id: x description: an API item that should get hyperlinked - type: '' + type: - id: 'y' description: a system type that should NOT get hyperlinked type: number return: - type: '' + type: description: an interface that should get hyperlinked - name: yamlReferenceUniquenessTest() - uid: 'api-documenter-test!yamlReferenceUniquenessTest:function(1)' + uid: api-documenter-test!yamlReferenceUniquenessTest:function(1) package: api-documenter-test! summary: '' remarks: '' @@ -70,12 +70,12 @@ functions: syntax: content: 'export declare function yamlReferenceUniquenessTest(): IDocInterface1;' return: - type: '' + type: description: '' ", "/api-documenter-test/abstractclass.yml": "### YamlMime:TSType name: AbstractClass -uid: 'api-documenter-test!AbstractClass:class' +uid: api-documenter-test!AbstractClass:class package: api-documenter-test! fullName: AbstractClass summary: Some abstract class with abstract members. @@ -86,7 +86,7 @@ isDeprecated: false type: class properties: - name: property - uid: 'api-documenter-test!AbstractClass#property:member' + uid: api-documenter-test!AbstractClass#property:member package: api-documenter-test! fullName: property summary: Some abstract property. @@ -100,7 +100,7 @@ properties: type: number methods: - name: method() - uid: 'api-documenter-test!AbstractClass#method:member(1)' + uid: api-documenter-test!AbstractClass#method:member(1) package: api-documenter-test! fullName: method() summary: Some abstract method. @@ -116,7 +116,7 @@ methods: ", "/api-documenter-test/constraint.yml": "### YamlMime:TSType name: Constraint -uid: 'api-documenter-test!Constraint:interface' +uid: api-documenter-test!Constraint:interface package: api-documenter-test! fullName: Constraint summary: Type parameter constraint used by test case below. @@ -128,7 +128,7 @@ type: interface ", "/api-documenter-test/decoratorexample.yml": "### YamlMime:TSType name: DecoratorExample -uid: 'api-documenter-test!DecoratorExample:class' +uid: api-documenter-test!DecoratorExample:class package: api-documenter-test! fullName: DecoratorExample summary: '' @@ -139,7 +139,7 @@ isDeprecated: false type: class properties: - name: creationDate - uid: 'api-documenter-test!DecoratorExample#creationDate:member' + uid: api-documenter-test!DecoratorExample#creationDate:member package: api-documenter-test! fullName: creationDate summary: The date when the record was created. @@ -154,7 +154,7 @@ properties: ", "/api-documenter-test/defaulttype.yml": "### YamlMime:TSType name: DefaultType -uid: 'api-documenter-test!DefaultType:interface' +uid: api-documenter-test!DefaultType:interface package: api-documenter-test! fullName: DefaultType summary: Type parameter default type used by test case below. @@ -166,7 +166,7 @@ type: interface ", "/api-documenter-test/docbaseclass.yml": "### YamlMime:TSType name: DocBaseClass -uid: 'api-documenter-test!DocBaseClass:class' +uid: api-documenter-test!DocBaseClass:class package: api-documenter-test! fullName: DocBaseClass summary: Example base class @@ -177,7 +177,7 @@ isDeprecated: false type: class constructors: - name: (constructor)() - uid: 'api-documenter-test!DocBaseClass:constructor(1)' + uid: api-documenter-test!DocBaseClass:constructor(1) package: api-documenter-test! fullName: (constructor)() summary: The simple constructor for \`DocBaseClass\` @@ -188,7 +188,7 @@ constructors: syntax: content: constructor(); - name: (constructor)(x) - uid: 'api-documenter-test!DocBaseClass:constructor(2)' + uid: api-documenter-test!DocBaseClass:constructor(2) package: api-documenter-test! fullName: (constructor)(x) summary: The overloaded constructor for \`DocBaseClass\` @@ -205,7 +205,7 @@ constructors: ", "/api-documenter-test/docclass1.yml": "### YamlMime:TSType name: DocClass1 -uid: 'api-documenter-test!DocClass1:class' +uid: api-documenter-test!DocClass1:class package: api-documenter-test! fullName: DocClass1 summary: This is an example class. @@ -225,7 +225,7 @@ isDeprecated: false type: class properties: - name: multipleModifiersProperty - uid: 'api-documenter-test!DocClass1.multipleModifiersProperty:member' + uid: api-documenter-test!DocClass1.multipleModifiersProperty:member package: api-documenter-test! fullName: multipleModifiersProperty summary: Some property with multiple modifiers. @@ -238,7 +238,7 @@ properties: return: type: boolean - name: protectedProperty - uid: 'api-documenter-test!DocClass1#protectedProperty:member' + uid: api-documenter-test!DocClass1#protectedProperty:member package: api-documenter-test! fullName: protectedProperty summary: Some protected property. @@ -251,7 +251,7 @@ properties: return: type: string - name: readonlyProperty - uid: 'api-documenter-test!DocClass1#readonlyProperty:member' + uid: api-documenter-test!DocClass1#readonlyProperty:member package: api-documenter-test! fullName: readonlyProperty summary: '' @@ -264,7 +264,7 @@ properties: return: type: string - name: regularProperty - uid: 'api-documenter-test!DocClass1#regularProperty:member' + uid: api-documenter-test!DocClass1#regularProperty:member package: api-documenter-test! fullName: regularProperty summary: This is a regular property that happens to use the SystemEvent type. @@ -275,9 +275,9 @@ properties: syntax: content: 'regularProperty: SystemEvent;' return: - type: '' + type: - name: writeableProperty - uid: 'api-documenter-test!DocClass1#writeableProperty:member' + uid: api-documenter-test!DocClass1#writeableProperty:member package: api-documenter-test! fullName: writeableProperty summary: '' @@ -293,7 +293,7 @@ properties: return: type: string - name: writeonlyProperty - uid: 'api-documenter-test!DocClass1#writeonlyProperty:member' + uid: api-documenter-test!DocClass1#writeonlyProperty:member package: api-documenter-test! fullName: writeonlyProperty summary: API Extractor will surface an \`ae-missing-getter\` finding for this property. @@ -307,7 +307,7 @@ properties: type: string methods: - name: deprecatedExample() - uid: 'api-documenter-test!DocClass1#deprecatedExample:member(1)' + uid: api-documenter-test!DocClass1#deprecatedExample:member(1) package: api-documenter-test! fullName: deprecatedExample() summary: '' @@ -321,10 +321,10 @@ methods: return: type: void description: '' - - name: 'exampleFunction(a, b)' - uid: 'api-documenter-test!DocClass1#exampleFunction:member(1)' + - name: exampleFunction(a, b) + uid: api-documenter-test!DocClass1#exampleFunction:member(1) package: api-documenter-test! - fullName: 'exampleFunction(a, b)' + fullName: exampleFunction(a, b) summary: This is an overloaded function. remarks: '' example: [] @@ -343,7 +343,7 @@ methods: type: string description: '' - name: exampleFunction(x) - uid: 'api-documenter-test!DocClass1#exampleFunction:member(2)' + uid: api-documenter-test!DocClass1#exampleFunction:member(2) package: api-documenter-test! fullName: exampleFunction(x) summary: This is also an overloaded function. @@ -361,7 +361,7 @@ methods: type: number description: '' - name: genericWithConstraintAndDefault(x) - uid: 'api-documenter-test!DocClass1#genericWithConstraintAndDefault:member(1)' + uid: api-documenter-test!DocClass1#genericWithConstraintAndDefault:member(1) package: api-documenter-test! fullName: genericWithConstraintAndDefault(x) summary: This is a method with a complex type parameter. @@ -379,7 +379,7 @@ methods: type: void description: '' - name: interestingEdgeCases() - uid: 'api-documenter-test!DocClass1#interestingEdgeCases:member(1)' + uid: api-documenter-test!DocClass1#interestingEdgeCases:member(1) package: api-documenter-test! fullName: interestingEdgeCases() summary: |- @@ -396,7 +396,7 @@ methods: type: void description: '' - name: optionalParamFunction(x) - uid: 'api-documenter-test!DocClass1#optionalParamFunction:member(1)' + uid: api-documenter-test!DocClass1#optionalParamFunction:member(1) package: api-documenter-test! fullName: optionalParamFunction(x) summary: This is a function with an optional parameter. @@ -413,10 +413,10 @@ methods: return: type: void description: '' - - name: 'sumWithExample(x, y)' - uid: 'api-documenter-test!DocClass1.sumWithExample:member(1)' + - name: sumWithExample(x, y) + uid: api-documenter-test!DocClass1.sumWithExample:member(1) package: api-documenter-test! - fullName: 'sumWithExample(x, y)' + fullName: sumWithExample(x, y) summary: Returns the sum of two numbers. remarks: This illustrates usage of the \`@example\` block tag. example: @@ -449,7 +449,7 @@ methods: type: number description: the sum of the two numbers - name: tableExample() - uid: 'api-documenter-test!DocClass1#tableExample:member(1)' + uid: api-documenter-test!DocClass1#tableExample:member(1) package: api-documenter-test! fullName: tableExample() summary: 'An example with tables:' @@ -464,7 +464,7 @@ methods: description: '' events: - name: malformedEvent - uid: 'api-documenter-test!DocClass1#malformedEvent:member' + uid: api-documenter-test!DocClass1#malformedEvent:member package: api-documenter-test! fullName: malformedEvent summary: This event should have been marked as readonly. @@ -475,9 +475,9 @@ events: syntax: content: 'malformedEvent: SystemEvent;' return: - type: '' + type: - name: modifiedEvent - uid: 'api-documenter-test!DocClass1#modifiedEvent:member' + uid: api-documenter-test!DocClass1#modifiedEvent:member package: api-documenter-test! fullName: modifiedEvent summary: This event is fired whenever the object is modified. @@ -488,12 +488,12 @@ events: syntax: content: 'readonly modifiedEvent: SystemEvent;' return: - type: '' -extends: '' + type: +extends: ", "/api-documenter-test/docclassinterfacemerge-class.yml": "### YamlMime:TSType name: DocClassInterfaceMerge -uid: 'api-documenter-test!DocClassInterfaceMerge:class' +uid: api-documenter-test!DocClassInterfaceMerge:class package: api-documenter-test! fullName: DocClassInterfaceMerge summary: Class that merges with interface @@ -508,7 +508,7 @@ type: class ", "/api-documenter-test/docclassinterfacemerge-interface.yml": "### YamlMime:TSType name: DocClassInterfaceMerge -uid: 'api-documenter-test!DocClassInterfaceMerge:interface' +uid: api-documenter-test!DocClassInterfaceMerge:interface package: api-documenter-test! fullName: DocClassInterfaceMerge summary: Interface that merges with class @@ -520,7 +520,7 @@ type: interface ", "/api-documenter-test/docenum.yml": "### YamlMime:TSEnum name: DocEnum -uid: 'api-documenter-test!DocEnum:enum' +uid: api-documenter-test!DocEnum:enum package: api-documenter-test! fullName: DocEnum summary: Docs for DocEnum @@ -530,12 +530,12 @@ isPreview: false isDeprecated: false fields: - name: One - uid: 'api-documenter-test!DocEnum.One:member' + uid: api-documenter-test!DocEnum.One:member package: api-documenter-test! summary: These are some docs for One value: '1' - name: Two - uid: 'api-documenter-test!DocEnum.Two:member' + uid: api-documenter-test!DocEnum.Two:member package: api-documenter-test! summary: |- These are some docs for Two. @@ -543,14 +543,14 @@ fields: [DocEnum.One](xref:api-documenter-test!DocEnum.One:member) is a direct link to another enum member. value: '2' - name: Zero - uid: 'api-documenter-test!DocEnum.Zero:member' + uid: api-documenter-test!DocEnum.Zero:member package: api-documenter-test! summary: These are some docs for Zero value: '0' ", "/api-documenter-test/docenumnamespacemerge-enum.yml": "### YamlMime:TSEnum name: DocEnumNamespaceMerge -uid: 'api-documenter-test!DocEnumNamespaceMerge:enum' +uid: api-documenter-test!DocEnumNamespaceMerge:enum package: api-documenter-test! fullName: DocEnumNamespaceMerge summary: Enum that merges with namespace @@ -565,19 +565,19 @@ isPreview: false isDeprecated: false fields: - name: Left - uid: 'api-documenter-test!DocEnumNamespaceMerge.Left:member' + uid: api-documenter-test!DocEnumNamespaceMerge.Left:member package: api-documenter-test! summary: These are some docs for Left value: '0' - name: Right - uid: 'api-documenter-test!DocEnumNamespaceMerge.Right:member' + uid: api-documenter-test!DocEnumNamespaceMerge.Right:member package: api-documenter-test! summary: These are some docs for Right value: '1' ", "/api-documenter-test/docenumnamespacemerge-namespace.yml": "### YamlMime:UniversalReference items: - - uid: 'api-documenter-test!DocEnumNamespaceMerge:namespace' + - uid: api-documenter-test!DocEnumNamespaceMerge:namespace summary: Namespace that merges with enum name: DocEnumNamespaceMerge fullName: DocEnumNamespaceMerge @@ -586,14 +586,14 @@ items: type: namespace package: api-documenter-test! children: - - 'api-documenter-test!DocEnumNamespaceMerge.exampleFunction:function(1)' - - uid: 'api-documenter-test!DocEnumNamespaceMerge.exampleFunction:function(1)' + - api-documenter-test!DocEnumNamespaceMerge.exampleFunction:function(1) + - uid: api-documenter-test!DocEnumNamespaceMerge.exampleFunction:function(1) summary: This is a function inside of a namespace that merges with an enum. name: exampleFunction() fullName: DocEnumNamespaceMerge.exampleFunction() langs: - typeScript - namespace: 'api-documenter-test!DocEnumNamespaceMerge:namespace' + namespace: api-documenter-test!DocEnumNamespaceMerge:namespace type: function syntax: content: 'function exampleFunction(): void;' @@ -604,7 +604,7 @@ items: ", "/api-documenter-test/ecmasymbols.yml": "### YamlMime:UniversalReference items: - - uid: 'api-documenter-test!EcmaSymbols:namespace' + - uid: api-documenter-test!EcmaSymbols:namespace summary: A namespace containing an ECMAScript symbol name: EcmaSymbols fullName: EcmaSymbols @@ -613,14 +613,14 @@ items: type: namespace package: api-documenter-test! children: - - 'api-documenter-test!EcmaSymbols.example:var' - - uid: 'api-documenter-test!EcmaSymbols.example:var' + - api-documenter-test!EcmaSymbols.example:var + - uid: api-documenter-test!EcmaSymbols.example:var summary: An ECMAScript symbol name: example fullName: EcmaSymbols.example langs: - typeScript - namespace: 'api-documenter-test!EcmaSymbols:namespace' + namespace: api-documenter-test!EcmaSymbols:namespace type: variable syntax: content: 'example: unique symbol' @@ -630,7 +630,7 @@ items: ", "/api-documenter-test/exampleduplicatetypealias.yml": "### YamlMime:TSTypeAlias name: ExampleDuplicateTypeAlias -uid: 'api-documenter-test!ExampleDuplicateTypeAlias:type' +uid: api-documenter-test!ExampleDuplicateTypeAlias:type package: api-documenter-test! fullName: ExampleDuplicateTypeAlias summary: A type alias that has duplicate references. @@ -642,7 +642,7 @@ syntax: export type ExampleDuplicateTypeAlias = SystemEvent | typeof SystemEvent ", "/api-documenter-test/exampletypealias.yml": "### YamlMime:TSTypeAlias name: ExampleTypeAlias -uid: 'api-documenter-test!ExampleTypeAlias:type' +uid: api-documenter-test!ExampleTypeAlias:type package: api-documenter-test! fullName: ExampleTypeAlias summary: A type alias @@ -654,7 +654,7 @@ syntax: export type ExampleTypeAlias = Promise; ", "/api-documenter-test/exampleuniontypealias.yml": "### YamlMime:TSTypeAlias name: ExampleUnionTypeAlias -uid: 'api-documenter-test!ExampleUnionTypeAlias:type' +uid: api-documenter-test!ExampleUnionTypeAlias:type package: api-documenter-test! fullName: ExampleUnionTypeAlias summary: A type alias that references multiple other types. @@ -666,7 +666,7 @@ syntax: export type ExampleUnionTypeAlias = IDocInterface1 | IDocInterface3; ", "/api-documenter-test/generic.yml": "### YamlMime:TSType name: Generic -uid: 'api-documenter-test!Generic:class' +uid: api-documenter-test!Generic:class package: api-documenter-test! fullName: Generic summary: Generic class. @@ -678,7 +678,7 @@ type: class ", "/api-documenter-test/generictypealias.yml": "### YamlMime:TSTypeAlias name: GenericTypeAlias -uid: 'api-documenter-test!GenericTypeAlias:type' +uid: api-documenter-test!GenericTypeAlias:type package: api-documenter-test! fullName: GenericTypeAlias summary: '' @@ -686,11 +686,11 @@ remarks: '' example: [] isPreview: false isDeprecated: false -syntax: 'export type GenericTypeAlias = T[];' +syntax: export type GenericTypeAlias = T[]; ", "/api-documenter-test/idocinterface1.yml": "### YamlMime:TSType name: IDocInterface1 -uid: 'api-documenter-test!IDocInterface1:interface' +uid: api-documenter-test!IDocInterface1:interface package: api-documenter-test! fullName: IDocInterface1 summary: '' @@ -701,7 +701,7 @@ isDeprecated: false type: interface properties: - name: regularProperty - uid: 'api-documenter-test!IDocInterface1#regularProperty:member' + uid: api-documenter-test!IDocInterface1#regularProperty:member package: api-documenter-test! fullName: regularProperty summary: Does something @@ -712,11 +712,11 @@ properties: syntax: content: 'regularProperty: SystemEvent;' return: - type: '' + type: ", "/api-documenter-test/idocinterface2.yml": "### YamlMime:TSType name: IDocInterface2 -uid: 'api-documenter-test!IDocInterface2:interface' +uid: api-documenter-test!IDocInterface2:interface package: api-documenter-test! fullName: IDocInterface2 summary: '' @@ -727,7 +727,7 @@ isDeprecated: false type: interface methods: - name: deprecatedExample() - uid: 'api-documenter-test!IDocInterface2#deprecatedExample:member(1)' + uid: api-documenter-test!IDocInterface2#deprecatedExample:member(1) package: api-documenter-test! fullName: deprecatedExample() summary: '' @@ -741,11 +741,11 @@ methods: return: type: void description: '' -extends: '' +extends: ", "/api-documenter-test/idocinterface3.yml": "### YamlMime:TSType name: IDocInterface3 -uid: 'api-documenter-test!IDocInterface3:interface' +uid: api-documenter-test!IDocInterface3:interface package: api-documenter-test! fullName: IDocInterface3 summary: Some less common TypeScript declaration kinds. @@ -756,7 +756,7 @@ isDeprecated: false type: interface properties: - name: '\\"[not.a.symbol]\\"' - uid: 'api-documenter-test!IDocInterface3#\\"[not.a.symbol]\\":member' + uid: api-documenter-test!IDocInterface3#\\"[not.a.symbol]\\":member package: api-documenter-test! fullName: '\\"[not.a.symbol]\\"' summary: An identifier that does need quotes. It misleadingly looks like an ECMAScript symbol. @@ -769,7 +769,7 @@ properties: return: type: string - name: '[EcmaSymbols.example]' - uid: 'api-documenter-test!IDocInterface3#[EcmaSymbols.example]:member' + uid: api-documenter-test!IDocInterface3#[EcmaSymbols.example]:member package: api-documenter-test! fullName: '[EcmaSymbols.example]' summary: ECMAScript symbol @@ -782,7 +782,7 @@ properties: return: type: string - name: redundantQuotes - uid: 'api-documenter-test!IDocInterface3#redundantQuotes:member' + uid: api-documenter-test!IDocInterface3#redundantQuotes:member package: api-documenter-test! fullName: redundantQuotes summary: A quoted identifier with redundant quotes. @@ -797,7 +797,7 @@ properties: ", "/api-documenter-test/idocinterface4.yml": "### YamlMime:TSType name: IDocInterface4 -uid: 'api-documenter-test!IDocInterface4:interface' +uid: api-documenter-test!IDocInterface4:interface package: api-documenter-test! fullName: IDocInterface4 summary: Type union in an interface. @@ -808,7 +808,7 @@ isDeprecated: false type: interface properties: - name: Context - uid: 'api-documenter-test!IDocInterface4#Context:member' + uid: api-documenter-test!IDocInterface4#Context:member package: api-documenter-test! fullName: Context summary: Test newline rendering when code blocks are used in tables @@ -827,7 +827,7 @@ properties: children: string; }) => boolean - name: generic - uid: 'api-documenter-test!IDocInterface4#generic:member' + uid: api-documenter-test!IDocInterface4#generic:member package: api-documenter-test! fullName: generic summary: make sure html entities are escaped in tables. @@ -838,9 +838,9 @@ properties: syntax: content: 'generic: Generic;' return: - type: '<number>' + type: <number> - name: numberOrFunction - uid: 'api-documenter-test!IDocInterface4#numberOrFunction:member' + uid: api-documenter-test!IDocInterface4#numberOrFunction:member package: api-documenter-test! fullName: numberOrFunction summary: a union type with a function @@ -853,7 +853,7 @@ properties: return: type: number | (() => number) - name: stringOrNumber - uid: 'api-documenter-test!IDocInterface4#stringOrNumber:member' + uid: api-documenter-test!IDocInterface4#stringOrNumber:member package: api-documenter-test! fullName: stringOrNumber summary: a union type @@ -868,7 +868,7 @@ properties: ", "/api-documenter-test/idocinterface5.yml": "### YamlMime:TSType name: IDocInterface5 -uid: 'api-documenter-test!IDocInterface5:interface' +uid: api-documenter-test!IDocInterface5:interface package: api-documenter-test! fullName: IDocInterface5 summary: Interface without inline tag to test custom TOC @@ -879,7 +879,7 @@ isDeprecated: false type: interface properties: - name: regularProperty - uid: 'api-documenter-test!IDocInterface5#regularProperty:member' + uid: api-documenter-test!IDocInterface5#regularProperty:member package: api-documenter-test! fullName: regularProperty summary: Property of type string that does something @@ -894,7 +894,7 @@ properties: ", "/api-documenter-test/idocinterface6.yml": "### YamlMime:TSType name: IDocInterface6 -uid: 'api-documenter-test!IDocInterface6:interface' +uid: api-documenter-test!IDocInterface6:interface package: api-documenter-test! fullName: IDocInterface6 summary: Interface without inline tag to test custom TOC with injection @@ -905,7 +905,7 @@ isDeprecated: false type: interface properties: - name: arrayProperty - uid: 'api-documenter-test!IDocInterface6#arrayProperty:member' + uid: api-documenter-test!IDocInterface6#arrayProperty:member package: api-documenter-test! fullName: arrayProperty summary: '' @@ -916,9 +916,9 @@ properties: syntax: content: 'arrayProperty: IDocInterface1[];' return: - type: '[]' + type: [] - name: intersectionProperty - uid: 'api-documenter-test!IDocInterface6#intersectionProperty:member' + uid: api-documenter-test!IDocInterface6#intersectionProperty:member package: api-documenter-test! fullName: intersectionProperty summary: '' @@ -933,7 +933,7 @@ properties: & - name: regularProperty - uid: 'api-documenter-test!IDocInterface6#regularProperty:member' + uid: api-documenter-test!IDocInterface6#regularProperty:member package: api-documenter-test! fullName: regularProperty summary: Property of type number that does something @@ -946,7 +946,7 @@ properties: return: type: number - name: tupleProperty - uid: 'api-documenter-test!IDocInterface6#tupleProperty:member' + uid: api-documenter-test!IDocInterface6#tupleProperty:member package: api-documenter-test! fullName: tupleProperty summary: '' @@ -961,7 +961,7 @@ properties: [, ] - name: typeReferenceProperty - uid: 'api-documenter-test!IDocInterface6#typeReferenceProperty:member' + uid: api-documenter-test!IDocInterface6#typeReferenceProperty:member package: api-documenter-test! fullName: typeReferenceProperty summary: '' @@ -976,7 +976,7 @@ properties: <> - name: unionProperty - uid: 'api-documenter-test!IDocInterface6#unionProperty:member' + uid: api-documenter-test!IDocInterface6#unionProperty:member package: api-documenter-test! fullName: unionProperty summary: '' @@ -992,7 +992,7 @@ properties: uid=\\"api-documenter-test!IDocInterface2:interface\\" /> methods: - name: genericReferenceMethod(x) - uid: 'api-documenter-test!IDocInterface6#genericReferenceMethod:member(1)' + uid: api-documenter-test!IDocInterface6#genericReferenceMethod:member(1) package: api-documenter-test! fullName: genericReferenceMethod(x) summary: '' @@ -1012,7 +1012,7 @@ methods: ", "/api-documenter-test/idocinterface7.yml": "### YamlMime:TSType name: IDocInterface7 -uid: 'api-documenter-test!IDocInterface7:interface' +uid: api-documenter-test!IDocInterface7:interface package: api-documenter-test! fullName: IDocInterface7 summary: Interface for testing optional properties @@ -1023,7 +1023,7 @@ isDeprecated: false type: interface properties: - name: optionalField - uid: 'api-documenter-test!IDocInterface7#optionalField:member' + uid: api-documenter-test!IDocInterface7#optionalField:member package: api-documenter-test! fullName: optionalField summary: Description of optionalField @@ -1036,7 +1036,7 @@ properties: return: type: boolean - name: optionalReadonlyField - uid: 'api-documenter-test!IDocInterface7#optionalReadonlyField:member' + uid: api-documenter-test!IDocInterface7#optionalReadonlyField:member package: api-documenter-test! fullName: optionalReadonlyField summary: Description of optionalReadonlyField @@ -1049,7 +1049,7 @@ properties: return: type: boolean - name: optionalUndocumentedField - uid: 'api-documenter-test!IDocInterface7#optionalUndocumentedField:member' + uid: api-documenter-test!IDocInterface7#optionalUndocumentedField:member package: api-documenter-test! fullName: optionalUndocumentedField summary: '' @@ -1063,7 +1063,7 @@ properties: type: boolean methods: - name: optionalMember() - uid: 'api-documenter-test!IDocInterface7#optionalMember:member(1)' + uid: api-documenter-test!IDocInterface7#optionalMember:member(1) package: api-documenter-test! fullName: optionalMember() summary: Description of optionalMember @@ -1079,7 +1079,7 @@ methods: ", "/api-documenter-test/outernamespace.innernamespace.yml": "### YamlMime:UniversalReference items: - - uid: 'api-documenter-test!OuterNamespace.InnerNamespace:namespace' + - uid: api-documenter-test!OuterNamespace.InnerNamespace:namespace summary: A nested namespace name: OuterNamespace.InnerNamespace fullName: OuterNamespace.InnerNamespace @@ -1088,14 +1088,14 @@ items: type: namespace package: api-documenter-test! children: - - 'api-documenter-test!OuterNamespace.InnerNamespace.nestedFunction:function(1)' - - uid: 'api-documenter-test!OuterNamespace.InnerNamespace.nestedFunction:function(1)' + - api-documenter-test!OuterNamespace.InnerNamespace.nestedFunction:function(1) + - uid: api-documenter-test!OuterNamespace.InnerNamespace.nestedFunction:function(1) summary: A function inside a namespace name: nestedFunction(x) fullName: OuterNamespace.InnerNamespace.nestedFunction(x) langs: - typeScript - namespace: 'api-documenter-test!OuterNamespace.InnerNamespace:namespace' + namespace: api-documenter-test!OuterNamespace.InnerNamespace:namespace type: function syntax: content: 'function nestedFunction(x: number): number;' @@ -1112,7 +1112,7 @@ items: ", "/api-documenter-test/outernamespace.yml": "### YamlMime:UniversalReference items: - - uid: 'api-documenter-test!OuterNamespace:namespace' + - uid: api-documenter-test!OuterNamespace:namespace summary: A top-level namespace name: OuterNamespace fullName: OuterNamespace @@ -1121,14 +1121,14 @@ items: type: namespace package: api-documenter-test! children: - - 'api-documenter-test!OuterNamespace.nestedVariable:var' - - uid: 'api-documenter-test!OuterNamespace.nestedVariable:var' + - api-documenter-test!OuterNamespace.nestedVariable:var + - uid: api-documenter-test!OuterNamespace.nestedVariable:var summary: A variable exported from within a namespace. name: nestedVariable fullName: OuterNamespace.nestedVariable langs: - typeScript - namespace: 'api-documenter-test!OuterNamespace:namespace' + namespace: api-documenter-test!OuterNamespace:namespace type: variable syntax: content: 'nestedVariable: boolean' @@ -1138,7 +1138,7 @@ items: ", "/api-documenter-test/systemevent.yml": "### YamlMime:TSType name: SystemEvent -uid: 'api-documenter-test!SystemEvent:class' +uid: api-documenter-test!SystemEvent:class package: api-documenter-test! fullName: SystemEvent summary: A class used to exposed events. @@ -1149,7 +1149,7 @@ isDeprecated: false type: class methods: - name: addHandler(handler) - uid: 'api-documenter-test!SystemEvent#addHandler:member(1)' + uid: api-documenter-test!SystemEvent#addHandler:member(1) package: api-documenter-test! fullName: addHandler(handler) summary: Adds an handler for the event. @@ -1169,7 +1169,7 @@ methods: ", "/api-documenter-test/typealias.yml": "### YamlMime:TSTypeAlias name: TypeAlias -uid: 'api-documenter-test!TypeAlias:type' +uid: api-documenter-test!TypeAlias:type package: api-documenter-test! fullName: TypeAlias summary: '' @@ -1191,75 +1191,75 @@ syntax: export type TypeAlias = number; - name: DocBaseClass items: - name: DocBaseClass - uid: 'api-documenter-test!DocBaseClass:class' + uid: api-documenter-test!DocBaseClass:class - name: IDocInterface1 - uid: 'api-documenter-test!IDocInterface1:interface' + uid: api-documenter-test!IDocInterface1:interface - name: IDocInterface2 - uid: 'api-documenter-test!IDocInterface2:interface' + uid: api-documenter-test!IDocInterface2:interface - name: DocClass1 items: - name: DocClass1 - uid: 'api-documenter-test!DocClass1:class' + uid: api-documenter-test!DocClass1:class - name: IDocInterface3 - uid: 'api-documenter-test!IDocInterface3:interface' + uid: api-documenter-test!IDocInterface3:interface - name: IDocInterface4 - uid: 'api-documenter-test!IDocInterface4:interface' + uid: api-documenter-test!IDocInterface4:interface - name: Interfaces items: - name: Interface5 items: - name: IDocInterface5 - uid: 'api-documenter-test!IDocInterface5:interface' + uid: api-documenter-test!IDocInterface5:interface - name: Interface6 items: - name: InjectedCustomInterface uid: customUid - name: IDocInterface6 - uid: 'api-documenter-test!IDocInterface6:interface' + uid: api-documenter-test!IDocInterface6:interface - name: References items: - name: InjectedCustomItem uid: customUrl - name: AbstractClass - uid: 'api-documenter-test!AbstractClass:class' + uid: api-documenter-test!AbstractClass:class - name: Constraint - uid: 'api-documenter-test!Constraint:interface' + uid: api-documenter-test!Constraint:interface - name: DecoratorExample - uid: 'api-documenter-test!DecoratorExample:class' + uid: api-documenter-test!DecoratorExample:class - name: DefaultType - uid: 'api-documenter-test!DefaultType:interface' + uid: api-documenter-test!DefaultType:interface - name: DocClassInterfaceMerge (Class) - uid: 'api-documenter-test!DocClassInterfaceMerge:class' + uid: api-documenter-test!DocClassInterfaceMerge:class - name: DocClassInterfaceMerge (Interface) - uid: 'api-documenter-test!DocClassInterfaceMerge:interface' + uid: api-documenter-test!DocClassInterfaceMerge:interface - name: DocEnum - uid: 'api-documenter-test!DocEnum:enum' + uid: api-documenter-test!DocEnum:enum - name: DocEnumNamespaceMerge (Enum) - uid: 'api-documenter-test!DocEnumNamespaceMerge:enum' + uid: api-documenter-test!DocEnumNamespaceMerge:enum - name: DocEnumNamespaceMerge (Namespace) - uid: 'api-documenter-test!DocEnumNamespaceMerge:namespace' + uid: api-documenter-test!DocEnumNamespaceMerge:namespace - name: EcmaSymbols - uid: 'api-documenter-test!EcmaSymbols:namespace' + uid: api-documenter-test!EcmaSymbols:namespace - name: ExampleDuplicateTypeAlias - uid: 'api-documenter-test!ExampleDuplicateTypeAlias:type' + uid: api-documenter-test!ExampleDuplicateTypeAlias:type - name: ExampleTypeAlias - uid: 'api-documenter-test!ExampleTypeAlias:type' + uid: api-documenter-test!ExampleTypeAlias:type - name: ExampleUnionTypeAlias - uid: 'api-documenter-test!ExampleUnionTypeAlias:type' + uid: api-documenter-test!ExampleUnionTypeAlias:type - name: Generic - uid: 'api-documenter-test!Generic:class' + uid: api-documenter-test!Generic:class - name: GenericTypeAlias - uid: 'api-documenter-test!GenericTypeAlias:type' + uid: api-documenter-test!GenericTypeAlias:type - name: IDocInterface7 - uid: 'api-documenter-test!IDocInterface7:interface' + uid: api-documenter-test!IDocInterface7:interface - name: OuterNamespace - uid: 'api-documenter-test!OuterNamespace:namespace' + uid: api-documenter-test!OuterNamespace:namespace - name: OuterNamespace.InnerNamespace - uid: 'api-documenter-test!OuterNamespace.InnerNamespace:namespace' + uid: api-documenter-test!OuterNamespace.InnerNamespace:namespace - name: SystemEvent - uid: 'api-documenter-test!SystemEvent:class' + uid: api-documenter-test!SystemEvent:class - name: TypeAlias - uid: 'api-documenter-test!TypeAlias:type' + uid: api-documenter-test!TypeAlias:type ", } `; From f5b1c9cd209941d14d739b3a127cadb8f0dafb72 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 13:19:52 -0700 Subject: [PATCH 23/26] Rebuild all --- build-tests/api-extractor-test-05/dist/tsdoc-metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tests/api-extractor-test-05/dist/tsdoc-metadata.json b/build-tests/api-extractor-test-05/dist/tsdoc-metadata.json index 5b39d9101b7..d95757eac5e 100644 --- a/build-tests/api-extractor-test-05/dist/tsdoc-metadata.json +++ b/build-tests/api-extractor-test-05/dist/tsdoc-metadata.json @@ -5,7 +5,7 @@ "toolPackages": [ { "packageName": "@microsoft/api-extractor", - "packageVersion": "7.52.11" + "packageVersion": "7.52.13" } ] } From 2a099f3ef3be86f40daf2ca59e4b1b491e51a95c Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 15:07:58 -0700 Subject: [PATCH 24/26] PR feedback --- apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts | 2 +- apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts | 2 +- apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts | 2 +- apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts b/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts index 05a733df473..11ce9f58c98 100644 --- a/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts +++ b/apps/lockfile-explorer-web/src/packlets/lfx-shared/LfxGraph.ts @@ -125,7 +125,7 @@ export class LfxGraphEntry { } export class LfxGraph { - public workspace: IJsonLfxWorkspace; + public readonly workspace: IJsonLfxWorkspace; public readonly entries: LfxGraphEntry[] = []; public constructor(workspace: IJsonLfxWorkspace) { diff --git a/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts b/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts index 37cf193215c..be0d29d7955 100644 --- a/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts +++ b/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts @@ -15,7 +15,7 @@ import * as lfxGraphLoader from '../lfxGraphLoader'; const FIXTURES_FOLDER: string = path.resolve(__dirname, '../../../src/graph/test/fixtures/'); -export async function loadAndSerializeLFxGraph(options: { +export async function loadAndSerializeLFxGraphAsync(options: { workspace: IJsonLfxWorkspace; lockfilePathUnderFixtures: string; }): Promise { diff --git a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts b/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts index 7a01f6dbc36..9e9bc2cf853 100644 --- a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts +++ b/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts @@ -16,7 +16,7 @@ export const workspace: IJsonLfxWorkspace = { describe('lfxGraphLoader 5.4', () => { it('loads a workspace', async () => { - const serializedYaml: string = await graphTestHelpers.loadAndSerializeLFxGraph({ + const serializedYaml: string = await graphTestHelpers.loadAndSerializeLFxGraphAsync({ lockfilePathUnderFixtures: '/website-sample-1/pnpm-lock-rush-5.4.yaml', workspace: workspace }); diff --git a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts b/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts index 3c89d2b616e..0b917147228 100644 --- a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts +++ b/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts @@ -16,7 +16,7 @@ export const workspace: IJsonLfxWorkspace = { describe('lfxGraphLoader 6.0', () => { it('loads a workspace', async () => { - const serializedYaml: string = await graphTestHelpers.loadAndSerializeLFxGraph({ + const serializedYaml: string = await graphTestHelpers.loadAndSerializeLFxGraphAsync({ lockfilePathUnderFixtures: '/website-sample-1/pnpm-lock-rush-6.0.yaml', workspace: workspace }); From 83cd9df9418fd6fcb70a7c1b95830af5c993aca9 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 15:19:29 -0700 Subject: [PATCH 25/26] PR feedback: move the copied packlet to build/lfx-shared (instead of temp/lfx-shared) --- .gitignore | 1 + apps/lockfile-explorer/.npmignore | 2 +- apps/lockfile-explorer/config/heft.json | 6 +++--- .../src/cli/explorer/ExplorerCommandLineParser.ts | 2 +- apps/lockfile-explorer/src/graph/lfxGraphLoader.ts | 2 +- apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts | 2 +- .../src/graph/test/lfxGraphLoader54.test.ts | 2 +- .../src/graph/test/lfxGraphLoader60.test.ts | 2 +- apps/lockfile-explorer/src/graph/test/lockfile.test.ts | 2 +- .../src/graph/test/serializeToJson.test.ts | 2 +- apps/lockfile-explorer/src/graph/test/testLockfile.ts | 2 +- apps/lockfile-explorer/src/state/index.ts | 2 +- 12 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index a7871370954..18091f23d4e 100644 --- a/.gitignore +++ b/.gitignore @@ -107,6 +107,7 @@ common/autoinstallers/*/.npmrc *.lock # Common toolchain intermediate files +build/ temp/ lib/ lib-amd/ diff --git a/apps/lockfile-explorer/.npmignore b/apps/lockfile-explorer/.npmignore index 97a5f164d30..538016c27d7 100644 --- a/apps/lockfile-explorer/.npmignore +++ b/apps/lockfile-explorer/.npmignore @@ -32,4 +32,4 @@ # --------------------------------------------------------------------------- # heft.json copies this folder from lockfile-explorer-web: -!/temp/lfx-shared/** +!/build/lfx-shared/** diff --git a/apps/lockfile-explorer/config/heft.json b/apps/lockfile-explorer/config/heft.json index 7150e66582b..6664d95480c 100644 --- a/apps/lockfile-explorer/config/heft.json +++ b/apps/lockfile-explorer/config/heft.json @@ -14,7 +14,7 @@ "phasesByName": { "build": { - "cleanFiles": [{ "includeGlobs": ["temp/lfx-shared"] }], + "cleanFiles": [{ "includeGlobs": ["build"] }], "tasksByName": { "copy-app-bundle": { @@ -46,12 +46,12 @@ "copyOperations": [ { "sourcePath": "node_modules/@rushstack/lockfile-explorer-web/lib/packlets/lfx-shared", - "destinationFolders": ["temp/lfx-shared"], + "destinationFolders": ["build/lfx-shared"], "includeGlobs": ["*.d.ts"] }, { "sourcePath": "node_modules/@rushstack/lockfile-explorer-web/lib-commonjs/packlets/lfx-shared", - "destinationFolders": ["temp/lfx-shared"], + "destinationFolders": ["build/lfx-shared"], "includeGlobs": ["*.js", "*.map"] } ] diff --git a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts index e52fe440db2..cc40653e354 100644 --- a/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts +++ b/apps/lockfile-explorer/src/cli/explorer/ExplorerCommandLineParser.ts @@ -21,7 +21,7 @@ import { lfxGraphSerializer, type IAppContext, type IJsonLfxGraph -} from '../../../temp/lfx-shared'; +} from '../../../build/lfx-shared'; import type { IAppState } from '../../state'; import { init } from '../../utils/init'; diff --git a/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts b/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts index 5ab04345d10..64ed34f997a 100644 --- a/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts +++ b/apps/lockfile-explorer/src/graph/lfxGraphLoader.ts @@ -12,7 +12,7 @@ import { LfxDependencyKind, LfxGraphDependency, type IJsonLfxWorkspace -} from '../../temp/lfx-shared'; +} from '../../build/lfx-shared'; import { convertLockfileV6DepPathToV5DepPath } from '../utils/shrinkwrap'; diff --git a/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts b/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts index be0d29d7955..52583dec6c2 100644 --- a/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts +++ b/apps/lockfile-explorer/src/graph/test/graphTestHelpers.ts @@ -9,7 +9,7 @@ import { type IJsonLfxWorkspace, lfxGraphSerializer, type LfxGraph -} from '../../../temp/lfx-shared'; +} from '../../../build/lfx-shared'; import * as lfxGraphLoader from '../lfxGraphLoader'; diff --git a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts b/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts index 9e9bc2cf853..3a890ff3188 100644 --- a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts +++ b/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { IJsonLfxWorkspace } from '../../../temp/lfx-shared'; +import type { IJsonLfxWorkspace } from '../../../build/lfx-shared'; import * as graphTestHelpers from './graphTestHelpers'; diff --git a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts b/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts index 0b917147228..e41eee16bb4 100644 --- a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts +++ b/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { IJsonLfxWorkspace } from '../../../temp/lfx-shared'; +import type { IJsonLfxWorkspace } from '../../../build/lfx-shared'; import * as graphTestHelpers from './graphTestHelpers'; diff --git a/apps/lockfile-explorer/src/graph/test/lockfile.test.ts b/apps/lockfile-explorer/src/graph/test/lockfile.test.ts index 01d7acdbb23..8b89f8de00d 100644 --- a/apps/lockfile-explorer/src/graph/test/lockfile.test.ts +++ b/apps/lockfile-explorer/src/graph/test/lockfile.test.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { LfxGraphEntry } from '../../../temp/lfx-shared'; +import type { LfxGraphEntry } from '../../../build/lfx-shared'; import { TEST_WORKSPACE, TEST_LOCKFILE } from './testLockfile'; import * as lfxGraphLoader from '../lfxGraphLoader'; diff --git a/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts b/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts index d298903d61f..977cae423be 100644 --- a/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts +++ b/apps/lockfile-explorer/src/graph/test/serializeToJson.test.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import { lfxGraphSerializer, type LfxGraph } from '../../../temp/lfx-shared'; +import { lfxGraphSerializer, type LfxGraph } from '../../../build/lfx-shared'; import * as lfxGraphLoader from '../lfxGraphLoader'; import { TEST_WORKSPACE, TEST_LOCKFILE } from './testLockfile'; diff --git a/apps/lockfile-explorer/src/graph/test/testLockfile.ts b/apps/lockfile-explorer/src/graph/test/testLockfile.ts index 3f8a7bfca06..0ba13018fbc 100644 --- a/apps/lockfile-explorer/src/graph/test/testLockfile.ts +++ b/apps/lockfile-explorer/src/graph/test/testLockfile.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { IJsonLfxWorkspace } from '../../../temp/lfx-shared'; +import type { IJsonLfxWorkspace } from '../../../build/lfx-shared'; export const TEST_WORKSPACE: IJsonLfxWorkspace = { workspaceRootFolder: '/test', diff --git a/apps/lockfile-explorer/src/state/index.ts b/apps/lockfile-explorer/src/state/index.ts index 529211b045d..481d2812655 100644 --- a/apps/lockfile-explorer/src/state/index.ts +++ b/apps/lockfile-explorer/src/state/index.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import type { IJsonLfxWorkspace } from '../../temp/lfx-shared'; +import type { IJsonLfxWorkspace } from '../../build/lfx-shared'; export interface IAppState { lockfileExplorerProjectRoot: string; From ea92f639372a04d15f8cd5a46d7672d28506afd9 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Sun, 14 Sep 2025 15:29:52 -0700 Subject: [PATCH 26/26] Improve test naming convention to better accommodate future test scenarios --- ....ts.snap => lfxGraph-website-sample-1-v5.4.test.ts.snap} | 2 +- ....ts.snap => lfxGraph-website-sample-1-v6.0.test.ts.snap} | 2 +- .../{pnpm-lock-rush-5.4.yaml => pnpm-lock-v5.4-rush.yaml} | 0 .../{pnpm-lock-rush-6.0.yaml => pnpm-lock-v6.0-rush.yaml} | 0 .../{pnpm-lock-pnpm-9.0.yaml => pnpm-lock-v9.0-pnpm.yaml} | 0 .../test/fixtures/website-sample-1/website-sample-1.md | 6 +++--- ...der54.test.ts => lfxGraph-website-sample-1-v5.4.test.ts} | 4 ++-- ...der60.test.ts => lfxGraph-website-sample-1-v6.0.test.ts} | 4 ++-- 8 files changed, 9 insertions(+), 9 deletions(-) rename apps/lockfile-explorer/src/graph/test/__snapshots__/{lfxGraphLoader54.test.ts.snap => lfxGraph-website-sample-1-v5.4.test.ts.snap} (99%) rename apps/lockfile-explorer/src/graph/test/__snapshots__/{lfxGraphLoader60.test.ts.snap => lfxGraph-website-sample-1-v6.0.test.ts.snap} (99%) rename apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/{pnpm-lock-rush-5.4.yaml => pnpm-lock-v5.4-rush.yaml} (100%) rename apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/{pnpm-lock-rush-6.0.yaml => pnpm-lock-v6.0-rush.yaml} (100%) rename apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/{pnpm-lock-pnpm-9.0.yaml => pnpm-lock-v9.0-pnpm.yaml} (100%) rename apps/lockfile-explorer/src/graph/test/{lfxGraphLoader54.test.ts => lfxGraph-website-sample-1-v5.4.test.ts} (84%) rename apps/lockfile-explorer/src/graph/test/{lfxGraphLoader60.test.ts => lfxGraph-website-sample-1-v6.0.test.ts} (84%) diff --git a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraph-website-sample-1-v5.4.test.ts.snap similarity index 99% rename from apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap rename to apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraph-website-sample-1-v5.4.test.ts.snap index 9bd8703a16b..f37d9721956 100644 --- a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader54.test.ts.snap +++ b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraph-website-sample-1-v5.4.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`lfxGraphLoader 5.4 loads a workspace 1`] = ` +exports[`lfxGraph-website-sample-1-v5.4 loads a workspace 1`] = ` "entries: - dependencies: [] displayText: '' diff --git a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraph-website-sample-1-v6.0.test.ts.snap similarity index 99% rename from apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap rename to apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraph-website-sample-1-v6.0.test.ts.snap index abd0957fda8..a24bbbb326c 100644 --- a/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraphLoader60.test.ts.snap +++ b/apps/lockfile-explorer/src/graph/test/__snapshots__/lfxGraph-website-sample-1-v6.0.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`lfxGraphLoader 6.0 loads a workspace 1`] = ` +exports[`lfxGraph-website-sample-1-v6.0 loads a workspace 1`] = ` "entries: - dependencies: [] displayText: '' diff --git a/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-rush-5.4.yaml b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-v5.4-rush.yaml similarity index 100% rename from apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-rush-5.4.yaml rename to apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-v5.4-rush.yaml diff --git a/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-rush-6.0.yaml b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-v6.0-rush.yaml similarity index 100% rename from apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-rush-6.0.yaml rename to apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-v6.0-rush.yaml diff --git a/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-pnpm-9.0.yaml b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-v9.0-pnpm.yaml similarity index 100% rename from apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-pnpm-9.0.yaml rename to apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/pnpm-lock-v9.0-pnpm.yaml diff --git a/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/website-sample-1.md b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/website-sample-1.md index 3370009c089..62e16149c48 100644 --- a/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/website-sample-1.md +++ b/apps/lockfile-explorer/src/graph/test/fixtures/website-sample-1/website-sample-1.md @@ -7,6 +7,6 @@ https://github.com/microsoft/lockfile-explorer-demos/tree/demo/sample-1 There are three versions of the lockfile: -- `pnpm-lock-rush-5.4.yaml`: The old 5.4 YAML format generated using PNPM 7.16.1 and Rush 5.83.3 from [`ee8a06e`](https://github.com/microsoft/lockfile-explorer-demos/commit/ee8a06e71b63feb806f240de01e57d42854d02af). -- `pnpm-lock-rush-6.0.yaml`: The 6.0 YAML format generated using PNPM 8.15.9 and Rush 5.158.1 from [`8c3ad3c`](https://github.com/microsoft/lockfile-explorer-demos/commit/8c3ad3cad68a921baa4eb6d264d293e928a962f5) -- `pnpm-lock-pnpm-9.0.yaml`: For comparison, a lockfile generated using a PNPM 9.15.9 with a plain PNPM workspace (without Rush). Rush doesn't support this format yet. +- `pnpm-lock-v5.4-rush.yaml`: The old 5.4 YAML format generated using PNPM 7.16.1 and Rush 5.83.3 from [`ee8a06e`](https://github.com/microsoft/lockfile-explorer-demos/commit/ee8a06e71b63feb806f240de01e57d42854d02af). +- `pnpm-lock-v6.0-rush.yaml`: The 6.0 YAML format generated using PNPM 8.15.9 and Rush 5.158.1 from [`8c3ad3c`](https://github.com/microsoft/lockfile-explorer-demos/commit/8c3ad3cad68a921baa4eb6d264d293e928a962f5) +- `pnpm-lock-v9.0-pnpm.yaml`: For comparison, a lockfile generated using a PNPM 9.15.9 with a plain PNPM workspace (without Rush). Rush doesn't support this format yet. diff --git a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts b/apps/lockfile-explorer/src/graph/test/lfxGraph-website-sample-1-v5.4.test.ts similarity index 84% rename from apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts rename to apps/lockfile-explorer/src/graph/test/lfxGraph-website-sample-1-v5.4.test.ts index 3a890ff3188..3ca5deda4b8 100644 --- a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader54.test.ts +++ b/apps/lockfile-explorer/src/graph/test/lfxGraph-website-sample-1-v5.4.test.ts @@ -14,10 +14,10 @@ export const workspace: IJsonLfxWorkspace = { } }; -describe('lfxGraphLoader 5.4', () => { +describe('lfxGraph-website-sample-1-v5.4', () => { it('loads a workspace', async () => { const serializedYaml: string = await graphTestHelpers.loadAndSerializeLFxGraphAsync({ - lockfilePathUnderFixtures: '/website-sample-1/pnpm-lock-rush-5.4.yaml', + lockfilePathUnderFixtures: '/website-sample-1/pnpm-lock-v5.4-rush.yaml', workspace: workspace }); expect(serializedYaml).toMatchSnapshot(); diff --git a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts b/apps/lockfile-explorer/src/graph/test/lfxGraph-website-sample-1-v6.0.test.ts similarity index 84% rename from apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts rename to apps/lockfile-explorer/src/graph/test/lfxGraph-website-sample-1-v6.0.test.ts index e41eee16bb4..dd381d93a96 100644 --- a/apps/lockfile-explorer/src/graph/test/lfxGraphLoader60.test.ts +++ b/apps/lockfile-explorer/src/graph/test/lfxGraph-website-sample-1-v6.0.test.ts @@ -14,10 +14,10 @@ export const workspace: IJsonLfxWorkspace = { } }; -describe('lfxGraphLoader 6.0', () => { +describe('lfxGraph-website-sample-1-v6.0', () => { it('loads a workspace', async () => { const serializedYaml: string = await graphTestHelpers.loadAndSerializeLFxGraphAsync({ - lockfilePathUnderFixtures: '/website-sample-1/pnpm-lock-rush-6.0.yaml', + lockfilePathUnderFixtures: '/website-sample-1/pnpm-lock-v6.0-rush.yaml', workspace: workspace }); expect(serializedYaml).toMatchSnapshot();