Initial commit

This commit is contained in:
yuding
2025-12-03 12:00:46 +08:00
commit 5763b764a3
5365 changed files with 1483113 additions and 0 deletions

29
node_modules/@rushstack/problem-matcher/CHANGELOG.json generated vendored Normal file
View File

@@ -0,0 +1,29 @@
{
"name": "@rushstack/problem-matcher",
"entries": [
{
"version": "0.1.1",
"tag": "@rushstack/problem-matcher_v0.1.1",
"date": "Tue, 30 Sep 2025 23:57:45 GMT",
"comments": {
"patch": [
{
"comment": "Fix multi-line looping problem matcher message parsing"
}
]
}
},
{
"version": "0.1.0",
"tag": "@rushstack/problem-matcher_v0.1.0",
"date": "Tue, 30 Sep 2025 20:33:51 GMT",
"comments": {
"minor": [
{
"comment": "Add @rushstack/problem-matcher library to parse and use VS Code style problem matchers"
}
]
}
}
]
}

18
node_modules/@rushstack/problem-matcher/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,18 @@
# Change Log - @rushstack/problem-matcher
This log was last generated on Tue, 30 Sep 2025 23:57:45 GMT and should not be manually modified.
## 0.1.1
Tue, 30 Sep 2025 23:57:45 GMT
### Patches
- Fix multi-line looping problem matcher message parsing
## 0.1.0
Tue, 30 Sep 2025 20:33:51 GMT
### Minor changes
- Add @rushstack/problem-matcher library to parse and use VS Code style problem matchers

24
node_modules/@rushstack/problem-matcher/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,24 @@
@rushstack/problem-matcher
Copyright (c) Microsoft Corporation. All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

12
node_modules/@rushstack/problem-matcher/README.md generated vendored Normal file
View File

