Skip to content

Commit c2bc72d

Browse files
committed
feat: remove dependency on git repos
1 parent 438ebbf commit c2bc72d

File tree

6 files changed

+72
-118
lines changed

6 files changed

+72
-118
lines changed

README.md

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,27 @@
22

33
[![NPM](https://img.shields.io/npm/v/apex-code-coverage-transformer.svg?label=apex-code-coverage-transformer)](https://www.npmjs.com/package/apex-code-coverage-transformer) [![Downloads/week](https://img.shields.io/npm/dw/apex-code-coverage-transformer.svg)](https://npmjs.org/package/apex-code-coverage-transformer) [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/LICENSE.md)
44

5+
<!-- TABLE OF CONTENTS -->
6+
<details>
7+
<summary>Table of Contents</summary>
8+
9+
- [Install](#install)
10+
- [Command](#command)
11+
- [`sf acc-transformer transform`](#sf-acc-transformer-transform)
12+
- [Hook](#hook)
13+
- [Errors and Warnings](#errors-and-warnings)
14+
- [Example](#example)
15+
- [Issues](#issues)
16+
- [License](#license)
17+
</details>
18+
519
The `apex-code-coverage-transformer` is a Salesforce CLI plugin to transform the Apex Code Coverage JSON files created during deployments and test runs into the Generic Test Coverage Format (XML). This format is accepted by static code analysis tools like SonarQube.
620

721
This plugin supports code coverage metrics created for Apex Classes and Apex Triggers. This also supports multiple package directories as listed in your project's `sfdx-project.json` configuration, assuming unique file-names are used in your package directories.
822

9-
This plugin is intended for users who deploy their Apex codebase from a git-based repository and use SonarQube for code quality. This plugin will work if you run local tests or run all tests in an org, including tests that originate from installed managed and unlocked packages. SonarQube relies on file-paths to map code coverage to the files in their file explorer interface. Since files from managed and unlocked packages aren't retrieved into git-based Salesforce repositories, these files cannot be included in your SonarQube scans. If your Apex code coverage JSON output includes managed/unlocked package files, they will not be added to the coverage XML created by this plugin. A warning will be printed for each file not found in a package directory in your git repository. See [Errors and Warnings](https://github.com/mcarvin8/apex-code-coverage-transformer?tab=readme-ov-file#errors-and-warnings) for more information.
23+
This plugin is intended for users who deploy their Apex codebase from a Salesforce DX repository and use SonarQube for code quality. This plugin is intended to work for any Salesforce DX repository with a `sfdx-project.json` file, not just git-based repositories. This plugin will work if you run local tests or run all tests in an org, including tests that originate from installed managed and unlocked packages.
24+
25+
SonarQube relies on file-paths to map code coverage to the files in their file explorer interface. Since files from managed and unlocked packages aren't retrieved into Salesforce DX repositories, these files cannot be included in your SonarQube scans. If your Apex code coverage JSON output includes managed/unlocked package files, they will not be added to the coverage XML created by this plugin. A warning will be printed for each file not found in a package directory in your repository. See [Errors and Warnings](https://github.com/mcarvin8/apex-code-coverage-transformer?tab=readme-ov-file#errors-and-warnings) for more information.
1026

1127
To create the code coverage JSON during a Salesforce CLI deployment/validation, append `--coverage-formatters json --results-dir "coverage"` to the `sf project deploy` command. This will create a coverage JSON in this relative path - `coverage/coverage/coverage.json`.
1228

@@ -21,7 +37,7 @@ sf apex run test --code-coverage --result-format json --output-dir "coverage"
2137
sf apex get test --test-run-id <test run id> --code-coverage --result-format json --output-dir "coverage"
2238
```
2339

24-
The code coverage JSONs created by the Salesforce CLI aren't accepted by SonarQube automatically for git-based Salesforce repositories and needs to be converted using this plugin.
40+
The code coverage JSONs created by the Salesforce CLI aren't accepted by SonarQube automatically for Salesforce DX repositories and needs to be converted using this plugin.
2541

2642
**Disclaimer**: Due to existing bugs with how the Salesforce CLI reports covered lines during deployments (see [5511](https://github.com/forcedotcom/salesforcedx-vscode/issues/5511) and [1568](https://github.com/forcedotcom/cli/issues/1568)), to add support for covered lines in this plugin for deployment coverage files, I had to add a function to re-number out-of-range covered lines the CLI may report (ex: line 100 in a 98-line Apex Class is reported back as covered by the Salesforce CLI deploy command). Salesforce's coverage result may also include extra lines as covered (ex: 120 lines are included in the coverage report for a 100 line file), so the coverage percentage may vary based on how many lines the API returns in the coverage report. Once Salesforce fixes the API to correctly return covered lines in the deploy command, this function will be removed.
2743

@@ -37,7 +53,7 @@ The `apex-code-coverage-transformer` has 1 command:
3753

3854
- `sf acc-transformer transform`
3955

40-
This command needs to be ran somewhere inside your Salesforce DX git repository, whether in the root folder (recommended) or in a subfolder. This plugin will determine the root folder of this repository and read the `sfdx-project.json` file in the root folder. All package directories listed in the `sfdx-project.json` file will be processed when running this plugin.
56+
This command needs to be ran somewhere inside your Salesforce DX repository, whether in the root folder (recommended) or in a subfolder. This plugin will determine the root folder of this repository and read the `sfdx-project.json` file in the root folder. All package directories listed in the `sfdx-project.json` file will be processed when running this plugin.
4157

4258
## `sf acc-transformer transform`
4359

@@ -110,7 +126,7 @@ Error (1): The provided JSON does not match a known coverage data format from th
110126
If the `sfdx-project.json` file was not found in your repository's root folder, the plugin will fail with:
111127

112128
```
113-
Error (1): Salesforce DX Config File does not exist in this path: {filePath}
129+
Error (1): sfdx-project.json not found in any parent directory.
114130
```
115131

116132
Any ENOENT failures indicate that the plugin had issues finding one of the package directories in the `sfdx-project.json` file:
@@ -194,3 +210,11 @@ This [code coverage JSON file](https://raw.githubusercontent.com/mcarvin8/apex-c
194210
</file>
195211
</coverage>
196212
```
213+
214+
## Issues
215+
216+
If you encounter any issues, please create an issue in the repository's [issue tracker](https://github.com/mcarvin8/apex-code-coverage-transformer/issues). Please also create issues to suggest any new features.
217+
218+
## License
219+
220+
This project is licensed under the MIT license. Please see the [LICENSE](https://raw.githubusercontent.com/mcarvin8/apex-code-coverage-transformer/main/LICENSE.md) file for details.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"@oclif/core": "^3.18.1",
77
"@salesforce/core": "^6.4.7",
88
"@salesforce/sf-plugins-core": "^7.1.3",
9-
"isomorphic-git": "^1.27.1",
109
"xmlbuilder2": "^3.1.1"
1110
},
1211
"devDependencies": {
@@ -29,7 +28,8 @@
2928
"/lib",
3029
"/messages",
3130
"/oclif.manifest.json",
32-
"/oclif.lock"
31+
"/oclif.lock",
32+
"/CHANGELOG.md"
3333
],
3434
"keywords": [
3535
"force",

src/helpers/getPackageDirectories.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
'use strict';
2-
/* eslint-disable no-await-in-loop */
32

4-
import { existsSync } from 'node:fs';
53
import { readFile } from 'node:fs/promises';
64
import { resolve } from 'node:path';
75

86
import { SfdxProject } from './types.js';
97
import { getRepoRoot } from './getRepoRoot.js';
108

119
export async function getPackageDirectories(): Promise<{ repoRoot: string; packageDirectories: string[] }> {
12-
const repoRoot = await getRepoRoot();
13-
const dxConfigPath = resolve(repoRoot, 'sfdx-project.json');
14-
if (!existsSync(dxConfigPath)) {
15-
throw Error(`Salesforce DX Config File does not exist in this path: ${dxConfigPath}`);
10+
const { repoRoot, dxConfigFilePath } = await getRepoRoot();
11+
12+
if (!repoRoot || !dxConfigFilePath) {
13+
throw new Error('Failed to retrieve repository root or sfdx-project.json path.');
1614
}
1715

18-
const sfdxProjectRaw: string = await readFile(dxConfigPath, 'utf-8');
16+
const sfdxProjectRaw: string = await readFile(dxConfigFilePath, 'utf-8');
1917
const sfdxProject: SfdxProject = JSON.parse(sfdxProjectRaw) as SfdxProject;
2018
const packageDirectories = sfdxProject.packageDirectories.map((directory) => resolve(repoRoot, directory.path));
2119
return { repoRoot, packageDirectories };

src/helpers/getRepoRoot.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,32 @@
11
'use strict';
2-
import { promises as fsPromises, readFile, stat, readdir } from 'node:fs';
3-
import git from 'isomorphic-git';
2+
/* eslint-disable no-await-in-loop */
3+
import { access } from 'node:fs/promises';
4+
import { join, dirname } from 'node:path';
45

5-
export async function getRepoRoot(): Promise<string> {
6-
const fs = { promises: fsPromises, readFile, stat, readdir };
7-
const repoRoot = await git.findRoot({
8-
fs,
9-
filepath: process.cwd(),
10-
});
11-
return repoRoot;
6+
export async function getRepoRoot(): Promise<{ repoRoot: string | undefined; dxConfigFilePath: string | undefined }> {
7+
let currentDir = process.cwd();
8+
let found = false;
9+
let dxConfigFilePath: string | undefined;
10+
let repoRoot: string | undefined;
11+
12+
do {
13+
const filePath = join(currentDir, 'sfdx-project.json');
14+
15+
try {
16+
// Check if sfdx-project.json exists in the current directory
17+
await access(filePath);
18+
dxConfigFilePath = filePath;
19+
repoRoot = currentDir;
20+
found = true;
21+
} catch {
22+
// If file not found, move up one directory level
23+
const parentDir = dirname(currentDir);
24+
if (currentDir === parentDir) {
25+
// Reached the root without finding the file, throw an error
26+
throw new Error('sfdx-project.json not found in any parent directory.');
27+
}
28+
currentDir = parentDir;
29+
}
30+
} while (!found);
31+
return { repoRoot, dxConfigFilePath };
1232
}

src/hooks/postrun.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ export const postrun: Hook<'postrun'> = async function (options) {
2424
return;
2525
}
2626
let configFile: ConfigFile;
27-
const repoRoot = await getRepoRoot();
27+
const { repoRoot } = await getRepoRoot();
28+
if (!repoRoot) {
29+
return;
30+
}
2831
const configPath = resolve(repoRoot, '.apexcodecovtransformer.config.json');
2932

3033
try {

yarn.lock

Lines changed: 4 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -3180,11 +3180,6 @@ astral-regex@^2.0.0:
31803180
resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz"
31813181
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
31823182

3183-
async-lock@^1.4.1:
3184-
version "1.4.1"
3185-
resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.4.1.tgz#56b8718915a9b68b10fce2f2a9a3dddf765ef53f"
3186-
integrity sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==
3187-
31883183
async-retry@^1.3.3:
31893184
version "1.3.3"
31903185
resolved "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz"
@@ -3603,11 +3598,6 @@ ci-info@^3.8.0:
36033598
resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz"
36043599
integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==
36053600

3606-
clean-git-ref@^2.0.1:
3607-
version "2.0.1"
3608-
resolved "https://registry.yarnpkg.com/clean-git-ref/-/clean-git-ref-2.0.1.tgz#dcc0ca093b90e527e67adb5a5e55b1af6816dcd9"
3609-
integrity sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==
3610-
36113601
clean-regexp@^1.0.0:
36123602
version "1.0.0"
36133603
resolved "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz"
@@ -3960,11 +3950,6 @@ cosmiconfig@^8.0.0, cosmiconfig@^8.3.6:
39603950
parse-json "^5.2.0"
39613951
path-type "^4.0.0"
39623952

3963-
crc-32@^1.2.0:
3964-
version "1.2.2"
3965-
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff"
3966-
integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==
3967-
39683953
create-require@^1.1.0:
39693954
version "1.1.1"
39703955
resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz"
@@ -4149,11 +4134,6 @@ dezalgo@^1.0.0:
41494134
asap "^2.0.0"
41504135
wrappy "1"
41514136

4152-
4153-
version "0.0.3"
4154-
resolved "https://registry.yarnpkg.com/diff3/-/diff3-0.0.3.tgz#d4e5c3a4cdf4e5fe1211ab42e693fcb4321580fc"
4155-
integrity sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==
4156-
41574137
[email protected], diff@^5.0.0:
41584138
version "5.0.0"
41594139
resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz"
@@ -5889,23 +5869,6 @@ isexe@^2.0.0:
58895869
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
58905870
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
58915871

5892-
isomorphic-git@^1.27.1:
5893-
version "1.27.1"
5894-
resolved "https://registry.yarnpkg.com/isomorphic-git/-/isomorphic-git-1.27.1.tgz#a2752fce23a09f04baa590c41cfaf61e973405b3"
5895-
integrity sha512-X32ph5zIWfT75QAqW2l3JCIqnx9/GWd17bRRehmn3qmWc34OYbSXY6Cxv0o9bIIY+CWugoN4nQFHNA+2uYf2nA==
5896-
dependencies:
5897-
async-lock "^1.4.1"
5898-
clean-git-ref "^2.0.1"
5899-
crc-32 "^1.2.0"
5900-
diff3 "0.0.3"
5901-
ignore "^5.1.4"
5902-
minimisted "^2.0.0"
5903-
pako "^1.0.10"
5904-
pify "^4.0.1"
5905-
readable-stream "^3.4.0"
5906-
sha.js "^2.4.9"
5907-
simple-get "^4.0.1"
5908-
59095872
istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0:
59105873
version "3.2.0"
59115874
resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz"
@@ -6721,13 +6684,6 @@ minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6:
67216684
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
67226685
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
67236686

6724-
minimisted@^2.0.0:
6725-
version "2.0.1"
6726-
resolved "https://registry.yarnpkg.com/minimisted/-/minimisted-2.0.1.tgz#d059fb905beecf0774bc3b308468699709805cb1"
6727-
integrity sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==
6728-
dependencies:
6729-
minimist "^1.2.5"
6730-
67316687
minipass-collect@^1.0.2:
67326688
version "1.0.2"
67336689
resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz"
@@ -7543,7 +7499,7 @@ pacote@^15.2.0:
75437499
ssri "^10.0.0"
75447500
tar "^6.1.11"
75457501

7546-
pako@^1.0.10, pako@~1.0.2:
7502+
pako@~1.0.2:
75477503
version "1.0.11"
75487504
resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz"
75497505
integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
@@ -8391,14 +8347,6 @@ setimmediate@^1.0.5:
83918347
resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz"
83928348
integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==
83938349

8394-
sha.js@^2.4.9:
8395-
version "2.4.11"
8396-
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
8397-
integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==
8398-
dependencies:
8399-
inherits "^2.0.1"
8400-
safe-buffer "^5.0.1"
8401-
84028350
shebang-command@^2.0.0:
84038351
version "2.0.0"
84048352
resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
@@ -8466,20 +8414,6 @@ sigstore@^1.3.0:
84668414
make-fetch-happen "^11.0.1"
84678415
tuf-js "^1.1.3"
84688416

8469-
simple-concat@^1.0.0:
8470-
version "1.0.1"
8471-
resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
8472-
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
8473-
8474-
simple-get@^4.0.1:
8475-
version "4.0.1"
8476-
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543"
8477-
integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==
8478-
dependencies:
8479-
decompress-response "^6.0.0"
8480-
once "^1.3.1"
8481-
simple-concat "^1.0.0"
8482-
84838417
simple-swizzle@^0.2.2:
84848418
version "0.2.2"
84858419
resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz"
@@ -8684,16 +8618,7 @@ ssri@^9.0.0:
86848618
dependencies:
86858619
minipass "^3.1.1"
86868620

8687-
"string-width-cjs@npm:string-width@^4.2.0":
8688-
version "4.2.3"
8689-
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
8690-
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
8691-
dependencies:
8692-
emoji-regex "^8.0.0"
8693-
is-fullwidth-code-point "^3.0.0"
8694-
strip-ansi "^6.0.1"
8695-
8696-
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
8621+
"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
86978622
version "4.2.3"
86988623
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
86998624
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -8752,14 +8677,7 @@ string_decoder@^1.3.0:
87528677
dependencies:
87538678
safe-buffer "~5.2.0"
87548679

8755-
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
8756-
version "6.0.1"
8757-
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
8758-
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
8759-
dependencies:
8760-
ansi-regex "^5.0.1"
8761-
8762-
[email protected], strip-ansi@^6.0.0, strip-ansi@^6.0.1:
8680+
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", [email protected], strip-ansi@^6.0.0, strip-ansi@^6.0.1:
87638681
version "6.0.1"
87648682
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
87658683
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -9490,7 +9408,7 @@ [email protected]:
94909408
resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz"
94919409
integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==
94929410

9493-
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
9411+
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
94949412
version "7.0.0"
94959413
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
94969414
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -9508,15 +9426,6 @@ wrap-ansi@^6.2.0:
95089426
string-width "^4.1.0"
95099427
strip-ansi "^6.0.0"
95109428

9511-
wrap-ansi@^7.0.0:
9512-
version "7.0.0"
9513-
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
9514-
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
9515-
dependencies:
9516-
ansi-styles "^4.0.0"
9517-
string-width "^4.1.0"
9518-
strip-ansi "^6.0.0"
9519-
95209429
wrap-ansi@^8.1.0:
95219430
version "8.1.0"
95229431
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz"

0 commit comments

Comments
 (0)