@@ -0,0 +1,12 @@
# @rushstack/problem-matcher
Parse VS Code style problem matcher definitions and extract structured problem reports (errors, warnings, info) from strings.
## Links
- [CHANGELOG.md](
https://github.com/microsoft/rushstack/blob/main/libraries/problem-matcher/CHANGELOG.md) - Find
out what's new in the latest version
- [API Reference](https://api.rushstack.io/pages/problem-matcher/)
`@rushstack/problem-matcher` is part of the [Rush Stack](https://rushstack.io/) family of projects.

View File

@@ -0,0 +1,121 @@
/**
* Parse VS Code style problem matcher definitions and use them to extract
* structured problem reports from strings.
*
* @packageDocumentation
*/
/**
* Represents a problem (generally an error or warning) detected in the console output.
*
* @public
*/
export declare interface IProblem {
/** The name of the matcher that detected the problem. */
readonly matcherName: string;
/** Parsed message from the problem matcher */
readonly message: string;
/** Parsed severity level from the problem matcher */
readonly severity?: ProblemSeverity;
/** Parsed file path from the problem matcher */
readonly file?: string;
/** Parsed line number from the problem matcher */
readonly line?: number;
/** Parsed column number from the problem matcher */
readonly column?: number;
/** Parsed ending line number from the problem matcher */
readonly endLine?: number;
/** Parsed ending column number from the problem matcher */
readonly endColumn?: number;
/** Parsed error or warning code from the problem matcher */
readonly code?: string;
}
/**
* A problem matcher processes one line at a time and returns an {@link IProblem} if a match occurs.
*
* @remarks
* Multi-line matchers may keep internal state and emit on a later line; they can also optionally
* implement `flush()` to emit any buffered problems when the stream closes.
*
* @public
*/
export declare interface IProblemMatcher {
/** A friendly (and stable) name identifying the matcher. */
readonly name: string;
/**
* Attempt to match a problem for the provided line of console output.
*
* @param line - A single line of text, always terminated with a newline character (\\n).
* @returns A problem if recognized, otherwise `false`.
*/
exec(line: string): IProblem | false;
/**
* Flush any buffered state and return additional problems. Optional.
*/
flush?(): IProblem[];
}
/**
* Minimal VS Code problem matcher definition.
*
* @public
*/
export declare interface IProblemMatcherJson {
/** A friendly (and stable) name identifying the matcher. */
name: string;
/** An optional default severity to apply if the pattern does not capture one. */
severity?: ProblemSeverity;
/** A single pattern or an array of patterns to match. */
pattern: IProblemPattern | IProblemPattern[];
}
/**
* VS Code style problem matcher pattern definition.
*
* @remarks
* This mirrors the shape used in VS Code's `problemMatcher.pattern` entries.
* Reference: https://code.visualstudio.com/docs/editor/tasks#_defining-a-problem-matcher
*
* @public
*/
export declare interface IProblemPattern {
/** A regular expression used to match the problem. */
regexp: string;
/** Match index for the file path. */
file?: number;
/** Match index for the location. */
location?: number;
/** Match index for the starting line number. */
line?: number;
/** Match index for the starting column number. */
column?: number;
/** Match index for the ending line number. */
endLine?: number;
/** Match index for the ending column number. */
endColumn?: number;
/** Match index for the severity level. */
severity?: number;
/** Match index for the problem code. */
code?: number;
/** Match index for the problem message. */
message: number;
/** If true, the last pattern in a multi-line matcher may repeat (loop) producing multiple problems */
loop?: boolean;
}
/**
* Parse VS Code problem matcher JSON definitions into {@link IProblemMatcher} objects.
*
* @public
*/
export declare function parseProblemMatchersJson(problemMatchers: IProblemMatcherJson[]): IProblemMatcher[];
/**
* Represents the severity level of a problem.
*
* @public
*/
export declare type ProblemSeverity = 'error' | 'warning' | 'info';
export { }

View File

@@ -0,0 +1,11 @@
// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
// It should be published with your NPM package. It should not be tracked by Git.
{
"tsdocVersion": "0.12",
"toolPackages": [
{
"packageName": "@microsoft/api-extractor",
"packageVersion": "7.52.11"
}
]
}

View File

@@ -0,0 +1,108 @@
/**
* Represents the severity level of a problem.
*
* @public
*/
export type ProblemSeverity = 'error' | 'warning' | 'info';
/**
* Represents a problem (generally an error or warning) detected in the console output.
*
* @public
*/
export interface IProblem {
/** The name of the matcher that detected the problem. */
readonly matcherName: string;
/** Parsed message from the problem matcher */
readonly message: string;
/** Parsed severity level from the problem matcher */
readonly severity?: ProblemSeverity;
/** Parsed file path from the problem matcher */
readonly file?: string;
/** Parsed line number from the problem matcher */
readonly line?: number;
/** Parsed column number from the problem matcher */
readonly column?: number;
/** Parsed ending line number from the problem matcher */
readonly endLine?: number;
/** Parsed ending column number from the problem matcher */
readonly endColumn?: number;
/** Parsed error or warning code from the problem matcher */
readonly code?: string;
}
/**
* A problem matcher processes one line at a time and returns an {@link IProblem} if a match occurs.
*
* @remarks
* Multi-line matchers may keep internal state and emit on a later line; they can also optionally
* implement `flush()` to emit any buffered problems when the stream closes.
*
* @public
*/
export interface IProblemMatcher {
/** A friendly (and stable) name identifying the matcher. */
readonly name: string;
/**
* Attempt to match a problem for the provided line of console output.
*
* @param line - A single line of text, always terminated with a newline character (\\n).
* @returns A problem if recognized, otherwise `false`.
*/
exec(line: string): IProblem | false;
/**
* Flush any buffered state and return additional problems. Optional.
*/
flush?(): IProblem[];
}
/**
* VS Code style problem matcher pattern definition.
*
* @remarks
* This mirrors the shape used in VS Code's `problemMatcher.pattern` entries.
* Reference: https://code.visualstudio.com/docs/editor/tasks#_defining-a-problem-matcher
*
* @public
*/
export interface IProblemPattern {
/** A regular expression used to match the problem. */
regexp: string;
/** Match index for the file path. */
file?: number;
/** Match index for the location. */
location?: number;
/** Match index for the starting line number. */
line?: number;
/** Match index for the starting column number. */
column?: number;
/** Match index for the ending line number. */
endLine?: number;
/** Match index for the ending column number. */
endColumn?: number;
/** Match index for the severity level. */
severity?: number;
/** Match index for the problem code. */
code?: number;
/** Match index for the problem message. */
message: number;
/** If true, the last pattern in a multi-line matcher may repeat (loop) producing multiple problems */
loop?: boolean;
}
/**
* Minimal VS Code problem matcher definition.
*
* @public
*/
export interface IProblemMatcherJson {
/** A friendly (and stable) name identifying the matcher. */
name: string;
/** An optional default severity to apply if the pattern does not capture one. */
severity?: ProblemSeverity;
/** A single pattern or an array of patterns to match. */
pattern: IProblemPattern | IProblemPattern[];
}
/**
* Parse VS Code problem matcher JSON definitions into {@link IProblemMatcher} objects.
*
* @public
*/
export declare function parseProblemMatchersJson(problemMatchers: IProblemMatcherJson[]): IProblemMatcher[];
//# sourceMappingURL=ProblemMatcher.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ProblemMatcher.d.ts","sourceRoot":"","sources":["../src/ProblemMatcher.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE3D;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,yDAAyD;IACzD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IACpC,gDAAgD;IAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACrC;;OAEG;IACH,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,sGAAsG;IACtG,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,yDAAyD;IACzD,OAAO,EAAE,eAAe,GAAG,eAAe,EAAE,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,mBAAmB,EAAE,GAAG,eAAe,EAAE,CAuBlG"}

View File

@@ -0,0 +1,234 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseProblemMatchersJson = parseProblemMatchersJson;
/**
* Parse VS Code problem matcher JSON definitions into {@link IProblemMatcher} objects.
*
* @public
*/
function parseProblemMatchersJson(problemMatchers) {
const result = [];
for (const matcher of problemMatchers) {
const problemPatterns = Array.isArray(matcher.pattern)
? matcher.pattern
: [matcher.pattern];
if (problemPatterns.length === 0) {
continue;
}
const name = matcher.name;
const defaultSeverity = matcher.severity;
const compiled = compileProblemPatterns(problemPatterns);
if (compiled.length === 1) {
result.push(createSingleLineMatcher(name, compiled[0], defaultSeverity));
}
else {
result.push(createMultiLineMatcher(name, compiled, defaultSeverity));
}
}
return result;
}
function toNumber(text) {
if (!text) {
return undefined;
}
const n = parseInt(text, 10);
return isNaN(n) ? undefined : n;
}
function normalizeSeverity(raw) {
if (!raw) {
return undefined;
}
const lowered = raw.toLowerCase();
// Support full words as well as common abbreviations (e.g. single-letter tokens)
if (lowered.indexOf('err') === 0)
return 'error';
if (lowered.indexOf('warn') === 0)
return 'warning';
if (lowered.indexOf('info') === 0)
return 'info';
return undefined;
}
function compileProblemPatterns(problemPatterns) {
return problemPatterns.map((problemPattern) => {
let reStr = problemPattern.regexp;
if (/\\r?\\n\$/.test(reStr) || /\\n\$/.test(reStr)) {
// already newline aware
}
else if (reStr.length > 0 && reStr.charAt(reStr.length - 1) === '$') {
reStr = reStr.slice(0, -1) + '\\r?\\n$';
}
else {
reStr = reStr + '(?:\\r?\\n)';
}
const re = new RegExp(reStr);
return { re, spec: problemPattern };
});
}
function createEmptyCaptures() {
return { messageParts: [] };
}
/**
* Apply one pattern's regex match to the (possibly accumulating) captures.
*/
function applyPatternCaptures(spec, reMatch, captures, defaultSeverity) {
if (spec.file && reMatch[spec.file]) {
captures.file = reMatch[spec.file];
}
if (spec.location && reMatch[spec.location]) {
const loc = reMatch[spec.location];
const parts = loc.split(/[,.:]/).filter((s) => s.length > 0);
if (parts.length === 1) {
captures.line = toNumber(parts[0]);
}
else if (parts.length === 2) {
captures.line = toNumber(parts[0]);
captures.column = toNumber(parts[1]);
}
else if (parts.length === 4) {
captures.line = toNumber(parts[0]);
captures.column = toNumber(parts[1]);
captures.endLine = toNumber(parts[2]);
captures.endColumn = toNumber(parts[3]);
}
}
else {
if (spec.line && reMatch[spec.line]) {
captures.line = toNumber(reMatch[spec.line]);
}
if (spec.column && reMatch[spec.column]) {
captures.column = toNumber(reMatch[spec.column]);
}
}
if (spec.endLine && reMatch[spec.endLine]) {
captures.endLine = toNumber(reMatch[spec.endLine]);
}
if (spec.endColumn && reMatch[spec.endColumn]) {
captures.endColumn = toNumber(reMatch[spec.endColumn]);
}
if (spec.severity && reMatch[spec.severity]) {
captures.severity = normalizeSeverity(reMatch[spec.severity]) || defaultSeverity;
}
else if (!captures.severity && defaultSeverity) {
captures.severity = defaultSeverity;
}
if (spec.code && reMatch[spec.code]) {
captures.code = reMatch[spec.code];
}
if (spec.message && reMatch[spec.message]) {
captures.messageParts.push(reMatch[spec.message]);
}
}
function finalizeProblem(matcherName, captures, defaultSeverity) {
// For multi-line patterns, use only the last non-empty message part
const message = captures.messageParts.length > 0 ? captures.messageParts[captures.messageParts.length - 1] : '';
return {
matcherName,
file: captures.file,
line: captures.line,
column: captures.column,
endLine: captures.endLine,
endColumn: captures.endColumn,
severity: captures.severity || defaultSeverity,
code: captures.code,
message: message
};
}
function createSingleLineMatcher(name, compiled, defaultSeverity) {
const { re, spec } = compiled;
return {
name,
exec(line) {
const match = re.exec(line);
if (!match) {
return false;
}
const captures = createEmptyCaptures();
applyPatternCaptures(spec, match, captures, defaultSeverity);
return finalizeProblem(name, captures, defaultSeverity);
}
};
}
function createMultiLineMatcher(name, compiled, defaultSeverity) {
// currentIndex points to the next pattern we expect to match. When it equals compiled.length
// and the last pattern is a loop, we are in a special "loop state" where additional lines
// should be attempted against only the last pattern to emit more problems.
let currentIndex = 0;
const lastSpec = compiled[compiled.length - 1].spec;
const lastIsLoop = !!lastSpec.loop;
let captures = createEmptyCaptures();
return {
name,
exec(line) {
let effectiveMatch = null;
let effectiveSpec;
// Determine matching behavior based on current state
if (currentIndex === compiled.length && lastIsLoop) {
// Loop state: only try to match the last pattern
const lastPattern = compiled[compiled.length - 1];
effectiveMatch = lastPattern.re.exec(line);
if (!effectiveMatch) {
// Exit loop state and reset for a potential new sequence
currentIndex = 0;
captures = createEmptyCaptures();
// Attempt to treat this line as a fresh start (pattern 0)
const first = compiled[0];
const fresh = first.re.exec(line);
if (!fresh) {
return false;
}
effectiveMatch = fresh;
effectiveSpec = first.spec;
currentIndex = compiled.length > 1 ? 1 : compiled.length;
}
else {
effectiveSpec = lastPattern.spec;
// currentIndex remains compiled.length (loop state) until we decide to emit
}
}
else {
// Normal multi-line progression state
const active = compiled[currentIndex];
const reMatch = active.re.exec(line);
if (!reMatch) {
// Reset and maybe attempt new start
currentIndex = 0;
captures = createEmptyCaptures();
const { re: re0, spec: spec0 } = compiled[0];
const restartMatch = re0.exec(line);
if (!restartMatch) {
return false;
}
effectiveMatch = restartMatch;
effectiveSpec = spec0;
currentIndex = compiled.length > 1 ? 1 : compiled.length;
}
else {
effectiveMatch = reMatch;
effectiveSpec = active.spec;
currentIndex++;
}
}
applyPatternCaptures(effectiveSpec, effectiveMatch, captures, defaultSeverity);
// If we haven't matched all patterns yet (and not in loop state), wait for more lines
if (currentIndex < compiled.length) {
return false;
}
// We have matched the full sequence (either first completion or a loop iteration)
const problem = finalizeProblem(name, captures, defaultSeverity);
if (lastIsLoop) {
// Stay in loop state; reset fields that accumulate per problem but retain other context (e.g., file if first pattern captured it?)
// For safety, if the last pattern provided the file each iteration we keep overwriting anyway.
captures.messageParts = [];
// Do not clear entire captures to allow preceding pattern data (e.g., summary) to persist if desirable.
}
else {
currentIndex = 0;
captures = createEmptyCaptures();
}
return problem;
}
};
}
//# sourceMappingURL=ProblemMatcher.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
/**
* Parse VS Code style problem matcher definitions and use them to extract
* structured problem reports from strings.
*
* @packageDocumentation
*/
export type { ProblemSeverity, IProblemMatcher, IProblemMatcherJson, IProblemPattern, IProblem } from './ProblemMatcher';
export { parseProblemMatchersJson } from './ProblemMatcher';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,YAAY,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC"}

8
node_modules/@rushstack/problem-matcher/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseProblemMatchersJson = void 0;
var ProblemMatcher_1 = require("./ProblemMatcher");
Object.defineProperty(exports, "parseProblemMatchersJson", { enumerable: true, get: function () { return ProblemMatcher_1.parseProblemMatchersJson; } });
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAgB3D,mDAA4D;AAAnD,0HAAA,wBAAwB,OAAA","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Parse VS Code style problem matcher definitions and use them to extract\n * structured problem reports from strings.\n *\n * @packageDocumentation\n */\n\nexport type {\n ProblemSeverity,\n IProblemMatcher,\n IProblemMatcherJson,\n IProblemPattern,\n IProblem\n} from './ProblemMatcher';\nexport { parseProblemMatchersJson } from './ProblemMatcher';\n"]}

32
node_modules/@rushstack/problem-matcher/package.json generated vendored Normal file
View File

@@ -0,0 +1,32 @@
{
"name": "@rushstack/problem-matcher",
"version": "0.1.1",
"description": "A library for parsing VS Code style problem matchers",
"main": "lib/index.js",
"typings": "dist/problem-matcher.d.ts",
"license": "MIT",
"repository": {
"url": "https://github.com/microsoft/rushstack.git",
"type": "git",
"directory": "libraries/problem-matcher"
},
"dependencies": {},
"devDependencies": {
"@rushstack/heft": "0.74.3",
"eslint": "~9.25.1",
"decoupled-local-node-rig": "1.0.0"
},
"peerDependencies": {
"@types/node": "*"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
}
},
"scripts": {
"build": "heft build --clean",
"_phase:build": "heft run --only build -- --clean",
"_phase:test": "heft run --only test -- --clean"
}
}